Browse Source

Update to SDL 2.0.11-b46a94bb2ab0

woollybah 5 years ago
parent
commit
0bf2be2c27
90 changed files with 1975 additions and 526 deletions
  1. 13 10
      sdl.mod/SDL/CMakeLists.txt
  2. 2 2
      sdl.mod/SDL/Makefile.os2
  3. 2 1
      sdl.mod/SDL/Makefile.psp
  4. 1 0
      sdl.mod/SDL/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj
  5. 3 0
      sdl.mod/SDL/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters
  6. 1 0
      sdl.mod/SDL/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj
  7. 3 0
      sdl.mod/SDL/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters
  8. 1 0
      sdl.mod/SDL/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj
  9. 3 0
      sdl.mod/SDL/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters
  10. 1 0
      sdl.mod/SDL/VisualC/SDL/SDL.vcxproj
  11. 1 0
      sdl.mod/SDL/VisualC/SDL/SDL.vcxproj.filters
  12. 10 0
      sdl.mod/SDL/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
  13. 8 0
      sdl.mod/SDL/Xcode/SDL/SDL.xcodeproj/project.pbxproj
  14. 1 1
      sdl.mod/SDL/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
  15. 3 10
      sdl.mod/SDL/configure
  16. 4 10
      sdl.mod/SDL/configure.ac
  17. 6 0
      sdl.mod/SDL/include/SDL_config.h.cmake
  18. 5 0
      sdl.mod/SDL/include/SDL_config.h.in
  19. 1 0
      sdl.mod/SDL/include/SDL_config_android.h
  20. 1 0
      sdl.mod/SDL/include/SDL_config_iphoneos.h
  21. 1 0
      sdl.mod/SDL/include/SDL_config_macosx.h
  22. 11 1
      sdl.mod/SDL/include/SDL_config_os2.h
  23. 4 0
      sdl.mod/SDL/include/SDL_config_windows.h
  24. 1 0
      sdl.mod/SDL/include/SDL_config_winrt.h
  25. 1 0
      sdl.mod/SDL/include/SDL_config_wiz.h
  26. 20 0
      sdl.mod/SDL/include/SDL_gamecontroller.h
  27. 16 1
      sdl.mod/SDL/include/SDL_hints.h
  28. 3 0
      sdl.mod/SDL/include/SDL_pixels.h
  29. 6 1
      sdl.mod/SDL/include/SDL_stdinc.h
  30. 2 1
      sdl.mod/SDL/include/SDL_syswm.h
  31. 1 1
      sdl.mod/SDL/src/SDL.c
  32. 11 4
      sdl.mod/SDL/src/SDL_hints.c
  33. 32 0
      sdl.mod/SDL/src/SDL_hints_c.h
  34. 2 1
      sdl.mod/SDL/src/atomic/SDL_spinlock.c
  35. 1 1
      sdl.mod/SDL/src/audio/pulseaudio/SDL_pulseaudio.c
  36. 11 10
      sdl.mod/SDL/src/core/linux/SDL_evdev.c
  37. 17 10
      sdl.mod/SDL/src/cpuinfo/SDL_cpuinfo.c
  38. 5 0
      sdl.mod/SDL/src/dynapi/SDL_dynapi_overrides.h
  39. 5 0
      sdl.mod/SDL/src/dynapi/SDL_dynapi_procs.h
  40. 6 14
      sdl.mod/SDL/src/events/SDL_mouse.c
  41. 9 9
      sdl.mod/SDL/src/events/scancodes_xfree86.h
  42. 9 5
      sdl.mod/SDL/src/hidapi/libusb/hid.c
  43. 16 0
      sdl.mod/SDL/src/joystick/SDL_gamecontroller.c
  44. 30 4
      sdl.mod/SDL/src/joystick/SDL_gamecontrollerdb.h
  45. 72 40
      sdl.mod/SDL/src/joystick/SDL_joystick.c
  46. 4 9
      sdl.mod/SDL/src/joystick/SDL_joystick_c.h
  47. 1 0
      sdl.mod/SDL/src/joystick/SDL_sysjoystick.h
  48. 169 154
      sdl.mod/SDL/src/joystick/controller_type.h
  49. 1 1
      sdl.mod/SDL/src/joystick/hidapi/SDL_hidapi_ps4.c
  50. 3 11
      sdl.mod/SDL/src/joystick/hidapi/SDL_hidapi_switch.c
  51. 8 2
      sdl.mod/SDL/src/joystick/hidapi/SDL_hidapi_xbox360.c
  52. 143 29
      sdl.mod/SDL/src/joystick/hidapi/SDL_hidapi_xboxone.c
  53. 22 2
      sdl.mod/SDL/src/joystick/hidapi/SDL_hidapijoystick.c
  54. 18 16
      sdl.mod/SDL/src/joystick/iphoneos/SDL_sysjoystick.m
  55. 25 13
      sdl.mod/SDL/src/joystick/linux/SDL_sysjoystick.c
  56. 146 29
      sdl.mod/SDL/src/joystick/windows/SDL_dinputjoystick.c
  57. 58 29
      sdl.mod/SDL/src/joystick/windows/SDL_xinputjoystick.c
  58. 18 2
      sdl.mod/SDL/src/main/haiku/SDL_BApp.h
  59. 3 2
      sdl.mod/SDL/src/main/haiku/SDL_BeApp.cc
  60. 3 0
      sdl.mod/SDL/src/main/haiku/SDL_BeApp.h
  61. 27 21
      sdl.mod/SDL/src/render/direct3d11/SDL_render_d3d11.c
  62. 44 11
      sdl.mod/SDL/src/stdlib/SDL_string.c
  63. 103 0
      sdl.mod/SDL/src/stdlib/SDL_strtokr.c
  64. 3 0
      sdl.mod/SDL/src/test/SDL_test_common.c
  65. 7 0
      sdl.mod/SDL/src/video/SDL_pixels.c
  66. 1 0
      sdl.mod/SDL/src/video/SDL_sysvideo.h
  67. 18 2
      sdl.mod/SDL/src/video/SDL_video.c
  68. 15 8
      sdl.mod/SDL/src/video/android/SDL_androidevents.c
  69. 1 1
      sdl.mod/SDL/src/video/android/SDL_androidwindow.c
  70. 30 2
      sdl.mod/SDL/src/video/cocoa/SDL_cocoaevents.m
  71. 21 7
      sdl.mod/SDL/src/video/cocoa/SDL_cocoamodes.m
  72. 19 27
      sdl.mod/SDL/src/video/haiku/SDL_BWin.h
  73. 425 0
      sdl.mod/SDL/src/video/haiku/SDL_bmessagebox.cc
  74. 45 0
      sdl.mod/SDL/src/video/haiku/SDL_bmessagebox.h
  75. 2 2
      sdl.mod/SDL/src/video/haiku/SDL_bopengl.cc
  76. 30 0
      sdl.mod/SDL/src/video/haiku/SDL_bvideo.cc
  77. 11 1
      sdl.mod/SDL/src/video/haiku/SDL_bwindow.cc
  78. 2 0
      sdl.mod/SDL/src/video/uikit/SDL_uikitevents.m
  79. 4 0
      sdl.mod/SDL/src/video/uikit/SDL_uikitmodes.h
  80. 163 3
      sdl.mod/SDL/src/video/uikit/SDL_uikitmodes.m
  81. 4 0
      sdl.mod/SDL/src/video/uikit/SDL_uikitopengles.h
  82. 1 1
      sdl.mod/SDL/src/video/uikit/SDL_uikitopengles.m
  83. 4 0
      sdl.mod/SDL/src/video/uikit/SDL_uikitopenglview.h
  84. 1 1
      sdl.mod/SDL/src/video/uikit/SDL_uikitopenglview.m
  85. 2 0
      sdl.mod/SDL/src/video/uikit/SDL_uikitvideo.m
  86. 2 0
      sdl.mod/SDL/src/video/uikit/SDL_uikitviewcontroller.m
  87. 4 0
      sdl.mod/SDL/src/video/uikit/SDL_uikitwindow.m
  88. 1 1
      sdl.mod/SDL/src/video/x11/SDL_x11events.c
  89. 0 2
      sdl.mod/SDL/src/video/x11/SDL_x11window.c
  90. 1 0
      sdl.mod/source.bmx

+ 13 - 10
sdl.mod/SDL/CMakeLists.txt

@@ -47,7 +47,7 @@ set(SDL_INTERFACE_AGE 0)
 set(SDL_BINARY_AGE 11)
 set(SDL_VERSION "${SDL_MAJOR_VERSION}.${SDL_MINOR_VERSION}.${SDL_MICRO_VERSION}")
 # the following should match the versions in Xcode project file:
-set(DYLIB_CURRENT_VERSION 10.0.0)
+set(DYLIB_CURRENT_VERSION 12.0.0)
 set(DYLIB_COMPATIBILITY_VERSION 1.0.0)
 
 # Set defaults preventing destination file conflicts
@@ -760,10 +760,10 @@ if(LIBC)
     set(HAVE_SIGNAL_H 1)
     foreach(_FN
             malloc calloc realloc free qsort abs memset memcpy memmove memcmp
-            wcslen wcscmp
+            wcslen wcslcpy wcslcat wcsdup wcsstr wcscmp wcsncmp
             strlen _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa
             _ultoa strtol strtoul strtoll strtod atoi atof strcmp strncmp
-            _stricmp _strnicmp sscanf
+            _stricmp _strnicmp strtok_s sscanf
             acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf
             copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf
             log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf)
@@ -797,10 +797,11 @@ if(LIBC)
     foreach(_FN
             strtod malloc calloc realloc free getenv setenv putenv unsetenv
             qsort abs bcopy memset memcpy memmove memcmp strlen strlcpy strlcat
-            _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa
+            _strrev _strupr _strlwr strchr strrchr strstr strtok_r itoa _ltoa
             _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull
             atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp
-            vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp
+            wcscmp wcsdup wcslcat wcslcpy wcslen wcsncmp wcsstr
+            sscanf vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp
             nanosleep sysconf sysctlbyname getauxval poll _Exit
             )
       string(TOUPPER ${_FN} _UPPER)
@@ -812,8 +813,10 @@ if(LIBC)
     if(HAVE_LIBM)
       set(CMAKE_REQUIRED_LIBRARIES m)
       foreach(_FN
-              atan atan2 ceil copysign cos cosf fabs floor log pow scalbn sin
-              sinf sqrt sqrtf tan tanf acos asin)
+              atan atan2 atanf atan2f ceil ceilf copysign copysignf cos cosf
+              exp expf fabs fabsf floor floorf fmod fmodf log logf log10 log10f
+              pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf acos acosf
+              asin asinf)
         string(TOUPPER ${_FN} _UPPER)
         set(_HAVEVAR "HAVE_${_UPPER}")
         check_function_exists("${_FN}" ${_HAVEVAR})
@@ -2010,7 +2013,7 @@ add_library(SDL2main STATIC ${SDLMAIN_SOURCES})
 target_include_directories(SDL2main PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include/SDL2>)
 set(_INSTALL_LIBS "SDL2main")
 if (NOT ANDROID)
-  set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
+  set_target_properties(SDL2main PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}")
 endif()
 
 if (ANDROID AND HAVE_HIDAPI)
@@ -2044,7 +2047,7 @@ if(SDL_SHARED)
   target_link_libraries(SDL2 ${EXTRA_LIBS} ${EXTRA_LDFLAGS})
   target_include_directories(SDL2 PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include/SDL2>)
   if (NOT ANDROID)
-    set_target_properties(SDL2 PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
+    set_target_properties(SDL2 PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}")
   endif()
   if(IOS OR TVOS)
     set_property(TARGET SDL2 APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc")
@@ -2090,7 +2093,7 @@ if(SDL_STATIC)
   target_link_libraries(SDL2-static ${EXTRA_LIBS} ${EXTRA_LDFLAGS})
   target_include_directories(SDL2-static PUBLIC "$<BUILD_INTERFACE:${SDL2_SOURCE_DIR}/include>" $<INSTALL_INTERFACE:include/SDL2>)
   if (NOT ANDROID)
-    set_target_properties(SDL2-static PROPERTIES DEBUG_POSTFIX ${SDL_CMAKE_DEBUG_POSTFIX})
+    set_target_properties(SDL2-static PROPERTIES DEBUG_POSTFIX "${SDL_CMAKE_DEBUG_POSTFIX}")
   endif()
   if(IOS OR TVOS)
     set_property(TARGET SDL2-static APPEND_STRING PROPERTY COMPILE_FLAGS "-fobjc-arc")

+ 2 - 2
sdl.mod/SDL/Makefile.os2

@@ -1,4 +1,4 @@
-# Open Watcom makefile to build SDL2.dll for OS/2:
+# Open Watcom makefile to build SDL2.dll for OS/2
 # wmake -f Makefile.os2
 
 LIBNAME = SDL2
@@ -33,7 +33,7 @@ MSRCS= e_atan2.c e_exp.c e_fmod.c e_log10.c e_log.c e_pow.c e_rem_pio2.c e_sqrt.
        s_atan.c s_copysign.c s_cos.c s_fabs.c s_floor.c s_scalbn.c s_sin.c s_tan.c
 
 SRCS = SDL.c SDL_assert.c SDL_error.c SDL_log.c SDL_dataqueue.c SDL_hints.c
-SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c
+SRCS+= SDL_getenv.c SDL_iconv.c SDL_malloc.c SDL_qsort.c SDL_stdlib.c SDL_string.c SDL_strtokr.c
 SRCS+= SDL_cpuinfo.c SDL_atomic.c SDL_spinlock.c SDL_thread.c SDL_timer.c
 SRCS+= SDL_rwops.c SDL_power.c
 SRCS+= SDL_audio.c SDL_audiocvt.c SDL_audiodev.c SDL_audiotypecvt.c SDL_mixer.c SDL_wave.c

+ 2 - 1
sdl.mod/SDL/Makefile.psp

@@ -50,6 +50,7 @@ OBJS= src/SDL.o \
       src/stdlib/SDL_qsort.o \
       src/stdlib/SDL_stdlib.o \
       src/stdlib/SDL_string.o \
+      src/stdlib/SDL_strtokr.o \
       src/thread/SDL_thread.o \
       src/thread/generic/SDL_systls.o \
       src/thread/psp/SDL_syssem.o \
@@ -78,7 +79,7 @@ OBJS= src/SDL.o \
       src/video/psp/SDL_pspevents.o \
       src/video/psp/SDL_pspvideo.o \
       src/video/psp/SDL_pspgl.o \
-      src/video/psp/SDL_pspmouse.o \
+      src/video/psp/SDL_pspmouse.o
 
 INCDIR = ./include
 CFLAGS = -g -O2 -G0 -Wall -D__PSP__ -DHAVE_OPENGL

+ 1 - 0
sdl.mod/SDL/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj

@@ -285,6 +285,7 @@
     <ClCompile Include="..\..\src\stdlib\SDL_qsort.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_string.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c" />
     <ClCompile Include="..\..\src\thread\generic\SDL_syssem.c" />
     <ClCompile Include="..\..\src\thread\SDL_thread.c" />
     <ClCompile Include="..\..\src\thread\stdcpp\SDL_syscond.cpp" />

+ 3 - 0
sdl.mod/SDL/VisualC-WinRT/UWP_VS2015/SDL-UWP.vcxproj.filters

@@ -626,6 +626,9 @@
     <ClCompile Include="..\..\src\stdlib\SDL_string.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\thread\generic\SDL_syssem.c">
       <Filter>Source Files</Filter>
     </ClCompile>

+ 1 - 0
sdl.mod/SDL/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj

@@ -251,6 +251,7 @@
     <ClCompile Include="..\..\src\stdlib\SDL_qsort.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_string.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c" />
     <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c" />
     <ClCompile Include="..\..\src\thread\SDL_thread.c" />
     <ClCompile Include="..\..\src\thread\windows\SDL_sysmutex.c" />

+ 3 - 0
sdl.mod/SDL/VisualC-WinRT/WinPhone81_VS2013/SDL-WinPhone81.vcxproj.filters

@@ -593,6 +593,9 @@
     <ClCompile Include="..\..\src\stdlib\SDL_string.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\thread\SDL_thread.c">
       <Filter>Source Files</Filter>
     </ClCompile>

+ 1 - 0
sdl.mod/SDL/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj

@@ -283,6 +283,7 @@
     <ClCompile Include="..\..\src\stdlib\SDL_qsort.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_string.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c" />
     <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c" />
     <ClCompile Include="..\..\src\thread\SDL_thread.c" />
     <ClCompile Include="..\..\src\thread\windows\SDL_sysmutex.c" />

+ 3 - 0
sdl.mod/SDL/VisualC-WinRT/WinRT81_VS2013/SDL-WinRT81.vcxproj.filters

@@ -611,6 +611,9 @@
     <ClCompile Include="..\..\src\stdlib\SDL_string.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\src\thread\SDL_thread.c">
       <Filter>Source Files</Filter>
     </ClCompile>

+ 1 - 0
sdl.mod/SDL/VisualC/SDL/SDL.vcxproj

@@ -484,6 +484,7 @@
     <ClCompile Include="..\..\src\stdlib\SDL_qsort.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_string.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c" />
     <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c" />
     <ClCompile Include="..\..\src\thread\SDL_thread.c" />
     <ClCompile Include="..\..\src\thread\windows\SDL_sysmutex.c" />

+ 1 - 0
sdl.mod/SDL/VisualC/SDL/SDL.vcxproj.filters

@@ -426,6 +426,7 @@
     <ClCompile Include="..\..\src\stdlib\SDL_qsort.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_stdlib.c" />
     <ClCompile Include="..\..\src\stdlib\SDL_string.c" />
+    <ClCompile Include="..\..\src\stdlib\SDL_strtokr.c" />
     <ClCompile Include="..\..\src\thread\generic\SDL_syscond.c" />
     <ClCompile Include="..\..\src\thread\SDL_thread.c" />
     <ClCompile Include="..\..\src\thread\windows\SDL_sysmutex.c" />

+ 10 - 0
sdl.mod/SDL/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj

@@ -355,6 +355,10 @@
 		56ED04E1118A8EE200A56AA6 /* SDL_power.c in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E0118A8EE200A56AA6 /* SDL_power.c */; };
 		56ED04E3118A8EFD00A56AA6 /* SDL_syspower.m in Sources */ = {isa = PBXBuildFile; fileRef = 56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */; };
 		56F9D5601DF73BA400C15B5D /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 566726431DF72CF5001DD3DB /* SDL_dataqueue.c */; };
+		63CC93C723849391002A5C54 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = 63CC93C623849391002A5C54 /* SDL_strtokr.c */; };
+		63CC93C823849391002A5C54 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = 63CC93C623849391002A5C54 /* SDL_strtokr.c */; };
+		63CC93C923849391002A5C54 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = 63CC93C623849391002A5C54 /* SDL_strtokr.c */; };
+		63CC93CA23849391002A5C54 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = 63CC93C623849391002A5C54 /* SDL_strtokr.c */; };
 		93CB792313FC5E5200BD3E05 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = 93CB792213FC5E5200BD3E05 /* SDL_uikitviewcontroller.h */; };
 		93CB792613FC5F5300BD3E05 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */; };
 		A704172E20F7E74800A82227 /* controller_type.h in Headers */ = {isa = PBXBuildFile; fileRef = A704172D20F7E74800A82227 /* controller_type.h */; };
@@ -963,6 +967,7 @@
 		56EA86FA13E9EC2B002E47EB /* SDL_coreaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_coreaudio.h; sourceTree = "<group>"; };
 		56ED04E0118A8EE200A56AA6 /* SDL_power.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_power.c; sourceTree = "<group>"; };
 		56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_syspower.m; sourceTree = "<group>"; };
+		63CC93C623849391002A5C54 /* SDL_strtokr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_strtokr.c; sourceTree = "<group>"; };
 		93CB792213FC5E5200BD3E05 /* SDL_uikitviewcontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitviewcontroller.h; sourceTree = "<group>"; };
 		93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitviewcontroller.m; sourceTree = "<group>"; };
 		A704172D20F7E74800A82227 /* controller_type.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = controller_type.h; sourceTree = "<group>"; };
@@ -1491,6 +1496,7 @@
 		FD3F4A6F0DEA620800C5B771 /* stdlib */ = {
 			isa = PBXGroup;
 			children = (
+				63CC93C623849391002A5C54 /* SDL_strtokr.c */,
 				FD3F4A700DEA620800C5B771 /* SDL_getenv.c */,
 				FD3F4A710DEA620800C5B771 /* SDL_iconv.c */,
 				FD3F4A720DEA620800C5B771 /* SDL_malloc.c */,
@@ -2568,6 +2574,7 @@
 				52ED1E56222889500061FCE0 /* SDL_gamecontroller.c in Sources */,
 				52ED1E57222889500061FCE0 /* SDL_systls.c in Sources */,
 				52ED1E58222889500061FCE0 /* SDL_sysfilesystem.m in Sources */,
+				63CC93C823849391002A5C54 /* SDL_strtokr.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2696,6 +2703,7 @@
 				F3E3C7452241389A007D243C /* SDL_gamecontroller.c in Sources */,
 				F3E3C7462241389A007D243C /* SDL_systls.c in Sources */,
 				F3E3C7472241389A007D243C /* SDL_sysfilesystem.m in Sources */,
+				63CC93CA23849391002A5C54 /* SDL_strtokr.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2822,6 +2830,7 @@
 				FAB598BD1BB5C31600BE72C5 /* SDL_hints.c in Sources */,
 				FAB598BE1BB5C31600BE72C5 /* SDL_log.c in Sources */,
 				FAB598BF1BB5C31600BE72C5 /* SDL.c in Sources */,
+				63CC93C923849391002A5C54 /* SDL_strtokr.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2942,6 +2951,7 @@
 				AA0AD06216647BBB00CE5896 /* SDL_gamecontroller.c in Sources */,
 				AA0F8495178D5F1A00823F9D /* SDL_systls.c in Sources */,
 				56C181E217C44D7A00406AE3 /* SDL_sysfilesystem.m in Sources */,
+				63CC93C723849391002A5C54 /* SDL_strtokr.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 8 - 0
sdl.mod/SDL/Xcode/SDL/SDL.xcodeproj/project.pbxproj

@@ -456,6 +456,9 @@
 		5C2EF6FE1FC9EE65003F5197 /* SDL_egl.c in Sources */ = {isa = PBXBuildFile; fileRef = 5C2EF6F51FC9EE35003F5197 /* SDL_egl.c */; };
 		5C2EF6FF1FC9EE65003F5197 /* SDL_rect_c.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C2EF6F41FC9EE34003F5197 /* SDL_rect_c.h */; };
 		5C2EF7011FC9EF10003F5197 /* SDL_egl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5C2EF7001FC9EF0F003F5197 /* SDL_egl.h */; };
+		63994BE7238492D000F9C268 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = 63994BE6238492D000F9C268 /* SDL_strtokr.c */; };
+		63994BE8238492D000F9C268 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = 63994BE6238492D000F9C268 /* SDL_strtokr.c */; };
+		63994BE9238492D000F9C268 /* SDL_strtokr.c in Sources */ = {isa = PBXBuildFile; fileRef = 63994BE6238492D000F9C268 /* SDL_strtokr.c */; };
 		A704170920F09A9800A82227 /* hid.c in Sources */ = {isa = PBXBuildFile; fileRef = A704170820F09A9800A82227 /* hid.c */; };
 		A704170A20F09A9800A82227 /* hid.c in Sources */ = {isa = PBXBuildFile; fileRef = A704170820F09A9800A82227 /* hid.c */; };
 		A704170B20F09A9800A82227 /* hid.c in Sources */ = {isa = PBXBuildFile; fileRef = A704170820F09A9800A82227 /* hid.c */; };
@@ -1152,6 +1155,7 @@
 		5C2EF6F51FC9EE35003F5197 /* SDL_egl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_egl.c; sourceTree = "<group>"; };
 		5C2EF6F61FC9EE35003F5197 /* SDL_egl_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_egl_c.h; sourceTree = "<group>"; };
 		5C2EF7001FC9EF0F003F5197 /* SDL_egl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_egl.h; sourceTree = "<group>"; };
+		63994BE6238492D000F9C268 /* SDL_strtokr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_strtokr.c; sourceTree = "<group>"; };
 		A704170820F09A9800A82227 /* hid.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hid.c; sourceTree = "<group>"; };
 		A704170D20F09AC800A82227 /* SDL_hidapijoystick.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_hidapijoystick.c; sourceTree = "<group>"; };
 		A704170E20F09AC800A82227 /* SDL_hidapijoystick_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_hidapijoystick_c.h; sourceTree = "<group>"; };
@@ -1636,6 +1640,7 @@
 		04BDFE5D12E6671700899322 /* stdlib */ = {
 			isa = PBXGroup;
 			children = (
+				63994BE6238492D000F9C268 /* SDL_strtokr.c */,
 				04BDFE5E12E6671700899322 /* SDL_getenv.c */,
 				04BDFE5F12E6671700899322 /* SDL_iconv.c */,
 				04BDFE6012E6671700899322 /* SDL_malloc.c */,
@@ -2812,6 +2817,7 @@
 				AA0F8491178D5ECC00823F9D /* SDL_systls.c in Sources */,
 				D55A1B82179F262300625D7C /* SDL_cocoamousetap.m in Sources */,
 				567E2F1C17C44BB2005F1892 /* SDL_sysfilesystem.m in Sources */,
+				63994BE7238492D000F9C268 /* SDL_strtokr.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -2950,6 +2956,7 @@
 				AA0F8492178D5ECC00823F9D /* SDL_systls.c in Sources */,
 				D55A1B84179F263600625D7C /* SDL_cocoamousetap.m in Sources */,
 				DB0F490817CA5292008798C5 /* SDL_sysfilesystem.m in Sources */,
+				63994BE8238492D000F9C268 /* SDL_strtokr.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -3088,6 +3095,7 @@
 				AA0F8493178D5ECC00823F9D /* SDL_systls.c in Sources */,
 				D55A1B83179F263500625D7C /* SDL_cocoamousetap.m in Sources */,
 				DB0F490A17CA5293008798C5 /* SDL_sysfilesystem.m in Sources */,
+				63994BE9238492D000F9C268 /* SDL_strtokr.c in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 1 - 1
sdl.mod/SDL/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java

@@ -2120,7 +2120,7 @@ class DummyEdit extends View implements View.OnKeyListener {
     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
         ic = new SDLInputConnection(this, true);
 
-        outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_NORMAL;
+        outAttrs.inputType = InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD;
         outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
                 | EditorInfo.IME_FLAG_NO_FULLSCREEN /* API 11 */;
 

+ 3 - 10
sdl.mod/SDL/configure

@@ -16978,7 +16978,7 @@ fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 
-    for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll _Exit
+    for ac_func in malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcslcpy wcslcat wcsdup wcsstr wcscmp wcsncmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll _Exit
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -24364,14 +24364,7 @@ _ACEOF
 
                 fi
             else
-                case "$host" in
-                *-*-cygwin* | *-*-mingw32* )
-                    SOURCES="$SOURCES $srcdir/src/hidapi/windows/hid.c"
-                    ;;
-                *-*-darwin* )
-                    SOURCES="$SOURCES $srcdir/src/hidapi/mac/hid.c"
-                    ;;
-                esac
+                SOURCES="$SOURCES $srcdir/src/hidapi/SDL_hidapi.c"
             fi
         fi
 
@@ -25493,7 +25486,7 @@ VERSION_OBJECTS=`echo $VERSION_SOURCES`
 VERSION_DEPENDS=`echo $VERSION_SOURCES`
 VERSION_OBJECTS=`echo "$VERSION_OBJECTS" | sed 's,[^ ]*/\([^ ]*\)\.rc,$(objects)/\1.o,g'`
 VERSION_DEPENDS=`echo "$VERSION_DEPENDS" | sed "s,\\([^ ]*\\)/\\([^ ]*\\)\\.rc,\\\\
-\\$(objects)/\\2.o: \\1/\\2.rc\\\\
+\\$(objects)/\\2.o: \\1/\\2.rc \\$(objects)/.created\\\\
 	\\$(WINDRES) \\$< \\$@,g"`
 
 SDLMAIN_OBJECTS=`echo $SDLMAIN_SOURCES`

+ 4 - 10
sdl.mod/SDL/configure.ac

@@ -335,7 +335,7 @@ if test x$enable_libc = xyes; then
         AC_DEFINE(HAVE_MPROTECT, 1, [ ])
         ]),
     )
-    AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcscmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll _Exit)
+    AC_CHECK_FUNCS(malloc calloc realloc free getenv setenv putenv unsetenv qsort abs bcopy memset memcpy memmove wcslen wcslcpy wcslcat wcsdup wcsstr wcscmp wcsncmp strlen strlcpy strlcat _strrev _strupr _strlwr strchr strrchr strstr strtok_r itoa _ltoa _uitoa _ultoa strtol strtoul _i64toa _ui64toa strtoll strtoull atoi atof strcmp strncmp _stricmp strcasecmp _strnicmp strncasecmp vsscanf vsnprintf fopen64 fseeko fseeko64 sigaction setjmp nanosleep sysconf sysctlbyname getauxval poll _Exit)
 
     AC_CHECK_LIB(m, pow, [LIBS="$LIBS -lm"; EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lm"])
     AC_CHECK_FUNCS(acos acosf asin asinf atan atanf atan2 atan2f ceil ceilf copysign copysignf cos cosf exp expf fabs fabsf floor floorf fmod fmodf log logf log10 log10f pow powf scalbn scalbnf sin sinf sqrt sqrtf tan tanf)
@@ -3315,6 +3315,7 @@ AS_HELP_STRING([--enable-hidapi], [use HIDAPI for low level joystick drivers [[d
             AC_DEFINE(SDL_JOYSTICK_HIDAPI, 1, [ ])
             EXTRA_CFLAGS="$EXTRA_CFLAGS -I$srcdir/src/hidapi/hidapi"
             SOURCES="$SOURCES $srcdir/src/joystick/hidapi/*.c"
+            SOURCES="$SOURCES $srcdir/src/hidapi/SDL_hidapi.c"
 
             if test x$have_libusb_h = xyes; then
                 EXTRA_CFLAGS="$EXTRA_CFLAGS $LIBUSB_CFLAGS"
@@ -3342,14 +3343,7 @@ AS_HELP_STRING([--enable-hidapi], [use HIDAPI for low level joystick drivers [[d
                     AC_DEFINE_UNQUOTED(SDL_LIBUSB_DYNAMIC, "$libusb_lib", [ ])
                 fi
             else
-                case "$host" in
-                *-*-cygwin* | *-*-mingw32* )
-                    SOURCES="$SOURCES $srcdir/src/hidapi/windows/hid.c"
-                    ;;
-                *-*-darwin* )
-                    SOURCES="$SOURCES $srcdir/src/hidapi/mac/hid.c"
-                    ;;
-                esac
+                SOURCES="$SOURCES $srcdir/src/hidapi/SDL_hidapi.c"
             fi
         fi
 
@@ -4177,7 +4171,7 @@ VERSION_OBJECTS=`echo $VERSION_SOURCES`
 VERSION_DEPENDS=`echo $VERSION_SOURCES`
 VERSION_OBJECTS=`echo "$VERSION_OBJECTS" | sed 's,[[^ ]]*/\([[^ ]]*\)\.rc,$(objects)/\1.o,g'`
 VERSION_DEPENDS=`echo "$VERSION_DEPENDS" | sed "s,\\([[^ ]]*\\)/\\([[^ ]]*\\)\\.rc,\\\\
-\\$(objects)/\\2.o: \\1/\\2.rc\\\\
+\\$(objects)/\\2.o: \\1/\\2.rc \\$(objects)/.created\\\\
 	\\$(WINDRES) \\$< \\$@,g"`
 
 SDLMAIN_OBJECTS=`echo $SDLMAIN_SOURCES`

+ 6 - 0
sdl.mod/SDL/include/SDL_config.h.cmake

@@ -96,7 +96,10 @@
 #cmakedefine HAVE_WCSLEN 1
 #cmakedefine HAVE_WCSLCPY 1
 #cmakedefine HAVE_WCSLCAT 1
+#cmakedefine HAVE_WCSDUP 1
+#cmakedefine HAVE_WCSSTR 1
 #cmakedefine HAVE_WCSCMP 1
+#cmakedefine HAVE_WCSNCMP 1
 #cmakedefine HAVE_STRLEN 1
 #cmakedefine HAVE_STRLCPY 1
 #cmakedefine HAVE_STRLCAT 1
@@ -108,6 +111,8 @@
 #cmakedefine HAVE_STRCHR 1
 #cmakedefine HAVE_STRRCHR 1
 #cmakedefine HAVE_STRSTR 1
+#cmakedefine HAVE_STRTOK_R 1
+#cmakedefine HAVE_STRTOK_S 1
 #cmakedefine HAVE_ITOA 1
 #cmakedefine HAVE__LTOA 1
 #cmakedefine HAVE__UITOA 1
@@ -127,6 +132,7 @@
 #cmakedefine HAVE_STRCASECMP 1
 #cmakedefine HAVE__STRNICMP 1
 #cmakedefine HAVE_STRNCASECMP 1
+#cmakedefine HAVE_SSCANF 1
 #cmakedefine HAVE_VSSCANF 1
 #cmakedefine HAVE_VSNPRINTF 1
 #cmakedefine HAVE_M_PI 1

+ 5 - 0
sdl.mod/SDL/include/SDL_config.h.in

@@ -99,7 +99,10 @@
 #undef HAVE_WCSLEN
 #undef HAVE_WCSLCPY
 #undef HAVE_WCSLCAT
+#undef HAVE_WCSDUP
+#undef HAVE_WCSSTR
 #undef HAVE_WCSCMP
+#undef HAVE_WCSNCMP
 #undef HAVE_STRLEN
 #undef HAVE_STRLCPY
 #undef HAVE_STRLCAT
@@ -111,6 +114,8 @@
 #undef HAVE_STRCHR
 #undef HAVE_STRRCHR
 #undef HAVE_STRSTR
+#undef HAVE_STRTOK_R
+#undef HAVE_STRTOK_S
 #undef HAVE_ITOA
 #undef HAVE__LTOA
 #undef HAVE__UITOA

+ 1 - 0
sdl.mod/SDL/include/SDL_config_android.h

@@ -71,6 +71,7 @@
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR    1
 #define HAVE_STRSTR 1
+#define HAVE_STRTOK_R 1
 #define HAVE_STRTOL 1
 #define HAVE_STRTOUL    1
 #define HAVE_STRTOLL    1

+ 1 - 0
sdl.mod/SDL/include/SDL_config_iphoneos.h

@@ -71,6 +71,7 @@
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR    1
 #define HAVE_STRSTR 1
+#define HAVE_STRTOK_R 1
 #define HAVE_STRTOL 1
 #define HAVE_STRTOUL    1
 #define HAVE_STRTOLL    1

+ 1 - 0
sdl.mod/SDL/include/SDL_config_macosx.h

@@ -74,6 +74,7 @@
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR    1
 #define HAVE_STRSTR 1
+#define HAVE_STRTOK_R 1
 #define HAVE_STRTOL 1
 #define HAVE_STRTOUL    1
 #define HAVE_STRTOLL    1

+ 11 - 1
sdl.mod/SDL/include/SDL_config_os2.h

@@ -110,6 +110,7 @@
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR 1
 #define HAVE_STRSTR 1
+/* #undef HAVE_STRTOK_R */
 #define HAVE_ITOA 1
 #define HAVE__LTOA 1
 #define HAVE__ULTOA 1
@@ -122,12 +123,21 @@
 #define HAVE_STRTOD 1
 #define HAVE_ATOI 1
 #define HAVE_ATOF 1
+#define HAVE_WCSLEN 1
+#define HAVE_WCSLCPY 1
+#define HAVE_WCSLCAT 1
+/* #define HAVE_WCSDUP 1 */
+/* #define wcsdup _wcsdup */
+#define HAVE_WCSSTR 1
+#define HAVE_WCSCMP 1
+#define HAVE_WCSNCMP 1
 #define HAVE_STRCMP 1
 #define HAVE_STRNCMP 1
 #define HAVE_STRICMP 1
 #define HAVE_STRCASECMP 1
 #define HAVE_STRNCASECMP 1
-#define HAVE_SSCANF 1
+#define HAVE_SSCANF  1
+#define HAVE_VSSCANF 1
 #define HAVE_SNPRINTF 1
 #define HAVE_VSNPRINTF 1
 #define HAVE_SETJMP 1

+ 4 - 0
sdl.mod/SDL/include/SDL_config_windows.h

@@ -117,6 +117,10 @@ typedef unsigned int uintptr_t;
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR 1
 #define HAVE_STRSTR 1
+/* #undef HAVE_STRTOK_R */
+#if defined(_MSC_VER)
+#define HAVE_STRTOK_S 1
+#endif
 /* These functions have security warnings, so we won't use them */
 /* #undef HAVE__LTOA */
 /* #undef HAVE__ULTOA */

+ 1 - 0
sdl.mod/SDL/include/SDL_config_winrt.h

@@ -130,6 +130,7 @@ typedef unsigned int uintptr_t;
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR 1
 #define HAVE_STRSTR 1
+#define HAVE_STRTOK_S 1
 //#define HAVE_ITOA 1   // TODO, WinRT: consider using _itoa_s instead
 //#define HAVE__LTOA 1  // TODO, WinRT: consider using _ltoa_s instead
 //#define HAVE__ULTOA 1 // TODO, WinRT: consider using _ultoa_s instead

+ 1 - 0
sdl.mod/SDL/include/SDL_config_wiz.h

@@ -67,6 +67,7 @@
 #define HAVE_STRCHR 1
 #define HAVE_STRRCHR 1
 #define HAVE_STRSTR 1
+#define HAVE_STRTOK_R 1
 #define HAVE_STRTOL 1
 #define HAVE_STRTOUL 1
 #define HAVE_STRTOLL 1

+ 20 - 0
sdl.mod/SDL/include/SDL_gamecontroller.h

@@ -57,6 +57,15 @@ extern "C" {
 struct _SDL_GameController;
 typedef struct _SDL_GameController SDL_GameController;
 
+typedef enum
+{
+    SDL_CONTROLLER_TYPE_UNKNOWN = 0,
+    SDL_CONTROLLER_TYPE_XBOX360,
+    SDL_CONTROLLER_TYPE_XBOXONE,
+    SDL_CONTROLLER_TYPE_PS3,
+    SDL_CONTROLLER_TYPE_PS4,
+    SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO
+} SDL_GameControllerType;
 
 typedef enum
 {
@@ -175,6 +184,12 @@ extern DECLSPEC SDL_bool SDLCALL SDL_IsGameController(int joystick_index);
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerNameForIndex(int joystick_index);
 
+/**
+ *  Get the type of a game controller.
+ *  This can be called before any controllers are opened.
+ */
+extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerTypeForIndex(int joystick_index);
+
 /**
  *  Get the mapping of a game controller.
  *  This can be called before any controllers are opened.
@@ -204,6 +219,11 @@ extern DECLSPEC SDL_GameController *SDLCALL SDL_GameControllerFromInstanceID(SDL
  */
 extern DECLSPEC const char *SDLCALL SDL_GameControllerName(SDL_GameController *gamecontroller);
 
+/**
+ *  Return the type of this currently opened controller
+ */
+extern DECLSPEC SDL_GameControllerType SDLCALL SDL_GameControllerGetType(SDL_GameController *gamecontroller);
+
 /**
  *  Get the player index of an opened game controller, or -1 if it's not available
  *

+ 16 - 1
sdl.mod/SDL/include/SDL_hints.h

@@ -164,6 +164,21 @@ extern "C" {
  */
 #define SDL_HINT_VIDEO_ALLOW_SCREENSAVER    "SDL_VIDEO_ALLOW_SCREENSAVER"
 
+/**
+ * \brief A variable controlling whether the graphics context is externally managed.
+ *
+ * This variable can be set to the following values:
+ *  "0"         - SDL will manage graphics contexts that are attached to windows.
+ *  "1"         - Disable graphics context management on windows.
+ *
+ * By default SDL will manage OpenGL contexts in certain situations. For example, on Android the
+ * context will be automatically saved and restored when pausing the application. Additionally, some
+ * platforms will assume usage of OpenGL if Vulkan isn't used. Setting this to "1" will prevent this
+ * behavior, which is desireable when the application manages the graphics context, such as
+ * an externally managed OpenGL context or attaching a Vulkan surface to the window.
+ */
+#define SDL_HINT_VIDEO_EXTERNAL_CONTEXT    "SDL_VIDEO_EXTERNAL_CONTEXT"
+
 /**
  *  \brief  A variable controlling whether the X11 VidMode extension should be used.
  *
@@ -507,7 +522,7 @@ extern "C" {
  *    "0"       - Report the face buttons by position, as though they were on an Xbox controller.
  *    "1"       - Report the face buttons by label instead of position
  *
- *  The default value is "0".  This hint may be set at any time.
+ *  The default value is "1".  This hint may be set at any time.
  */
 #define SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS "SDL_GAMECONTROLLER_USE_BUTTON_LABELS"
 

+ 3 - 0
sdl.mod/SDL/include/SDL_pixels.h

@@ -191,6 +191,9 @@ typedef enum
     SDL_PIXELFORMAT_RGB444 =
         SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
                                SDL_PACKEDLAYOUT_4444, 12, 2),
+    SDL_PIXELFORMAT_BGR444 =
+        SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR,
+                               SDL_PACKEDLAYOUT_4444, 12, 2),
     SDL_PIXELFORMAT_RGB555 =
         SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB,
                                SDL_PACKEDLAYOUT_1555, 15, 2),

+ 6 - 1
sdl.mod/SDL/include/SDL_stdinc.h

@@ -453,11 +453,14 @@ extern DECLSPEC void *SDLCALL SDL_memcpy(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_
 extern DECLSPEC void *SDLCALL SDL_memmove(SDL_OUT_BYTECAP(len) void *dst, SDL_IN_BYTECAP(len) const void *src, size_t len);
 extern DECLSPEC int SDLCALL SDL_memcmp(const void *s1, const void *s2, size_t len);
 
-extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr);
 extern DECLSPEC size_t SDLCALL SDL_wcslen(const wchar_t *wstr);
 extern DECLSPEC size_t SDLCALL SDL_wcslcpy(SDL_OUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
 extern DECLSPEC size_t SDLCALL SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t maxlen);
+extern DECLSPEC wchar_t *SDLCALL SDL_wcsdup(const wchar_t *wstr);
+extern DECLSPEC wchar_t *SDLCALL SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle);
+
 extern DECLSPEC int SDLCALL SDL_wcscmp(const wchar_t *str1, const wchar_t *str2);
+extern DECLSPEC int SDLCALL SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen);
 
 extern DECLSPEC size_t SDLCALL SDL_strlen(const char *str);
 extern DECLSPEC size_t SDLCALL SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen);
@@ -470,6 +473,7 @@ extern DECLSPEC char *SDLCALL SDL_strlwr(char *str);
 extern DECLSPEC char *SDLCALL SDL_strchr(const char *str, int c);
 extern DECLSPEC char *SDLCALL SDL_strrchr(const char *str, int c);
 extern DECLSPEC char *SDLCALL SDL_strstr(const char *haystack, const char *needle);
+extern DECLSPEC char *SDLCALL SDL_strtokr(char *s1, const char *s2, char **saveptr);
 extern DECLSPEC size_t SDLCALL SDL_utf8strlen(const char *str);
 
 extern DECLSPEC char *SDLCALL SDL_itoa(int value, char *str, int radix);
@@ -584,6 +588,7 @@ extern DECLSPEC char *SDLCALL SDL_iconv_string(const char *tocode,
 #define SDL_strchr strchr
 #define SDL_strrchr strrchr
 #define SDL_strstr strstr
+#define SDL_strtokr strtok_r
 #define SDL_strcmp strcmp
 #define SDL_strncmp strncmp
 #define SDL_strcasecmp strcasecmp

+ 2 - 1
sdl.mod/SDL/include/SDL_syswm.h

@@ -132,7 +132,8 @@ typedef enum
     SDL_SYSWM_WINRT,
     SDL_SYSWM_ANDROID,
     SDL_SYSWM_VIVANTE,
-    SDL_SYSWM_OS2
+    SDL_SYSWM_OS2,
+    SDL_SYSWM_HAIKU
 } SDL_SYSWM_TYPE;
 
 /**

+ 1 - 1
sdl.mod/SDL/src/SDL.c

@@ -57,7 +57,7 @@ extern int SDL_HelperWindowDestroy(void);
     parts of SDL, because we don't want anything calling it without an
     extremely good reason. */
 extern SDL_NORETURN void SDL_ExitProcess(int exitcode);
-SDL_NORETURN void SDL_ExitProcess(const int exitcode)
+SDL_NORETURN void SDL_ExitProcess(int exitcode)
 {
 #ifdef __WIN32__
     /* "if you do not know the state of all threads in your process, it is

+ 11 - 4
sdl.mod/SDL/src/SDL_hints.c

@@ -22,6 +22,7 @@
 
 #include "SDL_hints.h"
 #include "SDL_error.h"
+#include "SDL_hints_c.h"
 
 
 /* Assuming there aren't many hints set and they aren't being queried in
@@ -119,18 +120,24 @@ SDL_GetHint(const char *name)
 }
 
 SDL_bool
-SDL_GetHintBoolean(const char *name, SDL_bool default_value)
+SDL_GetStringBoolean(const char *value, SDL_bool default_value)
 {
-    const char *hint = SDL_GetHint(name);
-    if (!hint || !*hint) {
+    if (!value || !*value) {
         return default_value;
     }
-    if (*hint == '0' || SDL_strcasecmp(hint, "false") == 0) {
+    if (*value == '0' || SDL_strcasecmp(value, "false") == 0) {
         return SDL_FALSE;
     }
     return SDL_TRUE;
 }
 
+SDL_bool
+SDL_GetHintBoolean(const char *name, SDL_bool default_value)
+{
+    const char *hint = SDL_GetHint(name);
+    return SDL_GetStringBoolean(hint, default_value);
+}
+
 void
 SDL_AddHintCallback(const char *name, SDL_HintCallback callback, void *userdata)
 {

+ 32 - 0
sdl.mod/SDL/src/SDL_hints_c.h

@@ -0,0 +1,32 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2019 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#include "./SDL_internal.h"
+
+/* This file defines useful function for working with SDL hints */
+
+#ifndef SDL_hints_c_h_
+#define SDL_hints_c_h_
+
+extern SDL_bool SDL_GetStringBoolean(const char *value, SDL_bool default_value);
+
+#endif /* SDL_hints_c_h_ */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 2 - 1
sdl.mod/SDL/src/atomic/SDL_spinlock.c

@@ -79,7 +79,8 @@ SDL_AtomicTryLock(SDL_SpinLock *lock)
     return (__sync_lock_test_and_set(lock, 1) == 0);
 
 #elif defined(__GNUC__) && defined(__arm__) && \
-        (defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
+        (defined(__ARM_ARCH_3__) || defined(__ARM_ARCH_3M__) || \
+         defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || \
          defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5TE__) || \
          defined(__ARM_ARCH_5TEJ__))
     int result;

+ 1 - 1
sdl.mod/SDL/src/audio/pulseaudio/SDL_pulseaudio.c

@@ -429,7 +429,7 @@ PULSEAUDIO_FlushCapture(_THIS)
         h->capturelen = 0;
     }
 
-    while (SDL_TRUE) {
+    while (SDL_AtomicGet(&this->enabled)) {
         if (PULSEAUDIO_pa_context_get_state(h->context) != PA_CONTEXT_READY ||
             PULSEAUDIO_pa_stream_get_state(h->stream) != PA_STREAM_READY ||
             PULSEAUDIO_pa_mainloop_iterate(h->mainloop, 1, NULL) < 0) {

+ 11 - 10
sdl.mod/SDL/src/core/linux/SDL_evdev.c

@@ -446,18 +446,19 @@ SDL_EVDEV_translate_keycode(int keycode)
 {
     SDL_Scancode scancode = SDL_SCANCODE_UNKNOWN;
 
-    if (keycode < SDL_arraysize(linux_scancode_table))
+    if (keycode < SDL_arraysize(linux_scancode_table)) {
         scancode = linux_scancode_table[keycode];
 
-    if (scancode == SDL_SCANCODE_UNKNOWN) {
-        /* BTN_TOUCH is handled elsewhere, but we might still end up here if
-           you get an unexpected BTN_TOUCH from something SDL believes is not
-           a touch device. In this case, we'd rather not get a misleading
-           SDL_Log message about an unknown key. */
-        if (keycode != BTN_TOUCH) {
-            SDL_Log("The key you just pressed is not recognized by SDL. To help "
-                "get this fixed, please report this to the SDL forums/mailing list "
-                "<https://discourse.libsdl.org/> EVDEV KeyCode %d", keycode);
+        if (scancode == SDL_SCANCODE_UNKNOWN) {
+            /* BTN_TOUCH is handled elsewhere, but we might still end up here if
+               you get an unexpected BTN_TOUCH from something SDL believes is not
+               a touch device. In this case, we'd rather not get a misleading
+               SDL_Log message about an unknown key. */
+            if (keycode != BTN_TOUCH) {
+                SDL_Log("The key you just pressed is not recognized by SDL. To help "
+                    "get this fixed, please report this to the SDL forums/mailing list "
+                    "<https://discourse.libsdl.org/> EVDEV KeyCode %d", keycode);
+            }
         }
     }
 

+ 17 - 10
sdl.mod/SDL/src/cpuinfo/SDL_cpuinfo.c

@@ -334,16 +334,20 @@ CPU_haveAltiVec(void)
 }
 
 #if !defined(__ARM_ARCH)
-static SDL_bool CPU_haveARMSIMD(void) { return 0; }
+static int
+CPU_haveARMSIMD(void)
+{
+	return 0;
+}
 
-#elif defined(__linux__)
+#elif defined(__LINUX__)
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <elf.h>
 
-static SDL_bool
+static int
 CPU_haveARMSIMD(void)
 {
     int arm_simd = 0;
@@ -358,8 +362,10 @@ CPU_haveARMSIMD(void)
             if (aux.a_type == AT_PLATFORM)
             {
                 const char *plat = (const char *) aux.a_un.a_val;
-                arm_simd = strncmp(plat, "v6l", 3) == 0 ||
-                           strncmp(plat, "v7l", 3) == 0;
+                if (plat) {
+                    arm_simd = strncmp(plat, "v6l", 3) == 0 ||
+                               strncmp(plat, "v7l", 3) == 0;
+                }
             }
         }
         close(fd);
@@ -368,15 +374,17 @@ CPU_haveARMSIMD(void)
 }
 
 #else
-static SDL_bool
+static int
 CPU_haveARMSIMD(void)
 {
-    #warning SDL_HasARMSIMD is not implemented for this ARM platform. Write me.
-    return 0;
+#if !defined(__ANDROID__) && !defined(__IPHONEOS__) && !defined(__TVOS__)
+#warning SDL_HasARMSIMD is not implemented for this ARM platform, defaulting to TRUE
+#endif
+    return 1;
 }
 #endif
 
-#if (defined(__LINUX__) || defined(__ANDROID__)) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
+#if defined(__LINUX__) && defined(__ARM_ARCH) && !defined(HAVE_GETAUXVAL)
 static int
 readProcAuxvForNeon(void)
 {
@@ -396,7 +404,6 @@ readProcAuxvForNeon(void)
 }
 #endif
 
-
 static int
 CPU_haveNEON(void)
 {

+ 5 - 0
sdl.mod/SDL/src/dynapi/SDL_dynapi_overrides.h

@@ -728,3 +728,8 @@
 #define SDL_Metal_DestroyView SDL_Metal_DestroyView_REAL
 #define SDL_LockTextureToSurface SDL_LockTextureToSurface_REAL
 #define SDL_HasARMSIMD SDL_HasARMSIMD_REAL
+#define SDL_strtokr SDL_strtokr_REAL
+#define SDL_wcsstr SDL_wcsstr_REAL
+#define SDL_wcsncmp SDL_wcsncmp_REAL
+#define SDL_GameControllerTypeForIndex SDL_GameControllerTypeForIndex_REAL
+#define SDL_GameControllerGetType SDL_GameControllerGetType_REAL

+ 5 - 0
sdl.mod/SDL/src/dynapi/SDL_dynapi_procs.h

@@ -784,3 +784,8 @@ SDL_DYNAPI_PROC(SDL_MetalView,SDL_Metal_CreateView,(SDL_Window *a),(a),return)
 SDL_DYNAPI_PROC(void,SDL_Metal_DestroyView,(SDL_MetalView a),(a),)
 SDL_DYNAPI_PROC(int,SDL_LockTextureToSurface,(SDL_Texture *a, const SDL_Rect *b, SDL_Surface **c),(a,b,c),return)
 SDL_DYNAPI_PROC(SDL_bool,SDL_HasARMSIMD,(void),(),return)
+SDL_DYNAPI_PROC(char*,SDL_strtokr,(char *a, const char *b, char **c),(a,b,c),return)
+SDL_DYNAPI_PROC(wchar_t*,SDL_wcsstr,(const wchar_t *a, const wchar_t *b),(a,b),return)
+SDL_DYNAPI_PROC(int,SDL_wcsncmp,(const wchar_t *a, const wchar_t *b, size_t c),(a,b,c),return)
+SDL_DYNAPI_PROC(SDL_GameControllerType,SDL_GameControllerTypeForIndex,(int a),(a),return)
+SDL_DYNAPI_PROC(SDL_GameControllerType,SDL_GameControllerGetType,(SDL_GameController *a),(a),return)

+ 6 - 14
sdl.mod/SDL/src/events/SDL_mouse.c

@@ -27,6 +27,7 @@
 #include "SDL_timer.h"
 #include "SDL_events.h"
 #include "SDL_events_c.h"
+#include "../SDL_hints_c.h"
 #include "../video/SDL_sysvideo.h"
 #ifdef __WIN32__
 #include "../core/windows/SDL_windows.h"    // For GetDoubleClickTime()
@@ -100,30 +101,21 @@ SDL_TouchMouseEventsChanged(void *userdata, const char *name, const char *oldVal
 {
     SDL_Mouse *mouse = (SDL_Mouse *)userdata;
 
-    if (hint && (*hint == '0' || SDL_strcasecmp(hint, "false") == 0)) {
-        mouse->touch_mouse_events = SDL_FALSE;
-    } else {
-        mouse->touch_mouse_events = SDL_TRUE;
-    }
+    mouse->touch_mouse_events = SDL_GetStringBoolean(hint, SDL_TRUE);
 }
 
 static void SDLCALL
 SDL_MouseTouchEventsChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
 {
     SDL_Mouse *mouse = (SDL_Mouse *)userdata;
+    SDL_bool default_value;
 
-    if (hint == NULL || *hint == '\0') {
-        /* Default */
 #if defined(__ANDROID__) || (defined(__IPHONEOS__) && !defined(__TVOS__))
-        mouse->mouse_touch_events = SDL_TRUE;
+    default_value = SDL_TRUE;
 #else
-        mouse->mouse_touch_events = SDL_FALSE;
+    default_value = SDL_FALSE;
 #endif
-    } else if (*hint == '1' || SDL_strcasecmp(hint, "true") == 0) {
-        mouse->mouse_touch_events = SDL_TRUE;
-    } else {
-        mouse->mouse_touch_events = SDL_FALSE;
-    }
+    mouse->mouse_touch_events = SDL_GetStringBoolean(hint, default_value);
 
     if (mouse->mouse_touch_events) {
         SDL_AddTouch(SDL_MOUSE_TOUCHID, SDL_TOUCH_DEVICE_DIRECT, "mouse_input");

+ 9 - 9
sdl.mod/SDL/src/events/scancodes_xfree86.h

@@ -299,12 +299,12 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
     /* 115 */   SDL_SCANCODE_VOLUMEUP,
     /* 116 */   SDL_SCANCODE_POWER,
     /* 117 */   SDL_SCANCODE_KP_EQUALS,
-    /* 118 */   SDL_SCANCODE_UNKNOWN,   /* plusminus */
+    /* 118 */   SDL_SCANCODE_KP_PLUSMINUS, /* plusminus */
     /* 119 */   SDL_SCANCODE_PAUSE,
     /* 120 */   SDL_SCANCODE_UNKNOWN,   /* XF86LaunchA */
-    /* 121 */   SDL_SCANCODE_UNKNOWN,   /* KP_Decimal */
-    /* 122 */   SDL_SCANCODE_UNKNOWN,   /* Hangul */
-    /* 123 */   SDL_SCANCODE_UNKNOWN,   /* Hangul_Hanja */
+    /* 121 */   SDL_SCANCODE_KP_COMMA,  /* KP_Decimal */
+    /* 122 */   SDL_SCANCODE_LANG1,     /* Hangul */
+    /* 123 */   SDL_SCANCODE_LANG2,     /* Hangul_Hanja */
     /* 124 */   SDL_SCANCODE_INTERNATIONAL3, /* Yen */
     /* 125 */   SDL_SCANCODE_LGUI,
     /* 126 */   SDL_SCANCODE_RGUI,
@@ -320,7 +320,7 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
     /* 136 */   SDL_SCANCODE_FIND,
     /* 137 */   SDL_SCANCODE_CUT,
     /* 138 */   SDL_SCANCODE_HELP,
-    /* 139 */   SDL_SCANCODE_UNKNOWN,   /* XF86MenuKB */
+    /* 139 */   SDL_SCANCODE_MENU,   /* XF86MenuKB */
     /* 140 */   SDL_SCANCODE_CALCULATOR,
     /* 141 */   SDL_SCANCODE_UNKNOWN,
     /* 142 */   SDL_SCANCODE_SLEEP,
@@ -360,8 +360,8 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
     /* 176 */   SDL_SCANCODE_UNKNOWN,
     /* 177 */   SDL_SCANCODE_UNKNOWN,   /* XF86ScrollUp */
     /* 178 */   SDL_SCANCODE_UNKNOWN,   /* XF86ScrollDown */
-    /* 179 */   SDL_SCANCODE_UNKNOWN,   /* parenleft */
-    /* 180 */   SDL_SCANCODE_UNKNOWN,   /* parenright */
+    /* 179 */   SDL_SCANCODE_KP_LEFTPAREN,  /* parenleft */
+    /* 180 */   SDL_SCANCODE_KP_RIGHTPAREN, /* parenright */
     /* 181 */   SDL_SCANCODE_UNKNOWN,   /* XF86New */
     /* 182 */   SDL_SCANCODE_AGAIN,
     /* 183 */   SDL_SCANCODE_F13,       /* XF86Tools */
@@ -371,7 +371,7 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
     /* 187 */   SDL_SCANCODE_F17,       /* XF86Launch8 */
     /* 188 */   SDL_SCANCODE_F18,       /* XF86Launch9 */
     /* 189 */   SDL_SCANCODE_F19,       /* null keysym */
-    /* 190 */   SDL_SCANCODE_UNKNOWN,
+    /* 190 */   SDL_SCANCODE_F20,
     /* 191 */   SDL_SCANCODE_UNKNOWN,
     /* 192 */   SDL_SCANCODE_UNKNOWN,   /* XF86TouchpadToggle */
     /* 193 */   SDL_SCANCODE_UNKNOWN,
@@ -389,7 +389,7 @@ static const SDL_Scancode xfree86_scancode_table2[] = {
     /* 205 */   SDL_SCANCODE_UNKNOWN,   /* XF86Suspend */
     /* 206 */   SDL_SCANCODE_UNKNOWN,   /* XF86Close */
     /* 207 */   SDL_SCANCODE_AUDIOPLAY,
-    /* 208 */   SDL_SCANCODE_AUDIONEXT,
+    /* 208 */   SDL_SCANCODE_AUDIOFASTFORWARD,
     /* 209 */   SDL_SCANCODE_UNKNOWN,
     /* 210 */   SDL_SCANCODE_PRINTSCREEN,
     /* 211 */   SDL_SCANCODE_UNKNOWN,

+ 9 - 5
sdl.mod/SDL/src/hidapi/libusb/hid.c

@@ -491,7 +491,7 @@ static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_de
 		0x06a3, /* Saitek */
 		0x0738, /* Mad Catz */
 		0x07ff, /* Mad Catz */
-		0x0e6f, /* Unknown */
+		0x0e6f, /* PDP */
 		0x0f0d, /* Hori */
 		0x11c9, /* Nacon */
 		0x12ab, /* Unknown */
@@ -526,10 +526,11 @@ static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_de
         static const int SUPPORTED_VENDORS[] = {
             0x045e, /* Microsoft */
             0x0738, /* Mad Catz */
-            0x0e6f, /* Unknown */
+            0x0e6f, /* PDP */
             0x0f0d, /* Hori */
             0x1532, /* Razer Wildcat */
             0x24c6, /* PowerA */
+            0x2e24, /* Hyperkin */
         };
 
 	if (intf_desc->bInterfaceNumber == 0 &&
@@ -939,7 +940,10 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path, int bExclusive)
 		int i,j,k;
 		libusb_get_device_descriptor(usb_dev, &desc);
 
-		if (libusb_get_active_config_descriptor(usb_dev, &conf_desc) < 0)
+		res = libusb_get_active_config_descriptor(usb_dev, &conf_desc);
+		if (res < 0)
+			libusb_get_config_descriptor(usb_dev, 0, &conf_desc);
+		if (!conf_desc)
 			continue;
 		for (j = 0; j < conf_desc->bNumInterfaces; j++) {
 			const struct libusb_interface *intf = &conf_desc->interface[j];
@@ -1433,7 +1437,7 @@ static struct lang_map_entry lang_map[] = {
 	LANG("Lithuanian", "lt", 0x0427),
 	LANG("F.Y.R.O. Macedonia", "mk", 0x042F),
 	LANG("Malay - Malaysia", "ms_my", 0x043E),
-	LANG("Malay  Brunei", "ms_bn", 0x083E),
+	LANG("Malay ??? Brunei", "ms_bn", 0x083E),
 	LANG("Maltese", "mt", 0x043A),
 	LANG("Marathi", "mr", 0x044E),
 	LANG("Norwegian - Bokml", "no_no", 0x0414),
@@ -1484,7 +1488,7 @@ static struct lang_map_entry lang_map[] = {
 	LANG("Ukrainian", "uk", 0x0422),
 	LANG("Urdu", "ur", 0x0420),
 	LANG("Uzbek - Cyrillic", "uz_uz", 0x0843),
-	LANG("Uzbek  Latin", "uz_uz", 0x0443),
+	LANG("Uzbek ??? Latin", "uz_uz", 0x0443),
 	LANG("Vietnamese", "vi", 0x042A),
 	LANG("Xhosa", "xh", 0x0434),
 	LANG("Yiddish", "yi", 0x043D),

+ 16 - 0
sdl.mod/SDL/src/joystick/SDL_gamecontroller.c

@@ -1412,6 +1412,16 @@ SDL_GameControllerNameForIndex(int device_index)
 }
 
 
+/**
+ *  Get the type of a game controller.
+ */
+SDL_GameControllerType
+SDL_GameControllerTypeForIndex(int joystick_index)
+{
+    return SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGetDeviceGUID(joystick_index), SDL_JoystickNameForIndex(joystick_index));
+}
+
+
 /**
  *  Get the mapping of a game controller.
  *  This can be called before any controllers are opened.
@@ -1743,6 +1753,12 @@ SDL_GameControllerName(SDL_GameController * gamecontroller)
     }
 }
 
+SDL_GameControllerType
+SDL_GameControllerGetType(SDL_GameController *gamecontroller)
+{
+    return SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGetGUID(SDL_GameControllerGetJoystick(gamecontroller)), SDL_JoystickName(SDL_GameControllerGetJoystick(gamecontroller)));
+}
+
 int
 SDL_GameControllerGetPlayerIndex(SDL_GameController *gamecontroller)
 {

+ 30 - 4
sdl.mod/SDL/src/joystick/SDL_gamecontrollerdb.h

@@ -41,6 +41,7 @@ static const char *s_ControllerMappings [] =
     "03000000c82d00000060000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,",
     "03000000c82d00000061000000000000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,",
     "03000000102800000900000000000000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
+    "03000000c82d00000160000000000000,8Bitdo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,",
     "03000000a00500003232000000000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a2,dpleft:-a0,dpright:+a0,dpup:-a2,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,",
     "03000000c82d00002038000000000000,8bitdo,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b4,y:b3,",
     "030000008f0e00001200000000000000,Acme GA-02,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b2,y:b3,",
@@ -82,8 +83,6 @@ static const char *s_ControllerMappings [] =
     "03000000b80500000610000000000000,Elecom Gamepad,a:b2,b:b3,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:b1,",
     "03000000852100000201000000000000,FF-GP1,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,",
     "030000000d0f00002700000000000000,FIGHTING STICK V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
-    "030000000d0f00008500000000000000,Fighting Commander 2016 PS3,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,",
-    "030000000d0f00008400000000000000,Fighting Commander 5,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:a5,start:b9,x:b0,y:b3,",
     "030000000d0f00008700000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
     "030000000d0f00008800000000000000,Fighting Stick mini 4,a:b1,b:b2,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b8,x:b0,y:b3,",
     "78696e70757403000000000000000000,Fightstick TES,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,lefttrigger:a2,rightshoulder:b5,righttrigger:a5,start:b7,x:b2,y:b3,",
@@ -106,6 +105,8 @@ static const char *s_ControllerMappings [] =
     "03000000f0250000c483000000000000,Gioteck VX2 Controller,a:b2,b:b1,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:b3,y:b0,",
     "03000000f0250000c283000000000000,Gioteck,a:b2,b:b1,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:b3,y:b0,",
     "03000000632500002605000000000000,HJD-X,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
+    "030000000d0f00008400000000000000,HORI Fighting Commander,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:a5,start:b9,x:b0,y:b3,",
+    "030000000d0f00008500000000000000,HORI Fighting Commander,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,",
     "030000000d0f00006e00000000000000,HORIPAD 4 (PS3),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,",
     "030000000d0f00006600000000000000,HORIPAD 4 (PS4),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,",
     "030000000d0f0000ee00000000000000,HORIPAD mini4,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:a5,start:b9,x:b0,y:b3,",
@@ -137,6 +138,8 @@ static const char *s_ControllerMappings [] =
     "030000006d04000019c2000000000000,Logitech F710 Gamepad,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. */
     "03000000380700008081000000000000,MADCATZ SFV Arcade FightStick Alpha PS4,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
     "03000000380700006382000000000000,MLG GamePad 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,",
+    "03000000c62400002a89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
+    "03000000c62400002b89000000000000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
     "03000000250900006688000000000000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,",
     "03000000380700006652000000000000,Mad Catz C.T.R.L.R,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:a3,righty:a4,start:b9,x:b0,y:b3,",
     "03000000380700005032000000000000,Mad Catz FightPad PRO (PS3),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,",
@@ -170,6 +173,7 @@ static const char *s_ControllerMappings [] =
     "03000000782300000a10000000000000,Onlive Wireless Controller,a:b15,b:b14,back:b7,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b11,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b13,y:b12,",
     "030000006b14000001a1000000000000,Orange Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a4,rightx:a5,righty:a2,start:b9,x:b2,y:b3,",
     "03000000120c0000f60e000000000000,P4 Wired Gamepad,a:b1,b:b2,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b5,lefttrigger:b7,rightshoulder:b4,righttrigger:b6,start:b9,x:b0,y:b3,",
+    "030000006f0e00000901000000000000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
     "03000000632500002306000000000000,PS Controller,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
     "03000000e30500009605000000000000,PS to USB convert cable,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,",
     "03000000100800000100000000000000,PS1 Controller,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a3,righty:a2,start:b9,x:b3,y:b0,",
@@ -241,6 +245,7 @@ static const char *s_ControllerMappings [] =
     "030000009b2800000500000000000000,Saturn_Adapter_2.0,a:b1,b:b2,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b0,y:b3,",
     "030000008f0e00000800000000000000,SpeedLink Strike FX,a:b2,b:b1,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:b3,y:b0,",
     "03000000c01100000591000000000000,Speedlink Torid,a:b2,b:b1,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:b3,y:b0,",
+    "03000000d11800000094000000000000,Stadia Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b6,lefttrigger:b12,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:b11,rightx:a3,righty:a4,start:b9,x:b2,y:b3,",
     "03000000381000001814000000000000,SteelSeries Stratus XL,a:b0,b:b1,back:b18,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b19,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b2,y:b3,",
     "03000000110100001914000000000000,SteelSeries,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:,leftstick:b13,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:,rightstick:b14,righttrigger:b7,rightx:a3,righty:a4,start:b11,x:b3,y:b4,",
     "03000000d620000011a7000000000000,Switch,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,",
@@ -280,12 +285,15 @@ static const char *s_ControllerMappings [] =
     "03000000022000000090000001000000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
     "03000000203800000900000000010000,8Bitdo NES30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
     "03000000102800000900000000000000,8Bitdo SFC30 GamePad Joystick,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
+    "03000000c82d00000160000001000000,8Bitdo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
     "03000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,",
     "03000000a00500003232000009010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,",
     "03000000d62000002a79000000010000,BDA PS4 Fightpad,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,",
     "030000008305000031b0000000000000,Cideko AK08b,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,",
     "03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,",
     "03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,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:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,",
+    "030000000d0f00008400000000010000,Fighting Commander,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,",
+    "030000000d0f00008500000000010000,Fighting Commander,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,",
     "03000000790000000600000000000000,G-Shark GP-702,a:b2,b:b1,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:a3,righty:a4,start:b9,x:b3,y:b0,",
     "0500000047532047616d657061640000,GameStop Gamepad,a:b0,b:b1,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:b2,y:b3,",
     "03000000ad1b000001f9000000000000,Gamestop BB-070 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,",
@@ -306,6 +314,8 @@ static const char *s_ControllerMappings [] =
     "030000006d0400001fc2000000000000,Logitech F710 Gamepad (XInput),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,",
     "030000006d04000019c2000000000000,Logitech Wireless 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,", /* This includes F710 in DInput mode and the "Logitech Cordless RumblePad 2", at the very least. */
     "03000000d8140000cecf000000000000,MC Cthulhu,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
+    "03000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b21,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
+    "03000000c62400002b89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
     "03000000380700005032000000010000,Mad Catz FightPad PRO (PS3),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,",
     "03000000380700005082000000010000,Mad Catz FightPad PRO (PS4),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,",
     "03000000380700008433000000010000,Mad Catz FightStick TE S+ (PS3),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,",
@@ -314,7 +324,9 @@ static const char *s_ControllerMappings [] =
     "0300000025090000e803000000000000,Mayflash Wii Classic Controller,a:b1,b:b0,back:b8,dpdown:b13,dpleft:b12,dpright:b14,dpup:b11,guide:b10,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,",
     "03000000790000000018000000000000,Mayflash WiiU Pro Game Controller Adapter (DInput),a:b4,b:b8,back:b32,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b16,leftstick:b40,lefttrigger:b24,leftx:a0,lefty:a4,rightshoulder:b20,rightstick:b44,righttrigger:b28,rightx:a8,righty:a12,start:b36,x:b0,y:b12,",
     "030000001008000001e5000006010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,",
+    "03000000550900001472000025050000,NVIDIA Controller v01.04,a:b0,b:b1,back:b17,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b15,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,",
     "030000007e0500000920000000000000,Nintendo Switch Pro Controller,a:b0,b:b1,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:b2,y:b3,",
+    "030000006f0e00000901000002010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
     "030000004c0500006802000000000000,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,",
     "030000004c0500006802000000010000,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,",
     "030000004c050000a00b000000010000,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,",
@@ -336,6 +348,7 @@ static const char *s_ControllerMappings [] =
     "03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,",
     "030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,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,",
     "030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,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,",
+    "03000000d11800000094000000010000,Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
     "030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,",
     "03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,",
     "03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,",
@@ -352,6 +365,7 @@ static const char *s_ControllerMappings [] =
     "050000005769696d6f74652028313800,Wii U Pro Controller,a:b16,b:b15,back:b7,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b8,leftshoulder:b19,leftstick:b23,lefttrigger:b21,leftx:a0,lefty:a1,rightshoulder:b20,rightstick:b24,righttrigger:b22,rightx:a2,righty:a3,start:b6,x:b18,y:b17,",
     "030000005e0400008e02000000000000,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,",
     "03000000c6240000045d000000000000,Xbox 360 Wired 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,",
+    "030000005e040000050b000003090000,Xbox Elite Wireless Controller,a:b0,b:b1,back:b38,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
     "030000005e040000d102000000000000,Xbox One Wired 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,",
     "030000005e040000dd02000000000000,Xbox One Wired 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,",
     "030000005e040000e302000000000000,Xbox One Wired 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,",
@@ -372,7 +386,8 @@ static const char *s_ControllerMappings [] =
     "05000000c82d00000061000000010000,8Bitdo SF30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
     "05000000102800000900000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
     "05000000c82d00003028000000010000,8Bitdo SFC30 GamePad,a:b1,b:b0,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b4,y:b3,",
-    "05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,leftshoulder:b6,leftx:a0,lefty:a1,rightshoulder:b7,start:b11,x:b3,y:b4,",
+    "03000000c82d00000160000011010000,8Bitdo SN30 Pro,a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b13,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b4,y:b3,",
+    "05000000a00500003232000001000000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:b122,dpleft:b119,dpright:b120,dpup:b117,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,",
     "05000000a00500003232000008010000,8Bitdo Zero GamePad,a:b0,b:b1,back:b10,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b11,x:b3,y:b4,",
     "05000000050b00000045000031000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,",
     "05000000050b00000045000040000000,ASUS Gamepad,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b6,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b10,x:b2,y:b3,",
@@ -405,6 +420,8 @@ static const char *s_ControllerMappings [] =
     "030000000d0f00002200000011010000,HORI CO. LTD. REAL ARCADE Pro.V3,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
     "030000000d0f00006a00000011010000,HORI CO. LTD. Real Arcade Pro.4,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,",
     "030000000d0f00006b00000011010000,HORI CO. LTD. Real Arcade Pro.4,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,",
+    "030000000d0f00008400000011010000,HORI Fighting Commander,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,",
+    "030000000d0f00008500000010010000,HORI Fighting Commander,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,",
     "030000000d0f00006e00000011010000,HORIPAD 4 (PS3),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,",
     "030000000d0f00006600000011010000,HORIPAD 4 (PS4),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,",
     "030000000d0f00006700000001010000,HORIPAD ONE,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,",
@@ -412,8 +429,10 @@ static const char *s_ControllerMappings [] =
     "03000000d81400000862000011010000,HitBox (PS3/PC) Analog Mode,a:b1,b:b2,back:b8,guide:b9,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,start:b12,x:b0,y:b3,",
     "030000000d0f00005f00000011010000,Hori Fighting Commander 4 (PS3),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,",
     "030000000d0f00005e00000011010000,Hori Fighting Commander 4 (PS4),a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,",
+    "030000000d0f00008600000002010000,Hori Fighting Commander,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,",
     "03000000ad1b000001f5000033050000,Hori Pad EX Turbo 2,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,",
     "030000008f0e00001330000010010000,HuiJia SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b6,rightshoulder:b7,start:b9,x:b3,y:b0,",
+    "03000000242e00008816000001010000,Hyperkin X91,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,",
     "03000000d80400008200000003000000,IMS PCU#0 Gamepad Interface,a:b1,b:b0,back:b4,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,start:b5,x:b3,y:b2,",
     "03000000fd0500000030000000010000,InterAct GoPad I-73000 (Fighting Game Layout),a:b3,b:b4,back:b6,leftx:a0,lefty:a1,rightshoulder:b2,righttrigger:b5,start:b7,x:b0,y:b1,",
     "030000006e0500000320000010010000,JC-U3613M - DirectInput Mode,a:b2,b:b3,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a2,righty:a3,start:b11,x:b0,y:b1,",
@@ -430,6 +449,8 @@ static const char *s_ControllerMappings [] =
     "030000006d04000015c2000010010000,Logitech Logitech Extreme 3D,a:b0,b:b4,back:b6,guide:b8,leftshoulder:b9,leftstick:h0.8,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:h0.2,start:b7,x:b2,y:b5,",
     "030000006d04000018c2000010010000,Logitech RumblePad 2,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,",
     "030000006d04000011c2000010010000,Logitech WingMan Cordless RumblePad,a:b0,b:b1,back:b2,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b5,leftshoulder:b6,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b10,rightx:a3,righty:a4,start:b8,x:b3,y:b4,",
+    "03000000c62400002b89000011010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
+    "05000000c62400002a89000000010000,MOGA XP5-A Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b22,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
     "03000000250900006688000000010000,MP-8866 Super Dual Box,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,",
     "05000000380700006652000025010000,Mad Catz C.T.R.L.R ,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,",
     "03000000380700005032000011010000,Mad Catz FightPad PRO (PS3),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,",
@@ -455,6 +476,7 @@ static const char *s_ControllerMappings [] =
     "030000005e0400008902000021010000,Microsoft X-Box pad v2 (US),a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,",
     "05000000d6200000ad0d000001000000,Moga Pro,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
     "030000001008000001e5000010010000,NEXT SNES Controller,a:b2,b:b1,back:b8,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b6,start:b9,x:b3,y:b0,",
+    "03000000550900001472000011010000,NVIDIA Controller v01.04,a:b0,b:b1,back:b14,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b17,leftshoulder:b4,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,",
     "03000000550900001072000011010000,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b13,leftshoulder:b4,leftstick:b8,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
     "03000000451300000830000010010000,NYKO CORE,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:a5,start:b9,x:b0,y:b3,",
     "030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,",
@@ -467,11 +489,12 @@ static const char *s_ControllerMappings [] =
     "030000005e0400000202000000010000,Old Xbox pad,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,",
     "03000000ff1100003133000010010000,PC Game Controller,a:b2,b:b1,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:b3,y:b0,",
     "030000006f0e00006401000001010000,PDP Battlefield One,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,",
+    "030000006f0e00000901000011010000,PDP Versus Fighting Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,lefttrigger:b6,rightshoulder:b5,righttrigger:b7,start:b9,x:b0,y:b3,",
     "03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,",
     "03000000341a00003608000011010000,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,",
     "030000004c0500006802000010010000,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,",
     "030000004c0500006802000010810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,",
-    "030000004c0500006802000011010000,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,",
+    "030000004c0500006802000011010000,PS3 Controller,a:b14,b:b13,back:b0,dpdown:b6,dpleft:b7,dpright:b5,dpup:b4,guide:b16,leftshoulder:b10,leftstick:b1,lefttrigger:a12,leftx:a0,lefty:a1,rightshoulder:b11,rightstick:b2,righttrigger:a13,rightx:a2,righty:a3,start:b3,x:b15,y:b12,",
     "030000004c0500006802000011810000,PS3 Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:a5,rightx:a3,righty:a4,start:b9,x:b3,y:b2,",
     "030000006f0e00001402000011010000,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,",
     "030000008f0e00000300000010010000,PS3 Controller,a:b2,b:b1,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:b3,y:b0,",
@@ -527,6 +550,7 @@ static const char *s_ControllerMappings [] =
     "03000000250900000500000000010000,Sony PS2 pad with SmartJoy adapter,a:b2,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b6,leftstick:b10,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b11,righttrigger:b5,rightx:a2,righty:a3,start:b8,x:b3,y:b0,",
     "030000005e0400008e02000020200000,SpeedLink XEOX Pro Analog Gamepad pad,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,",
     "030000005e0400008e02000073050000,Speedlink TORID Wireless Gamepad,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,",
+    "03000000d11800000094000011010000,Stadia 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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
     "03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
     "03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
     "03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,",
@@ -563,6 +587,7 @@ static const char *s_ControllerMappings [] =
     "0000000058626f782033363020576900,Xbox 360 Wireless Controller,a:b0,b:b1,back:b14,dpdown:b11,dpleft:b12,dpright:b13,dpup:b10,guide:b7,leftshoulder:b4,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,",
     "030000005e040000a102000014010000,Xbox 360 Wireless Receiver (XBOX),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,",
     "0000000058626f782047616d65706100,Xbox Gamepad (userspace driver),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:a5,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a4,rightx:a2,righty:a3,start:b7,x:b2,y:b3,",
+    "050000005e040000050b000003090000,Xbox One Elite Series 2,a:b0,b:b1,back:b136,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b137,leftshoulder:b6,leftstick:b13,lefttrigger:a6,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a5,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
     "030000005e040000ea02000001030000,Xbox One Wireless Controller (Model 1708),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,",
     "050000005e040000e002000003090000,Xbox One Wireless 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,",
     "050000005e040000fd02000003090000,Xbox One Wireless Controller,a:b0,b:b1,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b16,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,",
@@ -582,6 +607,7 @@ static const char *s_ControllerMappings [] =
     "05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
     "050000005509000003720000cf7f3f00,NVIDIA Controller v01.01,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,",
     "050000005509000010720000ffff3f00,NVIDIA Controller v01.03,a:b0,b:b1,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,",
+    "050000005509000014720000df7f3f00,NVIDIA Controller v01.04,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,",
     "050000007e05000009200000ffff0f00,Nintendo Switch Pro Controller,a:b0,b:b1,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:b9,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:b10,rightx:a2,righty:a3,start:b16,x:b17,y:b2,", /* Extremely slow in Bluetooth mode on Android */
     "050000004c05000068020000dfff3f00,PS3 Controller,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,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,",
     "050000004c050000c4050000fffe3f00,PS4 Controller,a:b1,b:b17,back:b15,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,guide:b5,leftshoulder:b3,leftstick:b4,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b6,righttrigger:+a4,rightx:a2,righty:a5,start:b16,x:b0,y:b2,",

+ 72 - 40
sdl.mod/SDL/src/joystick/SDL_joystick.c

@@ -833,43 +833,49 @@ int
 SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value)
 {
     int posted;
+    SDL_JoystickAxisInfo *info;
 
     /* Make sure we're not getting garbage or duplicate events */
     if (axis >= joystick->naxes) {
         return 0;
     }
-    if (!joystick->axes[axis].has_initial_value) {
-        joystick->axes[axis].initial_value = value;
-        joystick->axes[axis].value = value;
-        joystick->axes[axis].zero = value;
-        joystick->axes[axis].has_initial_value = SDL_TRUE;
+
+    info = &joystick->axes[axis];
+    if (!info->has_initial_value ||
+        (!info->has_second_value && info->initial_value == -32768 && SDL_abs(value) < (SDL_JOYSTICK_AXIS_MAX / 4))) {
+        info->initial_value = value;
+        info->value = value;
+        info->zero = value;
+        info->has_initial_value = SDL_TRUE;
+    } else {
+        info->has_second_value = SDL_TRUE;
     }
-    if (value == joystick->axes[axis].value) {
+    if (value == info->value) {
         return 0;
     }
-    if (!joystick->axes[axis].sent_initial_value) {
+    if (!info->sent_initial_value) {
         /* Make sure we don't send motion until there's real activity on this axis */
         const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80;  /* ShanWan PS3 controller needed 96 */
-        if (SDL_abs(value - joystick->axes[axis].value) <= MAX_ALLOWED_JITTER) {
+        if (SDL_abs(value - info->value) <= MAX_ALLOWED_JITTER) {
             return 0;
         }
-        joystick->axes[axis].sent_initial_value = SDL_TRUE;
-        joystick->axes[axis].value = value; /* Just so we pass the check above */
-        SDL_PrivateJoystickAxis(joystick, axis, joystick->axes[axis].initial_value);
+        info->sent_initial_value = SDL_TRUE;
+        info->value = value; /* Just so we pass the check above */
+        SDL_PrivateJoystickAxis(joystick, axis, info->initial_value);
     }
 
     /* We ignore events if we don't have keyboard focus, except for centering
      * events.
      */
     if (SDL_PrivateJoystickShouldIgnoreEvent()) {
-        if ((value > joystick->axes[axis].zero && value >= joystick->axes[axis].value) ||
-            (value < joystick->axes[axis].zero && value <= joystick->axes[axis].value)) {
+        if ((value > info->zero && value >= info->value) ||
+            (value < info->zero && value <= info->value)) {
             return 0;
         }
     }
 
     /* Update internal joystick state */
-    joystick->axes[axis].value = value;
+    info->value = value;
 
     /* Post the event, if desired */
     posted = 0;
@@ -1158,12 +1164,6 @@ void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *prod
     }
 }
 
-SDL_bool
-SDL_IsJoystickPS4(Uint16 vendor, Uint16 product)
-{
-    return (GuessControllerType(vendor, product) == k_eControllerType_PS4Controller);
-}
-
 SDL_bool
 SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
 {
@@ -1172,38 +1172,70 @@ SDL_IsJoystickNintendoSwitchPro(Uint16 vendor, Uint16 product)
             eType == k_eControllerType_SwitchInputOnlyController);
 }
 
-SDL_bool
-SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor, Uint16 product)
+SDL_GameControllerType
+SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name)
 {
-    EControllerType eType = GuessControllerType(vendor, product);
-    return (eType == k_eControllerType_SwitchInputOnlyController);
-}
+    SDL_GameControllerType type;
+    Uint16 vendor, product;
 
-SDL_bool
-SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
-{
-    EControllerType eType = GuessControllerType(vendor, product);
-    return (eType == k_eControllerType_SteamController ||
-            eType == k_eControllerType_SteamControllerV2);
+    SDL_GetJoystickGUIDInfo(guid, &vendor, &product, NULL);
+    type = SDL_GetJoystickGameControllerType(vendor, product, name);
+    if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
+        if (SDL_IsJoystickXInput(guid)) {
+            /* This is probably an Xbox One controller */
+            return SDL_CONTROLLER_TYPE_XBOXONE;
+        }
+    }
+    return type;
 }
 
-SDL_bool
-SDL_IsJoystickXbox360(Uint16 vendor, Uint16 product)
+SDL_GameControllerType
+SDL_GetJoystickGameControllerType(Uint16 vendor, Uint16 product, const char *name)
 {
-    /* Filter out some bogus values here */
     if (vendor == 0x0000 && product == 0x0000) {
-        return SDL_FALSE;
+        /* Some devices are only identifiable by their name */
+        if (SDL_strcmp(name, "Lic Pro Controller") == 0 ||
+            SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 ||
+            SDL_strcmp(name, "Wireless Gamepad") == 0) {
+            /* HORI or PowerA Switch Pro Controller clone */
+            return SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
+        }
+        return SDL_CONTROLLER_TYPE_UNKNOWN;
     }
     if (vendor == 0x0001 && product == 0x0001) {
-        return SDL_FALSE;
+        return SDL_CONTROLLER_TYPE_UNKNOWN;
+    }
+
+    switch (GuessControllerType(vendor, product)) {
+    case k_eControllerType_XBox360Controller:
+        return SDL_CONTROLLER_TYPE_XBOX360;
+    case k_eControllerType_XBoxOneController:
+        return SDL_CONTROLLER_TYPE_XBOXONE;
+    case k_eControllerType_PS3Controller:
+        return SDL_CONTROLLER_TYPE_PS3;
+    case k_eControllerType_PS4Controller:
+        return SDL_CONTROLLER_TYPE_PS4;
+    case k_eControllerType_SwitchProController:
+    case k_eControllerType_SwitchInputOnlyController:
+        return SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO;
+    default:
+        return SDL_CONTROLLER_TYPE_UNKNOWN;
     }
-    return (GuessControllerType(vendor, product) == k_eControllerType_XBox360Controller);
 }
 
 SDL_bool
-SDL_IsJoystickXboxOne(Uint16 vendor, Uint16 product)
+SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor, Uint16 product)
+{
+    EControllerType eType = GuessControllerType(vendor, product);
+    return (eType == k_eControllerType_SwitchInputOnlyController);
+}
+
+SDL_bool
+SDL_IsJoystickSteamController(Uint16 vendor, Uint16 product)
 {
-    return (GuessControllerType(vendor, product) == k_eControllerType_XBoxOneController);
+    EControllerType eType = GuessControllerType(vendor, product);
+    return (eType == k_eControllerType_SteamController ||
+            eType == k_eControllerType_SteamControllerV2);
 }
 
 SDL_bool
@@ -1481,7 +1513,7 @@ SDL_bool SDL_ShouldIgnoreJoystick(const char *name, SDL_JoystickGUID guid)
         }
     }
 
-    if (SDL_IsJoystickPS4(vendor, product) && SDL_IsPS4RemapperRunning()) {
+    if (SDL_GetJoystickGameControllerType(vendor, product, name) == SDL_CONTROLLER_TYPE_PS4 && SDL_IsPS4RemapperRunning()) {
         return SDL_TRUE;
     }
 

+ 4 - 9
sdl.mod/SDL/src/joystick/SDL_joystick_c.h

@@ -25,6 +25,7 @@
 #include "../SDL_internal.h"
 
 /* Useful functions and variables from SDL_joystick.c */
+#include "SDL_gamecontroller.h"
 #include "SDL_joystick.h"
 
 struct _SDL_JoystickDriver;
@@ -51,22 +52,16 @@ extern int SDL_JoystickGetDeviceIndexFromInstanceID(SDL_JoystickID instance_id);
 /* Function to extract information from an SDL joystick GUID */
 extern void SDL_GetJoystickGUIDInfo(SDL_JoystickGUID guid, Uint16 *vendor, Uint16 *product, Uint16 *version);
 
-/* Function to return whether a joystick is a PS4 controller */
-extern SDL_bool SDL_IsJoystickPS4(Uint16 vendor_id, Uint16 product_id);
+/* Function to return the type of a controller */
+extern SDL_GameControllerType SDL_GetJoystickGameControllerTypeFromGUID(SDL_JoystickGUID guid, const char *name);
+extern SDL_GameControllerType SDL_GetJoystickGameControllerType(Uint16 vendor, Uint16 product, const char *name);
 
 /* Function to return whether a joystick is a Nintendo Switch Pro controller */
-extern SDL_bool SDL_IsJoystickNintendoSwitchPro( Uint16 vendor_id, Uint16 product_id );
 extern SDL_bool SDL_IsJoystickNintendoSwitchProInputOnly(Uint16 vendor_id, Uint16 product_id);
 
 /* Function to return whether a joystick is a Steam Controller */
 extern SDL_bool SDL_IsJoystickSteamController(Uint16 vendor_id, Uint16 product_id);
 
-/* Function to return whether a joystick is an Xbox 360 controller */
-extern SDL_bool SDL_IsJoystickXbox360(Uint16 vendor_id, Uint16 product_id);
-
-/* Function to return whether a joystick is an Xbox One controller */
-extern SDL_bool SDL_IsJoystickXboxOne(Uint16 vendor_id, Uint16 product_id);
-
 /* Function to return whether a joystick guid comes from the XInput driver */
 extern SDL_bool SDL_IsJoystickXInput(SDL_JoystickGUID guid);
 

+ 1 - 0
sdl.mod/SDL/src/joystick/SDL_sysjoystick.h

@@ -35,6 +35,7 @@ typedef struct _SDL_JoystickAxisInfo
     Sint16 value;               /* Current axis state */
     Sint16 zero;                /* Zero point on the axis (-32768 for triggers) */
     SDL_bool has_initial_value; /* Whether we've seen a value on the axis yet */
+    SDL_bool has_second_value;  /* Whether we've seen a second value on the axis yet */
     SDL_bool sent_initial_value; /* Whether we've sent the initial axis value */
 } SDL_JoystickAxisInfo;
 

+ 169 - 154
sdl.mod/SDL/src/joystick/controller_type.h

@@ -69,6 +69,101 @@ typedef struct
 } ControllerDescription_t;
 
 static const ControllerDescription_t arrControllers[] = {
+	{ MAKE_CONTROLLER_ID( 0x0079, 0x181a ), k_eControllerType_PS3Controller },	// Venom Arcade Stick
+	{ MAKE_CONTROLLER_ID( 0x0079, 0x1844 ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller },	// Firestorm Dual Analog 3
+	{ MAKE_CONTROLLER_ID( 0x044f, 0xd007 ), k_eControllerType_PS3Controller },	// Thrustmaster wireless 3-1
+	{ MAKE_CONTROLLER_ID( 0x054c, 0x0268 ), k_eControllerType_PS3Controller },	// Sony PS3 Controller
+	{ MAKE_CONTROLLER_ID( 0x056e, 0x200f ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x056e, 0x2013 ), k_eControllerType_PS3Controller },	// JC-U4113SBK
+	{ MAKE_CONTROLLER_ID( 0x05b8, 0x1004 ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x05b8, 0x1006 ), k_eControllerType_PS3Controller },	// JC-U3412SBK
+	{ MAKE_CONTROLLER_ID( 0x06a3, 0xf622 ), k_eControllerType_PS3Controller },	// Cyborg V3
+	{ MAKE_CONTROLLER_ID( 0x0738, 0x3180 ), k_eControllerType_PS3Controller },	// Mad Catz Alpha PS3 mode
+	{ MAKE_CONTROLLER_ID( 0x0738, 0x3250 ), k_eControllerType_PS3Controller },	// madcats fightpad pro ps3
+	{ MAKE_CONTROLLER_ID( 0x0738, 0x8180 ), k_eControllerType_PS3Controller },	// Mad Catz Alpha PS4 mode (no touchpad on device)
+	{ MAKE_CONTROLLER_ID( 0x0738, 0x8838 ), k_eControllerType_PS3Controller },	// Madcatz Fightstick Pro
+	{ MAKE_CONTROLLER_ID( 0x0810, 0x0001 ), k_eControllerType_PS3Controller },	// actually ps2 - maybe break out later
+	{ MAKE_CONTROLLER_ID( 0x0810, 0x0003 ), k_eControllerType_PS3Controller },	// actually ps2 - maybe break out later
+	{ MAKE_CONTROLLER_ID( 0x0925, 0x0005 ), k_eControllerType_PS3Controller },	// Sony PS3 Controller
+	{ MAKE_CONTROLLER_ID( 0x0925, 0x8866 ), k_eControllerType_PS3Controller },	// PS2 maybe break out later
+	{ MAKE_CONTROLLER_ID( 0x0925, 0x8888 ), k_eControllerType_PS3Controller },	// Actually ps2 -maybe break out later Lakeview Research WiseGroup Ltd, MP-8866 Dual Joypad
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0109 ), k_eControllerType_PS3Controller },	// PDP Versus Fighting Pad
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x011e ), k_eControllerType_PS3Controller },	// Rock Candy PS4
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0128 ), k_eControllerType_PS3Controller },	// Rock Candy PS3
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0203 ), k_eControllerType_PS3Controller },	// Victrix Pro FS (PS4 peripheral but no trackpad/lightbar)
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0214 ), k_eControllerType_PS3Controller },	// afterglow ps3
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x1314 ), k_eControllerType_PS3Controller },	// PDP Afterglow Wireless PS3 controller
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x6302 ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x0e8f, 0x0008 ), k_eControllerType_PS3Controller },	// Green Asia
+	{ MAKE_CONTROLLER_ID( 0x0e8f, 0x3075 ), k_eControllerType_PS3Controller },	// SpeedLink Strike FX
+	{ MAKE_CONTROLLER_ID( 0x0e8f, 0x310d ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0009 ), k_eControllerType_PS3Controller },	// HORI BDA GP1
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x004d ), k_eControllerType_PS3Controller },	// Horipad 3
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x005e ), k_eControllerType_PS3Controller },	// HORI Fighting commander ps4
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x005f ), k_eControllerType_PS3Controller },	// HORI Fighting commander ps3
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x006a ), k_eControllerType_PS3Controller },	// Real Arcade Pro 4
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x006e ), k_eControllerType_PS3Controller },	// HORI horipad4 ps3
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0085 ), k_eControllerType_PS3Controller },	// HORI Fighting Commander PS3
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0086 ), k_eControllerType_PS3Controller },	// HORI Fighting Commander PC (Uses the Xbox 360 protocol, but has PS3 buttons)
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0087 ), k_eControllerType_PS3Controller },	// HORI fighting mini stick
+	{ MAKE_CONTROLLER_ID( 0x0f30, 0x1100 ), k_eControllerType_PS3Controller },	// Quanba Q1 fight stick
+	{ MAKE_CONTROLLER_ID( 0x11ff, 0x3331 ), k_eControllerType_PS3Controller },	// SRXJ-PH2400
+	{ MAKE_CONTROLLER_ID( 0x1345, 0x1000 ), k_eControllerType_PS3Controller },	// PS2 ACME GA-D5
+	{ MAKE_CONTROLLER_ID( 0x1345, 0x6005 ), k_eControllerType_PS3Controller },	// ps2 maybe break out later
+	{ MAKE_CONTROLLER_ID( 0x146b, 0x0603 ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x146b, 0x5500 ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x1a34, 0x0836 ), k_eControllerType_PS3Controller },	// Afterglow PS3
+	{ MAKE_CONTROLLER_ID( 0x20bc, 0x5500 ), k_eControllerType_PS3Controller },	// ShanWan PS3
+	{ MAKE_CONTROLLER_ID( 0x20d6, 0x576d ), k_eControllerType_PS3Controller },	// Power A PS3
+	{ MAKE_CONTROLLER_ID( 0x20d6, 0xca6d ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x2563, 0x0523 ), k_eControllerType_PS3Controller },	// Digiflip GP006
+	{ MAKE_CONTROLLER_ID( 0x2563, 0x0575 ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x25f0, 0x83c3 ), k_eControllerType_PS3Controller },	// gioteck vx2
+	{ MAKE_CONTROLLER_ID( 0x25f0, 0xc121 ), k_eControllerType_PS3Controller },	//
+	{ MAKE_CONTROLLER_ID( 0x2c22, 0x2000 ), k_eControllerType_PS3Controller },	// Quanba Drone
+	{ MAKE_CONTROLLER_ID( 0x2c22, 0x2003 ), k_eControllerType_PS3Controller },	// From SDL
+	{ MAKE_CONTROLLER_ID( 0x8380, 0x0003 ), k_eControllerType_PS3Controller },	// BTP 2163
+	{ MAKE_CONTROLLER_ID( 0x8888, 0x0308 ), k_eControllerType_PS3Controller },	// Sony PS3 Controller
+
+	{ MAKE_CONTROLLER_ID( 0x0079, 0x181b ), k_eControllerType_PS4Controller },	// Venom Arcade Stick - XXX:this may not work and may need to be called a ps3 controller
+	{ MAKE_CONTROLLER_ID( 0x054c, 0x05c4 ), k_eControllerType_PS4Controller },	// Sony PS4 Controller
+	{ MAKE_CONTROLLER_ID( 0x054c, 0x05c5 ), k_eControllerType_PS4Controller },	// STRIKEPAD PS4 Grip Add-on
+	{ MAKE_CONTROLLER_ID( 0x054c, 0x09cc ), k_eControllerType_PS4Controller },	// Sony PS4 Slim Controller
+	{ MAKE_CONTROLLER_ID( 0x054c, 0x0ba0 ), k_eControllerType_PS4Controller },	// Sony PS4 Controller (Wireless dongle)
+	{ MAKE_CONTROLLER_ID( 0x0738, 0x8250 ), k_eControllerType_PS4Controller },	// Mad Catz FightPad Pro PS4
+	{ MAKE_CONTROLLER_ID( 0x0738, 0x8384 ), k_eControllerType_PS4Controller },	// Mad Catz FightStick TE S+ PS4
+	{ MAKE_CONTROLLER_ID( 0x0738, 0x8480 ), k_eControllerType_PS4Controller },	// Mad Catz FightStick TE 2 PS4
+	{ MAKE_CONTROLLER_ID( 0x0738, 0x8481 ), k_eControllerType_PS4Controller },	// Mad Catz FightStick TE 2+ PS4
+	{ MAKE_CONTROLLER_ID( 0x0C12, 0x0E10 ), k_eControllerType_PS4Controller },	// Armor Armor 3 Pad PS4
+	{ MAKE_CONTROLLER_ID( 0x0C12, 0x1CF6 ), k_eControllerType_PS4Controller },	// EMIO PS4 Elite Controller
+	{ MAKE_CONTROLLER_ID( 0x0c12, 0x0e15 ), k_eControllerType_PS4Controller },	// Game:Pad 4
+	{ MAKE_CONTROLLER_ID( 0x0c12, 0x0ef6 ), k_eControllerType_PS4Controller },	// Hitbox Arcade Stick
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0055 ), k_eControllerType_PS4Controller },	// HORIPAD 4 FPS
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0066 ), k_eControllerType_PS4Controller },	// HORIPAD 4 FPS Plus 
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0084 ), k_eControllerType_PS4Controller },	// HORI Fighting Commander PS4
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x008a ), k_eControllerType_PS4Controller },	// HORI Real Arcade Pro 4
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x009c ), k_eControllerType_PS4Controller },	// HORI TAC PRO mousething
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00a0 ), k_eControllerType_PS4Controller },	// HORI TAC4 mousething
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00ee ), k_eControllerType_PS4Controller },	// Hori mini wired https://www.playstation.com/en-us/explore/accessories/gaming-controllers/mini-wired-gamepad/
+	{ MAKE_CONTROLLER_ID( 0x11c0, 0x4001 ), k_eControllerType_PS4Controller },	// "PS4 Fun Controller" added from user log
+	{ MAKE_CONTROLLER_ID( 0x146b, 0x0d01 ), k_eControllerType_PS4Controller },	// Nacon Revolution Pro Controller - has gyro
+	{ MAKE_CONTROLLER_ID( 0x146b, 0x0d02 ), k_eControllerType_PS4Controller },	// Nacon Revolution Pro Controller v2 - has gyro
+	{ MAKE_CONTROLLER_ID( 0x146b, 0x0d10 ), k_eControllerType_PS4Controller },	// NACON Revolution Infinite - has gyro
+	{ MAKE_CONTROLLER_ID( 0x1532, 0X0401 ), k_eControllerType_PS4Controller },	// Razer Panthera PS4 Controller
+	{ MAKE_CONTROLLER_ID( 0x1532, 0x1000 ), k_eControllerType_PS4Controller },	// Razer Raiju PS4 Controller
+	{ MAKE_CONTROLLER_ID( 0x1532, 0x1004 ), k_eControllerType_PS4Controller },	// Razer Raiju 2 Ultimate USB
+	{ MAKE_CONTROLLER_ID( 0x1532, 0x1007 ), k_eControllerType_PS4Controller },	// Razer Raiju 2 Tournament edition USB
+	{ MAKE_CONTROLLER_ID( 0x1532, 0x1008 ), k_eControllerType_PS4Controller },	// Razer Panthera Evo Fightstick
+	{ MAKE_CONTROLLER_ID( 0x1532, 0x1009 ), k_eControllerType_PS4Controller },	// Razer Raiju 2 Ultimate BT
+	{ MAKE_CONTROLLER_ID( 0x1532, 0x100A ), k_eControllerType_PS4Controller },	// Razer Raiju 2 Tournament edition BT
+	{ MAKE_CONTROLLER_ID( 0x1532, 0x1100 ), k_eControllerType_PS4Controller },	// Razer AION Fightstick - Trackpad, no gyro, lightbar hardcoded to green - UNANNOUNCED PRODUCT
+	{ MAKE_CONTROLLER_ID( 0x20d6, 0x792a ), k_eControllerType_PS4Controller },	// PowerA - Fusion Fight Pad
+	{ MAKE_CONTROLLER_ID( 0x7545, 0x0104 ), k_eControllerType_PS4Controller },	// Armor 3 or Level Up Cobra - At least one variant has gyro
+	{ MAKE_CONTROLLER_ID( 0x9886, 0x0025 ), k_eControllerType_PS4Controller },	// Astro C40
+
+	{ MAKE_CONTROLLER_ID( 0x0079, 0x0006 ), k_eControllerType_UnknownNonSteamController },	// DragonRise Generic USB PCB, sometimes configured as a PC Twin Shock Controller - looks like a DS3 but the face buttons are 1-4 instead of symbols
+
 	{ MAKE_CONTROLLER_ID( 0x0079, 0x18d4 ), k_eControllerType_XBox360Controller },	// GPD Win 2 X-Box Controller
 	{ MAKE_CONTROLLER_ID( 0x044f, 0xb326 ), k_eControllerType_XBox360Controller },	// Thrustmaster Gamepad GP XID
 	{ MAKE_CONTROLLER_ID( 0x045e, 0x028e ), k_eControllerType_XBox360Controller },	// Microsoft X-Box 360 pad
@@ -76,115 +171,11 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x045e, 0x0291 ), k_eControllerType_XBox360Controller },	// Xbox 360 Wireless Receiver (XBOX)
 	{ MAKE_CONTROLLER_ID( 0x045e, 0x02a0 ), k_eControllerType_XBox360Controller },	// Microsoft X-Box 360 Big Button IR
 	{ MAKE_CONTROLLER_ID( 0x045e, 0x02a1 ), k_eControllerType_XBox360Controller },	// Microsoft X-Box 360 pad
-	{ MAKE_CONTROLLER_ID( 0x045e, 0x02d1 ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One pad
-	{ MAKE_CONTROLLER_ID( 0x045e, 0x02dd ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One pad (Firmware 2015)
-	{ MAKE_CONTROLLER_ID( 0x045e, 0x02e0 ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One S pad (Bluetooth)
-	{ MAKE_CONTROLLER_ID( 0x045e, 0x02e3 ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One Elite pad
-	{ MAKE_CONTROLLER_ID( 0x045e, 0x02ea ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One S pad
-	{ MAKE_CONTROLLER_ID( 0x045e, 0x02fd ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One S pad (Bluetooth)
-	{ MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One Elite pad
 	{ MAKE_CONTROLLER_ID( 0x045e, 0x0719 ), k_eControllerType_XBox360Controller },	// Xbox 360 Wireless Receiver
 	{ MAKE_CONTROLLER_ID( 0x046d, 0xc21d ), k_eControllerType_XBox360Controller },	// Logitech Gamepad F310
 	{ MAKE_CONTROLLER_ID( 0x046d, 0xc21e ), k_eControllerType_XBox360Controller },	// Logitech Gamepad F510
 	{ MAKE_CONTROLLER_ID( 0x046d, 0xc21f ), k_eControllerType_XBox360Controller },	// Logitech Gamepad F710
 	{ MAKE_CONTROLLER_ID( 0x046d, 0xc242 ), k_eControllerType_XBox360Controller },	// Logitech Chillstream Controller
-
-	{ MAKE_CONTROLLER_ID( 0x054c, 0x0268 ), k_eControllerType_PS3Controller },		// Sony PS3 Controller
-	{ MAKE_CONTROLLER_ID( 0x0925, 0x0005 ), k_eControllerType_PS3Controller },		// Sony PS3 Controller
-	{ MAKE_CONTROLLER_ID( 0x8888, 0x0308 ), k_eControllerType_PS3Controller },		// Sony PS3 Controller
-	{ MAKE_CONTROLLER_ID( 0x1a34, 0x0836 ), k_eControllerType_PS3Controller },		// Afterglow ps3
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x006e ), k_eControllerType_PS3Controller },		// HORI horipad4 ps3
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0066 ), k_eControllerType_PS3Controller },		// HORI horipad4 ps4
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x005f ), k_eControllerType_PS3Controller },		// HORI Fighting commander ps3
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x005e ), k_eControllerType_PS3Controller },		// HORI Fighting commander ps4
-	//{ MAKE_CONTROLLER_ID( 0x0738, 0x3250 ), k_eControllerType_PS3Controller },		// madcats fightpad pro ps3 already in ps4 list.. does this work??
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x8250 ), k_eControllerType_PS3Controller },		// madcats fightpad pro ps4
-	{ MAKE_CONTROLLER_ID( 0x0079, 0x181a ), k_eControllerType_PS3Controller },		// Venom Arcade Stick
-	{ MAKE_CONTROLLER_ID( 0x0079, 0x0006 ), k_eControllerType_PS3Controller },		// PC Twin Shock Controller - looks like a DS3 but the face buttons are 1-4 instead of symbols
-	{ MAKE_CONTROLLER_ID( 0x0079, 0x1844 ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x8888, 0x0308 ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x2563, 0x0575 ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x0810, 0x0001 ), k_eControllerType_PS3Controller },		// actually ps2 - maybe break out later
-	{ MAKE_CONTROLLER_ID( 0x0810, 0x0003 ), k_eControllerType_PS3Controller },		// actually ps2 - maybe break out later
-	{ MAKE_CONTROLLER_ID( 0x2563, 0x0523 ), k_eControllerType_PS3Controller },		// Digiflip GP006
-	{ MAKE_CONTROLLER_ID( 0x11ff, 0x3331 ), k_eControllerType_PS3Controller },		// SRXJ-PH2400
-	{ MAKE_CONTROLLER_ID( 0x20bc, 0x5500 ), k_eControllerType_PS3Controller },		// ShanWan PS3
-	{ MAKE_CONTROLLER_ID( 0x05b8, 0x1004 ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x146b, 0x0603 ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x044f, 0xb315 ), k_eControllerType_PS3Controller },		// Firestorm Dual Analog 3
-	{ MAKE_CONTROLLER_ID( 0x0925, 0x8888 ), k_eControllerType_PS3Controller },		// Actually ps2 -maybe break out later Lakeview Research WiseGroup Ltd, MP-8866 Dual Joypad
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x004d ), k_eControllerType_PS3Controller },		// Horipad 3
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0009 ), k_eControllerType_PS3Controller },		// HORI BDA GP1
-	{ MAKE_CONTROLLER_ID( 0x0e8f, 0x0008 ), k_eControllerType_PS3Controller },		// Green Asia
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x006a ), k_eControllerType_PS3Controller },		// Real Arcade Pro 4
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x011e ), k_eControllerType_PS3Controller },		// Rock Candy PS4
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0214 ), k_eControllerType_PS3Controller },		// afterglow ps3
-	{ MAKE_CONTROLLER_ID( 0x0925, 0x8866 ), k_eControllerType_PS3Controller },		// PS2 maybe break out later
-	{ MAKE_CONTROLLER_ID( 0x0e8f, 0x310d ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x2c22, 0x2003 ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x056e, 0x2013 ), k_eControllerType_PS3Controller },		// JC-U4113SBK
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x8838 ), k_eControllerType_PS3Controller },		// Madcatz Fightstick Pro
-	{ MAKE_CONTROLLER_ID( 0x1a34, 0x0836 ), k_eControllerType_PS3Controller },		// Afterglow PS3
-	{ MAKE_CONTROLLER_ID( 0x0f30, 0x1100 ), k_eControllerType_PS3Controller },		// Quanba Q1 fight stick
-	{ MAKE_CONTROLLER_ID( 0x1345, 0x6005 ), k_eControllerType_PS3Controller },		// ps2 maybe break out later
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0087 ), k_eControllerType_PS3Controller },		// HORI fighting mini stick
-	{ MAKE_CONTROLLER_ID( 0x146b, 0x5500 ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x20d6, 0xca6d ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x25f0, 0xc121 ), k_eControllerType_PS3Controller },		//
-	{ MAKE_CONTROLLER_ID( 0x8380, 0x0003 ), k_eControllerType_PS3Controller },		// BTP 2163
-	{ MAKE_CONTROLLER_ID( 0x1345, 0x1000 ), k_eControllerType_PS3Controller },		// PS2 ACME GA-D5
-	{ MAKE_CONTROLLER_ID( 0x0e8f, 0x3075 ), k_eControllerType_PS3Controller },		// SpeedLink Strike FX
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0128 ), k_eControllerType_PS3Controller },		// Rock Candy PS3
-	{ MAKE_CONTROLLER_ID( 0x2c22, 0x2000 ), k_eControllerType_PS3Controller },		// Quanba Drone
-	{ MAKE_CONTROLLER_ID( 0x06a3, 0xf622 ), k_eControllerType_PS3Controller },		// Cyborg V3
-	{ MAKE_CONTROLLER_ID( 0x044f, 0xd007 ), k_eControllerType_PS3Controller },		// Thrustmaster wireless 3-1
-	{ MAKE_CONTROLLER_ID( 0x25f0, 0x83c3 ), k_eControllerType_PS3Controller },		// gioteck vx2
-	{ MAKE_CONTROLLER_ID( 0x05b8, 0x1006 ), k_eControllerType_PS3Controller },		// JC-U3412SBK
-	{ MAKE_CONTROLLER_ID( 0x20d6, 0x576d ), k_eControllerType_PS3Controller },		// Power A PS3
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x6302 ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x056e, 0x200f ), k_eControllerType_PS3Controller },		// From SDL
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x1314 ), k_eControllerType_PS3Controller },		// PDP Afterglow Wireless PS3 controller
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x3180 ), k_eControllerType_PS3Controller },		// Mad Catz Alpha PS3 mode
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x8180 ), k_eControllerType_PS3Controller },		// Mad Catz Alpha PS4 mode (no touchpad on device)
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0203 ), k_eControllerType_PS3Controller },		// Victrix Pro FS (PS4 peripheral but no trackpad/lightbar)
-
-	{ MAKE_CONTROLLER_ID( 0x054c, 0x05c4 ), k_eControllerType_PS4Controller },		// Sony PS4 Controller
-	{ MAKE_CONTROLLER_ID( 0x054c, 0x09cc ), k_eControllerType_PS4Controller },		// Sony PS4 Slim Controller
-	{ MAKE_CONTROLLER_ID( 0x054c, 0x0ba0 ), k_eControllerType_PS4Controller },		// Sony PS4 Controller (Wireless dongle)
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x008a ), k_eControllerType_PS4Controller },		// HORI Real Arcade Pro 4
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0055 ), k_eControllerType_PS4Controller },		// HORIPAD 4 FPS
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0066 ), k_eControllerType_PS4Controller },		// HORIPAD 4 FPS Plus 
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x8384 ), k_eControllerType_PS4Controller },		// Mad Catz FightStick TE S+ PS4
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x8250 ), k_eControllerType_PS4Controller },		// Mad Catz FightPad Pro PS4
-	{ MAKE_CONTROLLER_ID( 0x0C12, 0x0E10 ), k_eControllerType_PS4Controller },		// Armor Armor 3 Pad PS4
-	{ MAKE_CONTROLLER_ID( 0x0C12, 0x1CF6 ), k_eControllerType_PS4Controller },		// EMIO PS4 Elite Controller
-	{ MAKE_CONTROLLER_ID( 0x1532, 0x1000 ), k_eControllerType_PS4Controller },		// Razer Raiju PS4 Controller
-	{ MAKE_CONTROLLER_ID( 0x1532, 0X0401 ), k_eControllerType_PS4Controller },		// Razer Panthera PS4 Controller
-	{ MAKE_CONTROLLER_ID( 0x054c, 0x05c5 ), k_eControllerType_PS4Controller },		// STRIKEPAD PS4 Grip Add-on
-	{ MAKE_CONTROLLER_ID( 0x146b, 0x0d01 ), k_eControllerType_PS4Controller },		// Nacon Revolution Pro Controller - has gyro
-	{ MAKE_CONTROLLER_ID( 0x146b, 0x0d02 ), k_eControllerType_PS4Controller },		// Nacon Revolution Pro Controller v2 - has gyro
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00a0 ), k_eControllerType_PS4Controller },		// HORI TAC4 mousething
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x009c ), k_eControllerType_PS4Controller },		// HORI TAC PRO mousething
-	{ MAKE_CONTROLLER_ID( 0x0c12, 0x0ef6 ), k_eControllerType_PS4Controller },		// Hitbox Arcade Stick
-	{ MAKE_CONTROLLER_ID( 0x0079, 0x181b ), k_eControllerType_PS4Controller },		// Venom Arcade Stick - XXX:this may not work and may need to be called a ps3 controller
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x3250 ), k_eControllerType_PS4Controller },		// Mad Catz FightPad PRO - controller shaped with 6 face buttons
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00ee ), k_eControllerType_PS4Controller },		// Hori mini wired https://www.playstation.com/en-us/explore/accessories/gaming-controllers/mini-wired-gamepad/
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x8481 ), k_eControllerType_PS4Controller },		// Mad Catz FightStick TE 2+ PS4
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x8480 ), k_eControllerType_PS4Controller },		// Mad Catz FightStick TE 2 PS4
-	{ MAKE_CONTROLLER_ID( 0x7545, 0x0104 ), k_eControllerType_PS4Controller },		// Armor 3 or Level Up Cobra - At least one variant has gyro
-	{ MAKE_CONTROLLER_ID( 0x0c12, 0x0e15 ), k_eControllerType_PS4Controller },		// Game:Pad 4
-	{ MAKE_CONTROLLER_ID( 0x11c0, 0x4001 ), k_eControllerType_PS4Controller },		// "PS4 Fun Controller" added from user log
-
-	{ MAKE_CONTROLLER_ID( 0x1532, 0x1007 ), k_eControllerType_PS4Controller },		// Razer Raiju 2 Tournament edition USB
-	{ MAKE_CONTROLLER_ID( 0x1532, 0x100A ), k_eControllerType_PS4Controller },		// Razer Raiju 2 Tournament edition BT
-	{ MAKE_CONTROLLER_ID( 0x1532, 0x1004 ), k_eControllerType_PS4Controller },		// Razer Raiju 2 Ultimate USB
-	{ MAKE_CONTROLLER_ID( 0x1532, 0x1009 ), k_eControllerType_PS4Controller },		// Razer Raiju 2 Ultimate BT
-	{ MAKE_CONTROLLER_ID( 0x1532, 0x1008 ), k_eControllerType_PS4Controller },		// Razer Panthera Evo Fightstick
-	{ MAKE_CONTROLLER_ID( 0x9886, 0x0025 ), k_eControllerType_PS4Controller },		// Astro C40
-	{ MAKE_CONTROLLER_ID( 0x1532, 0x1100 ), k_eControllerType_PS4Controller },		// Razer AION Fightstick - Trackpad, no gyro, lightbar hardcoded to green - UNANNOUNCED PRODUCT
-	{ MAKE_CONTROLLER_ID( 0x146b, 0x0d10 ), k_eControllerType_PS4Controller },		// NACON Revolution Infinite - has gyro
-	{ MAKE_CONTROLLER_ID( 0x20d6, 0x792a ), k_eControllerType_PS4Controller },		// PowerA - Fusion Fight Pad
-
 	{ MAKE_CONTROLLER_ID( 0x056e, 0x2004 ), k_eControllerType_XBox360Controller },	// Elecom JC-U3613M
 	{ MAKE_CONTROLLER_ID( 0x06a3, 0xf51a ), k_eControllerType_XBox360Controller },	// Saitek P3600
 	{ MAKE_CONTROLLER_ID( 0x0738, 0x4716 ), k_eControllerType_XBox360Controller },	// Mad Catz Wired Xbox 360 Controller
@@ -194,35 +185,23 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x0738, 0x4736 ), k_eControllerType_XBox360Controller },	// Mad Catz MicroCon Gamepad
 	{ MAKE_CONTROLLER_ID( 0x0738, 0x4738 ), k_eControllerType_XBox360Controller },	// Mad Catz Wired Xbox 360 Controller (SFIV)
 	{ MAKE_CONTROLLER_ID( 0x0738, 0x4740 ), k_eControllerType_XBox360Controller },	// Mad Catz Beat Pad
-	{ MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController },	// Mad Catz FightStick TE 2
 	{ MAKE_CONTROLLER_ID( 0x0738, 0xb726 ), k_eControllerType_XBox360Controller },	// Mad Catz Xbox controller - MW2
 	{ MAKE_CONTROLLER_ID( 0x0738, 0xbeef ), k_eControllerType_XBox360Controller },	// Mad Catz JOYTECH NEO SE Advanced GamePad
 	{ MAKE_CONTROLLER_ID( 0x0738, 0xcb02 ), k_eControllerType_XBox360Controller },	// Saitek Cyborg Rumble Pad - PC/Xbox 360
 	{ MAKE_CONTROLLER_ID( 0x0738, 0xcb03 ), k_eControllerType_XBox360Controller },	// Saitek P3200 Rumble Pad - PC/Xbox 360
 	{ MAKE_CONTROLLER_ID( 0x0738, 0xf738 ), k_eControllerType_XBox360Controller },	// Super SFIV FightStick TE S
-	//{ MAKE_CONTROLLER_ID( 0x0955, 0xb400 ), k_eControllerType_XBox360Controller },	// NVIDIA Shield streaming controller
+	{ MAKE_CONTROLLER_ID( 0x0955, 0x7210 ), k_eControllerType_XBox360Controller },	// Nvidia Shield local controller
+	{ MAKE_CONTROLLER_ID( 0x0955, 0xb400 ), k_eControllerType_XBox360Controller },	// NVIDIA Shield streaming controller
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0105 ), k_eControllerType_XBox360Controller },	// HSM3 Xbox360 dancepad
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0113 ), k_eControllerType_XBox360Controller },	// Afterglow AX.1 Gamepad for Xbox 360
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x011f ), k_eControllerType_XBox360Controller },	// Rock Candy Gamepad Wired Controller
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0131 ), k_eControllerType_XBox360Controller },	// PDP EA Sports Controller
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0133 ), k_eControllerType_XBox360Controller },	// Xbox 360 Wired Controller
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController },	// Afterglow Prismatic Wired Controller
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x013a ), k_eControllerType_XBoxOneController },	// PDP Xbox One Controller
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0146 ), k_eControllerType_XBoxOneController },	// Rock Candy Wired Controller for Xbox One
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0147 ), k_eControllerType_XBoxOneController },	// PDP Marvel Xbox One Controller
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x015c ), k_eControllerType_XBoxOneController },	// PDP Xbox One Arcade Stick
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0161 ), k_eControllerType_XBoxOneController },	// PDP Xbox One Controller
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0162 ), k_eControllerType_XBoxOneController },	// PDP Xbox One Controller
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0163 ), k_eControllerType_XBoxOneController },	// PDP Xbox One Controller
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0164 ), k_eControllerType_XBoxOneController },	// PDP Battlefield One
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0165 ), k_eControllerType_XBoxOneController },	// PDP Titanfall 2
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0201 ), k_eControllerType_XBox360Controller },	// Pelican PL-3601 'TSZ' Wired Xbox 360 Controller
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0213 ), k_eControllerType_XBox360Controller },	// Afterglow Gamepad for Xbox 360
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x021f ), k_eControllerType_XBox360Controller },	// Rock Candy Gamepad for Xbox 360
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0246 ), k_eControllerType_XBoxOneController },	// Rock Candy Gamepad for Xbox One 2015
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a0 ), k_eControllerType_XBox360Controller },	// Counterfeit 360Controller
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0301 ), k_eControllerType_XBox360Controller },	// Logic3 Controller
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0346 ), k_eControllerType_XBoxOneController },	// Rock Candy Gamepad for Xbox One 2016
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0401 ), k_eControllerType_XBox360Controller },	// Logic3 Controller
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0413 ), k_eControllerType_XBox360Controller },	// Afterglow AX.1 Gamepad for Xbox 360
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0501 ), k_eControllerType_XBox360Controller },	// PDP Xbox 360 Controller
@@ -233,10 +212,10 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x000d ), k_eControllerType_XBox360Controller },	// Hori Fighting Stick EX2
 	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0016 ), k_eControllerType_XBox360Controller },	// Hori Real Arcade Pro.EX
 	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x001b ), k_eControllerType_XBox360Controller },	// Hori Real Arcade Pro VX
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0063 ), k_eControllerType_XBoxOneController },	// Hori Real Arcade Pro Hayabusa (USA) Xbox One
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0067 ), k_eControllerType_XBoxOneController },	// HORIPAD ONE
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0078 ), k_eControllerType_XBoxOneController },	// Hori Real Arcade Pro V Kai Xbox One
 	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x008c ), k_eControllerType_XBox360Controller },	// Hori Real Arcade Pro 4
+	{ MAKE_CONTROLLER_ID( 0x1038, 0x1430 ), k_eControllerType_XBox360Controller },	// SteelSeries Stratus Duo
+	{ MAKE_CONTROLLER_ID( 0x1038, 0x1431 ), k_eControllerType_XBox360Controller },	// SteelSeries Stratus Duo
+	{ MAKE_CONTROLLER_ID( 0x1038, 0xb360 ), k_eControllerType_XBox360Controller },	// SteelSeries Nimbus/Stratus XL
 	{ MAKE_CONTROLLER_ID( 0x11c9, 0x55f0 ), k_eControllerType_XBox360Controller },	// Nacon GC-100XF
 	{ MAKE_CONTROLLER_ID( 0x12ab, 0x0004 ), k_eControllerType_XBox360Controller },	// Honey Bee Xbox360 dancepad
 	{ MAKE_CONTROLLER_ID( 0x12ab, 0x0301 ), k_eControllerType_XBox360Controller },	// PDP AFTERGLOW AX.1
@@ -246,8 +225,6 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x1430, 0xf801 ), k_eControllerType_XBox360Controller },	// RedOctane Controller
 	{ MAKE_CONTROLLER_ID( 0x146b, 0x0601 ), k_eControllerType_XBox360Controller },	// BigBen Interactive XBOX 360 Controller
 	{ MAKE_CONTROLLER_ID( 0x1532, 0x0037 ), k_eControllerType_XBox360Controller },	// Razer Sabertooth
-	{ MAKE_CONTROLLER_ID( 0x1532, 0x0a00 ), k_eControllerType_XBoxOneController },	// Razer Atrox Arcade Stick
-	{ MAKE_CONTROLLER_ID( 0x1532, 0x0a03 ), k_eControllerType_XBoxOneController },	// Razer Wildcat
 	{ MAKE_CONTROLLER_ID( 0x15e4, 0x3f00 ), k_eControllerType_XBox360Controller },	// Power A Mini Pro Elite
 	{ MAKE_CONTROLLER_ID( 0x15e4, 0x3f0a ), k_eControllerType_XBox360Controller },	// Xbox Airflo wired controller
 	{ MAKE_CONTROLLER_ID( 0x15e4, 0x3f10 ), k_eControllerType_XBox360Controller },	// Batarang Xbox 360 controller
@@ -296,19 +273,14 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x530a ), k_eControllerType_XBox360Controller },	// Xbox 360 Pro EX Controller
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x531a ), k_eControllerType_XBox360Controller },	// PowerA Pro Ex
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5397 ), k_eControllerType_XBox360Controller },	// FUS1ON Tournament Controller
-	{ MAKE_CONTROLLER_ID( 0x24c6, 0x541a ), k_eControllerType_XBoxOneController },	// PowerA Xbox One Mini Wired Controller
-	{ MAKE_CONTROLLER_ID( 0x24c6, 0x542a ), k_eControllerType_XBoxOneController },	// Xbox ONE spectra
-	{ MAKE_CONTROLLER_ID( 0x24c6, 0x543a ), k_eControllerType_XBoxOneController },	// PowerA Xbox One wired controller
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5500 ), k_eControllerType_XBox360Controller },	// Hori XBOX 360 EX 2 with Turbo
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5501 ), k_eControllerType_XBox360Controller },	// Hori Real Arcade Pro VX-SA
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5502 ), k_eControllerType_XBox360Controller },	// Hori Fighting Stick VX Alt
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5503 ), k_eControllerType_XBox360Controller },	// Hori Fighting Edge
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5506 ), k_eControllerType_XBox360Controller },	// Hori SOULCALIBUR V Stick
-	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5510 ), k_eControllerType_XBox360Controller },	// Hori Fighting Commander ONE
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x550d ), k_eControllerType_XBox360Controller },	// Hori GEM Xbox controller
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x550e ), k_eControllerType_XBox360Controller },	// Hori Real Arcade Pro V Kai 360
-	{ MAKE_CONTROLLER_ID( 0x24c6, 0x551a ), k_eControllerType_XBoxOneController },	// PowerA FUSION Pro Controller
-	{ MAKE_CONTROLLER_ID( 0x24c6, 0x561a ), k_eControllerType_XBoxOneController },	// PowerA FUSION Controller
+	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5510 ), k_eControllerType_XBox360Controller },	// Hori Fighting Commander ONE
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5b00 ), k_eControllerType_XBox360Controller },	// ThrustMaster Ferrari Italia 458 Racing Wheel
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5b02 ), k_eControllerType_XBox360Controller },	// Thrustmaster, Inc. GPX Controller
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0x5b03 ), k_eControllerType_XBox360Controller },	// Thrustmaster Ferrari 458 Racing Wheel
@@ -316,19 +288,55 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafa ), k_eControllerType_XBox360Controller },	// Aplay Controller
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafb ), k_eControllerType_XBox360Controller },	// Aplay Controller
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafc ), k_eControllerType_XBox360Controller },	// Afterglow Gamepad 1
-	{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafe ), k_eControllerType_XBox360Controller },	// Rock Candy Gamepad for Xbox 360
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafd ), k_eControllerType_XBox360Controller },	// Afterglow Gamepad 3
-	//{ MAKE_CONTROLLER_ID( 0x0955, 0x7210 ), k_eControllerType_XBox360Controller },	// Nvidia Shield local controller
+	{ MAKE_CONTROLLER_ID( 0x24c6, 0xfafe ), k_eControllerType_XBox360Controller },	// Rock Candy Gamepad for Xbox 360
+
+	{ MAKE_CONTROLLER_ID( 0x045e, 0x02d1 ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One pad
+	{ MAKE_CONTROLLER_ID( 0x045e, 0x02dd ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One pad (Firmware 2015)
+	{ MAKE_CONTROLLER_ID( 0x045e, 0x02e0 ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One S pad (Bluetooth)
+	{ MAKE_CONTROLLER_ID( 0x045e, 0x02e3 ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One Elite pad
+	{ MAKE_CONTROLLER_ID( 0x045e, 0x02ea ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One S pad
+	{ MAKE_CONTROLLER_ID( 0x045e, 0x02fd ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One S pad (Bluetooth)
+	{ MAKE_CONTROLLER_ID( 0x045e, 0x02ff ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One Elite pad
+	{ MAKE_CONTROLLER_ID( 0x045e, 0x0b00 ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One Elite Series 2 pad
+	{ MAKE_CONTROLLER_ID( 0x045e, 0x0b05 ), k_eControllerType_XBoxOneController },	// Microsoft X-Box One Elite Series 2 pad (Bluetooth)
+	{ MAKE_CONTROLLER_ID( 0x0738, 0x4a01 ), k_eControllerType_XBoxOneController },	// Mad Catz FightStick TE 2
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0139 ), k_eControllerType_XBoxOneController },	// Afterglow Prismatic Wired Controller
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x013a ), k_eControllerType_XBoxOneController },	// PDP Xbox One Controller
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0146 ), k_eControllerType_XBoxOneController },	// Rock Candy Wired Controller for Xbox One
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0147 ), k_eControllerType_XBoxOneController },	// PDP Marvel Xbox One Controller
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x015c ), k_eControllerType_XBoxOneController },	// PDP Xbox One Arcade Stick
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0161 ), k_eControllerType_XBoxOneController },	// PDP Xbox One Controller
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0162 ), k_eControllerType_XBoxOneController },	// PDP Xbox One Controller
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0163 ), k_eControllerType_XBoxOneController },	// PDP Xbox One Controller
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0164 ), k_eControllerType_XBoxOneController },	// PDP Battlefield One
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0165 ), k_eControllerType_XBoxOneController },	// PDP Titanfall 2
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0205 ), k_eControllerType_XBoxOneController },	// Victrix Pro FS Xbox One Edition
-	
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0246 ), k_eControllerType_XBoxOneController },	// Rock Candy Gamepad for Xbox One 2015
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a4 ), k_eControllerType_XBoxOneController },	// PDP Wired Controller for Xbox One - Stealth Series
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02a6 ), k_eControllerType_XBoxOneController },	// PDP Wired Controller for Xbox One - Camo Series
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x02ab ), k_eControllerType_XBoxOneController },	// PDP Controller for Xbox One
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0346 ), k_eControllerType_XBoxOneController },	// Rock Candy Gamepad for Xbox One 2016
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0063 ), k_eControllerType_XBoxOneController },	// Hori Real Arcade Pro Hayabusa (USA) Xbox One
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0067 ), k_eControllerType_XBoxOneController },	// HORIPAD ONE
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0078 ), k_eControllerType_XBoxOneController },	// Hori Real Arcade Pro V Kai Xbox One
+	{ MAKE_CONTROLLER_ID( 0x1532, 0x0a00 ), k_eControllerType_XBoxOneController },	// Razer Atrox Arcade Stick
+	{ MAKE_CONTROLLER_ID( 0x1532, 0x0a03 ), k_eControllerType_XBoxOneController },	// Razer Wildcat
+	{ MAKE_CONTROLLER_ID( 0x24c6, 0x541a ), k_eControllerType_XBoxOneController },	// PowerA Xbox One Mini Wired Controller
+	{ MAKE_CONTROLLER_ID( 0x24c6, 0x542a ), k_eControllerType_XBoxOneController },	// Xbox ONE spectra
+	{ MAKE_CONTROLLER_ID( 0x24c6, 0x543a ), k_eControllerType_XBoxOneController },	// PowerA Xbox One wired controller
+	{ MAKE_CONTROLLER_ID( 0x24c6, 0x551a ), k_eControllerType_XBoxOneController },	// PowerA FUSION Pro Controller
+	{ MAKE_CONTROLLER_ID( 0x24c6, 0x561a ), k_eControllerType_XBoxOneController },	// PowerA FUSION Controller
+	{ MAKE_CONTROLLER_ID( 0x24c6, 0x591a ), k_eControllerType_XBoxOneController },	// PowerA FUSION Pro Controller
+	{ MAKE_CONTROLLER_ID( 0x24c6, 0x791a ), k_eControllerType_XBoxOneController },	// PowerA Fusion Fight Pad
+	{ MAKE_CONTROLLER_ID( 0x2e24, 0x1688 ), k_eControllerType_XBoxOneController },	// Hyperkin X91
+
 	// These have been added via Minidump for unrecognized Xinput controller assert
 	{ MAKE_CONTROLLER_ID( 0x0000, 0x0000 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x045e, 0x02a2 ), k_eControllerType_XBox360Controller },	// Unknown Controller - Microsoft VID
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x1414 ), k_eControllerType_XBox360Controller },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x1314 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0159 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x24c6, 0xfaff ), k_eControllerType_XBox360Controller },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0086 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x006d ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00a4 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0079, 0x1832 ), k_eControllerType_XBox360Controller },	// Unknown Controller
@@ -343,8 +351,6 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x056e, 0x2012 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x146b, 0x0602 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00ae ), k_eControllerType_XBox360Controller },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x146b, 0x0603 ), k_eControllerType_XBox360Controller },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x056e, 0x2013 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x046d, 0x0401 ), k_eControllerType_XBox360Controller },	// logitech xinput
 	{ MAKE_CONTROLLER_ID( 0x046d, 0x0301 ), k_eControllerType_XBox360Controller },	// logitech xinput
 	{ MAKE_CONTROLLER_ID( 0x046d, 0xcaa3 ), k_eControllerType_XBox360Controller },	// logitech xinput
@@ -353,11 +359,7 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x0079, 0x18d3 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00b1 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0001, 0x0001 ), k_eControllerType_XBox360Controller },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x1345, 0x6005 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0079, 0x188e ), k_eControllerType_XBox360Controller },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x0079, 0x18d4 ), k_eControllerType_XBox360Controller },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x2c22, 0x2003 ), k_eControllerType_XBox360Controller },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00b1 ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0079, 0x187c ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0079, 0x189c ), k_eControllerType_XBox360Controller },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x0079, 0x1874 ), k_eControllerType_XBox360Controller },	// Unknown Controller
@@ -367,25 +369,20 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x2f24, 0x2e ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x9886, 0x24 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x2f24, 0x91 ), k_eControllerType_XBoxOneController },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0xe6f, 0x2a4 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x1430, 0x719 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0xf0d, 0xed ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x3eb, 0xff02 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0xf0d, 0xc0 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0xe6f, 0x152 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0xe6f, 0x2a7 ), k_eControllerType_XBoxOneController },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0xe6f, 0x2a6 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x46d, 0x1007 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0xe6f, 0x2b8 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0xe6f, 0x2a8 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x2c22, 0x2503 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x79, 0x18a1 ), k_eControllerType_XBoxOneController },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x1038, 0xb360 ), k_eControllerType_XBox360Controller },	// SteelSeries Nimbus/Stratus XL
 
 	/* Added from Minidumps 10-9-19 */
 	{ MAKE_CONTROLLER_ID( 0x0,		0x6686 ), k_eControllerType_XBoxOneController },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x1038,	0x1430 ), k_eControllerType_XBoxOneController },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x1038,	0x1431 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x11ff,	0x511 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x12ab,	0x304 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x1430,	0x291 ), k_eControllerType_XBoxOneController },	// Unknown Controller
@@ -407,12 +404,10 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x2f24,	0x11 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x2f24,	0x53 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x2f24,	0xb7 ), k_eControllerType_XBoxOneController },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x45e,	0x28e ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x45e,	0x2a9 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x46d,	0x0 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x46d,	0x1004 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x46d,	0x1008 ), k_eControllerType_XBoxOneController },	// Unknown Controller
-	{ MAKE_CONTROLLER_ID( 0x46d,	0xc21d ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x46d,	0xf301 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x738,	0x2a0 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0x738,	0x7263 ), k_eControllerType_XBoxOneController },	// Unknown Controller
@@ -444,7 +439,6 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0xf0d,	0xd8 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 	{ MAKE_CONTROLLER_ID( 0xfff,	0x2a1 ), k_eControllerType_XBoxOneController },	// Unknown Controller
 
-																					
 	//{ MAKE_CONTROLLER_ID( 0x1949, 0x0402 ), /*android*/ },	// Unknown Controller
 
 	{ MAKE_CONTROLLER_ID( 0x05ac, 0x0001 ), k_eControllerType_AppleController },	// MFI Extended Gamepad (generic entry for iOS/tvOS)
@@ -464,11 +458,11 @@ static const ControllerDescription_t arrControllers[] = {
     // * Sunwaytek Wireless Motion Controller for Nintendo Switch
 	{ MAKE_CONTROLLER_ID( 0x057e, 0x2009 ), k_eControllerType_SwitchProController },        // Nintendo Switch Pro Controller
     
-    { MAKE_CONTROLLER_ID( 0x0f0d, 0x00c1 ), k_eControllerType_SwitchInputOnlyController },  // HORIPAD for Nintendo Switch
-    { MAKE_CONTROLLER_ID( 0x0f0d, 0x0092 ), k_eControllerType_SwitchInputOnlyController },  // HORI Pokken Tournament DX Pro Pad
-    { MAKE_CONTROLLER_ID( 0x0f0d, 0x00f6 ), k_eControllerType_SwitchProController },        // HORI Wireless Switch Pad
-	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00dc ), k_eControllerType_XInputSwitchController },     // HORI Battle Pad. Is a Switch controller but shows up through XInput on Windows.
-    { MAKE_CONTROLLER_ID( 0x0e6f, 0x0185 ), k_eControllerType_SwitchInputOnlyController },  // PDP Wired Fight Pad Pro for Nintendo Switch
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00c1 ), k_eControllerType_SwitchInputOnlyController },  // HORIPAD for Nintendo Switch
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x0092 ), k_eControllerType_SwitchInputOnlyController },  // HORI Pokken Tournament DX Pro Pad
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00f6 ), k_eControllerType_SwitchProController },		// HORI Wireless Switch Pad
+	{ MAKE_CONTROLLER_ID( 0x0f0d, 0x00dc ), k_eControllerType_XInputSwitchController },	 // HORI Battle Pad. Is a Switch controller but shows up through XInput on Windows.
+	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0185 ), k_eControllerType_SwitchInputOnlyController },  // PDP Wired Fight Pad Pro for Nintendo Switch
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0180 ), k_eControllerType_SwitchInputOnlyController },  // PDP Faceoff Wired Pro Controller for Nintendo Switch
 	{ MAKE_CONTROLLER_ID( 0x0e6f, 0x0181 ), k_eControllerType_SwitchInputOnlyController },  // PDP Faceoff Deluxe Wired Pro Controller for Nintendo Switch
 	{ MAKE_CONTROLLER_ID( 0x20d6, 0xa711 ), k_eControllerType_SwitchInputOnlyController },  // PowerA Wired Controller Plus/PowerA Wired Controller Nintendo GameCube Style
@@ -476,7 +470,7 @@ static const ControllerDescription_t arrControllers[] = {
 	{ MAKE_CONTROLLER_ID( 0x20d6, 0xa713 ), k_eControllerType_SwitchInputOnlyController },  // PowerA - Super Mario Controller
 
 	// Valve products - don't add to public list
-    { MAKE_CONTROLLER_ID( 0x0000, 0x11fb ), k_eControllerType_MobileTouch },		// Streaming mobile touch virtual controls
+	{ MAKE_CONTROLLER_ID( 0x0000, 0x11fb ), k_eControllerType_MobileTouch },	// Streaming mobile touch virtual controls
 	{ MAKE_CONTROLLER_ID( 0x28de, 0x1101 ), k_eControllerType_SteamController },	// Valve Legacy Steam Controller (CHELL)
 	{ MAKE_CONTROLLER_ID( 0x28de, 0x1102 ), k_eControllerType_SteamController },	// Valve wired Steam Controller (D0G)
 	{ MAKE_CONTROLLER_ID( 0x28de, 0x1105 ), k_eControllerType_SteamController },	// Valve Bluetooth Steam Controller (D0G)
@@ -488,6 +482,27 @@ static const ControllerDescription_t arrControllers[] = {
 
 static SDL_INLINE EControllerType GuessControllerType( int nVID, int nPID )
 {
+#if 0//def _DEBUG
+	// Verify that there are no duplicates in the controller list
+	// If the list were sorted, we could do this much more efficiently, as well as improve lookup speed.
+	static bool s_bCheckedForDuplicates;
+	if ( !s_bCheckedForDuplicates )
+	{
+		s_bCheckedForDuplicates = true;
+
+		for ( int i = 0; i < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++i )
+		{
+			for ( int j = i + 1; j < sizeof( arrControllers ) / sizeof( arrControllers[ 0 ] ); ++j )
+			{
+				if ( arrControllers[ i ].m_unDeviceID == arrControllers[ j ].m_unDeviceID )
+				{
+					Log( "Duplicate controller entry found for VID 0x%.4x PID 0x%.4x\n", ( arrControllers[ i ].m_unDeviceID >> 16 ), arrControllers[ i ].m_unDeviceID & 0xFFFF );
+				}
+			}
+		}
+	}
+#endif // _DEBUG
+
 	unsigned int unDeviceID = MAKE_CONTROLLER_ID( nVID, nPID );
 	int iIndex;
 	for ( iIndex = 0; iIndex < sizeof( arrControllers ) / sizeof( arrControllers[0] ); ++iIndex )

+ 1 - 1
sdl.mod/SDL/src/joystick/hidapi/SDL_hidapi_ps4.c

@@ -141,7 +141,7 @@ static Uint32 crc32(Uint32 crc, const void *data, int count)
 static SDL_bool
 HIDAPI_DriverPS4_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, const char *name)
 {
-    return SDL_IsJoystickPS4(vendor_id, product_id);
+    return (SDL_GetJoystickGameControllerType(vendor_id, product_id, name) == SDL_CONTROLLER_TYPE_PS4);
 }
 
 static const char *

+ 3 - 11
sdl.mod/SDL/src/joystick/hidapi/SDL_hidapi_switch.c

@@ -33,6 +33,7 @@
 #include "SDL_gamecontroller.h"
 #include "../SDL_sysjoystick.h"
 #include "SDL_hidapijoystick_c.h"
+#include "../../SDL_hints_c.h"
 
 
 #ifdef SDL_JOYSTICK_HIDAPI_SWITCH
@@ -225,16 +226,7 @@ typedef struct {
 static SDL_bool
 HIDAPI_DriverSwitch_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, const char *name)
 {
-    if (vendor_id == 0 && product_id == 0) {
-        /* Some devices are only identifiable by their name */
-        if (SDL_strcmp(name, "Lic Pro Controller") == 0 ||
-            SDL_strcmp(name, "Nintendo Wireless Gamepad") == 0 ||
-            SDL_strcmp(name, "Wireless Gamepad") == 0) {
-            /* HORI or PowerA Switch Pro Controller clone */
-            return SDL_TRUE;
-        }
-    }
-    return SDL_IsJoystickNintendoSwitchPro(vendor_id, product_id);
+    return (SDL_GetJoystickGameControllerType(vendor_id, product_id, name) == SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO);
 }
 
 static const char *
@@ -591,7 +583,7 @@ static Sint16 ApplyStickCalibration(SDL_DriverSwitch_Context *ctx, int nStick, i
 static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
 {
     SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)userdata;
-    ctx->m_bUseButtonLabels = (hint && *hint != '0' && SDL_strcasecmp(hint, "false") != 0);
+    ctx->m_bUseButtonLabels = SDL_GetStringBoolean(hint, SDL_TRUE);
 }
 
 static Uint8 RemapButton(SDL_DriverSwitch_Context *ctx, Uint8 button)

+ 8 - 2
sdl.mod/SDL/src/joystick/hidapi/SDL_hidapi_xbox360.c

@@ -249,6 +249,12 @@ HIDAPI_DriverXbox360_QuitWindowsGamingInput(SDL_DriverXbox360_Context *ctx)
 static SDL_bool
 HIDAPI_DriverXbox360_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, const char *name)
 {
+    SDL_GameControllerType type = SDL_GetJoystickGameControllerType(vendor_id, product_id, name);
+
+    if (vendor_id == 0x0955) {
+        /* This is the NVIDIA Shield controller which doesn't talk XBox controller protocol */
+        return SDL_FALSE;
+    }
 #if defined(__MACOSX__) || defined(__WIN32__)
     if (vendor_id == 0x045e && product_id == 0x028e && version == 1) {
         /* This is the Steam Virtual Gamepad, which isn't supported by this driver */
@@ -258,9 +264,9 @@ HIDAPI_DriverXbox360_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint
         /* This is the old Bluetooth Xbox One S firmware, which isn't supported by this driver */
         return SDL_FALSE;
     }
-    return SDL_IsJoystickXbox360(vendor_id, product_id) || SDL_IsJoystickXboxOne(vendor_id, product_id);
+    return (type == SDL_CONTROLLER_TYPE_XBOX360 || type == SDL_CONTROLLER_TYPE_XBOXONE);
 #else
-    return SDL_IsJoystickXbox360(vendor_id, product_id);
+    return (type == SDL_CONTROLLER_TYPE_XBOX360);
 #endif
 }
 

+ 143 - 29
sdl.mod/SDL/src/joystick/hidapi/SDL_hidapi_xboxone.c

@@ -36,6 +36,35 @@
 
 #define USB_PACKET_LENGTH   64
 
+/* The amount of time to wait after hotplug to send controller init sequence */
+#define CONTROLLER_INIT_DELAY_MS    100
+
+/* This is the full init sequence for the Xbox One Elite Series 2 controller.
+   Normally it isn't needed, but this switches the controller back to wired report mode after being in Bluetooth mode.
+*/
+static const Uint8 xboxone_elite_init0[] = {
+    0x04, 0x20, 0x01, 0x00
+};
+static const Uint8 xboxone_elite_init1[] = {
+    0x01, 0x20, 0x28, 0x09, 0x00, 0x04, 0x20, 0x3A,
+    0x00, 0x00, 0x00, 0x31, 0x01
+};
+static const Uint8 xboxone_elite_init2[] = {
+    0x01, 0x20, 0x28, 0x09, 0x00, 0x04, 0x20, 0x6B,
+    0x01, 0x00, 0x00, 0x00, 0x00
+};
+static const Uint8 xboxone_elite_init3[] = {
+    0x05, 0x20, 0x02, 0x0F, 0x06, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x55, 0x53, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00
+};
+static const Uint8 xboxone_elite_init4[] = {
+    0x05, 0x20, 0x03, 0x01, 0x00
+};
+static const Uint8 xboxone_elite_init5[] = {
+    0x0A, 0x20, 0x04, 0x03, 0x00, 0x01, 0x14
+};
+
 /*
  * This packet is required for all Xbox One pads with 2015
  * or later firmware installed (or present from the factory).
@@ -105,16 +134,19 @@ typedef struct {
     int size;
 } SDL_DriverXboxOne_InitPacket;
 
+
 static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
     { 0x0e6f, 0x0165, xboxone_hori_init, sizeof(xboxone_hori_init) },
     { 0x0f0d, 0x0067, xboxone_hori_init, sizeof(xboxone_hori_init) },
+    { 0x045e, 0x0b00, xboxone_elite_init0, sizeof(xboxone_elite_init0) },
+    { 0x045e, 0x0b00, xboxone_elite_init1, sizeof(xboxone_elite_init1) },
+    { 0x045e, 0x0b00, xboxone_elite_init2, sizeof(xboxone_elite_init2) },
+    { 0x045e, 0x0b00, xboxone_elite_init3, sizeof(xboxone_elite_init3) },
+    { 0x045e, 0x0b00, xboxone_elite_init4, sizeof(xboxone_elite_init4) },
+    { 0x045e, 0x0b00, xboxone_elite_init5, sizeof(xboxone_elite_init5) },
     { 0x0000, 0x0000, xboxone_fw2015_init, sizeof(xboxone_fw2015_init) },
-    { 0x0e6f, 0x0246, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) },
-    { 0x0e6f, 0x0246, xboxone_pdp_init2, sizeof(xboxone_pdp_init2) },
-    { 0x0e6f, 0x02ab, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) },
-    { 0x0e6f, 0x02ab, xboxone_pdp_init2, sizeof(xboxone_pdp_init2) },
-    { 0x0e6f, 0x02a4, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) },
-    { 0x0e6f, 0x02a4, xboxone_pdp_init2, sizeof(xboxone_pdp_init2) },
+    { 0x0e6f, 0x0000, xboxone_pdp_init1, sizeof(xboxone_pdp_init1) },
+    { 0x0e6f, 0x0000, xboxone_pdp_init2, sizeof(xboxone_pdp_init2) },
     { 0x24c6, 0x541a, xboxone_rumblebegin_init, sizeof(xboxone_rumblebegin_init) },
     { 0x24c6, 0x542a, xboxone_rumblebegin_init, sizeof(xboxone_rumblebegin_init) },
     { 0x24c6, 0x543a, xboxone_rumblebegin_init, sizeof(xboxone_rumblebegin_init) },
@@ -124,16 +156,92 @@ static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
 };
 
 typedef struct {
+    Uint16 vendor_id;
+    Uint16 product_id;
+    Uint32 start_time;
+    SDL_bool initialized;
     Uint8 sequence;
     Uint8 last_state[USB_PACKET_LENGTH];
     Uint32 rumble_expiration;
 } SDL_DriverXboxOne_Context;
 
 
+static SDL_bool
+IsBluetoothXboxOneController(Uint16 vendor_id, Uint16 product_id)
+{
+    /* Check to see if it's the Xbox One S or Xbox One Elite Series 2 in Bluetooth mode */
+    const Uint16 USB_VENDOR_MICROSOFT = 0x045e;
+    const Uint16 USB_PRODUCT_XBOX_ONE_S_REV1 = 0x02e0;
+    const Uint16 USB_PRODUCT_XBOX_ONE_S_REV2 = 0x02fd;
+    const Uint16 USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2 = 0x0b05;
+
+    if (vendor_id == USB_VENDOR_MICROSOFT) {
+        if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1 ||
+            product_id == USB_PRODUCT_XBOX_ONE_S_REV2 ||
+            product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2) {
+            return SDL_TRUE;
+        }
+    }
+    return SDL_FALSE;
+}
+
+static SDL_bool
+SendControllerInit(hid_device *dev, SDL_DriverXboxOne_Context *ctx)
+{
+    Uint16 vendor_id = ctx->vendor_id;
+    Uint16 product_id = ctx->product_id;
+
+    if (!IsBluetoothXboxOneController(vendor_id, product_id)) {
+        int i, j;
+        Uint8 init_packet[USB_PACKET_LENGTH];
+
+        for (i = 0; i < SDL_arraysize(xboxone_init_packets); ++i) {
+            const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[i];
+
+            if (packet->vendor_id && (vendor_id != packet->vendor_id)) {
+                continue;
+            }
+
+            if (packet->product_id && (product_id != packet->product_id)) {
+                continue;
+            }
+
+            SDL_memcpy(init_packet, packet->data, packet->size);
+            init_packet[2] = ctx->sequence++;
+            if (hid_write(dev, init_packet, packet->size) != packet->size) {
+                SDL_SetError("Couldn't write Xbox One initialization packet");
+                return SDL_FALSE;
+            }
+
+            /* After the init we need to sync up the rumble sequence */
+            if (packet->data == xboxone_fw2015_init) {
+                for (j = 0; j < 255; ++j) {
+                    if (hid_write(dev, xboxone_rumbleend_init, sizeof(xboxone_rumbleend_init)) != sizeof(xboxone_rumbleend_init)) {
+                        SDL_SetError("Couldn't write Xbox One initialization packet");
+                        return SDL_FALSE;
+                    }
+                }
+            }
+        }
+    }
+    return SDL_TRUE;
+}
+
+
 static SDL_bool
 HIDAPI_DriverXboxOne_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, const char *name)
 {
-    return SDL_IsJoystickXboxOne(vendor_id, product_id);
+#ifdef __LINUX__
+    if (IsBluetoothXboxOneController(vendor_id, product_id)) {
+        /* We can't do rumble on this device, hid_write() fails, so don't try to open it here */
+        return SDL_FALSE;
+    }
+    if (vendor_id == 0x24c6 && product_id == 0x541a) {
+        /* The PowerA Mini controller, model 1240245-01, blocks while writing feature reports */
+        return SDL_FALSE;
+    }
+#endif
+    return (SDL_GetJoystickGameControllerType(vendor_id, product_id, name) == SDL_CONTROLLER_TYPE_XBOXONE);
 }
 
 static const char *
@@ -146,8 +254,6 @@ static SDL_bool
 HIDAPI_DriverXboxOne_Init(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor_id, Uint16 product_id, void **context)
 {
     SDL_DriverXboxOne_Context *ctx;
-    int i;
-    Uint8 init_packet[USB_PACKET_LENGTH];
 
     ctx = (SDL_DriverXboxOne_Context *)SDL_calloc(1, sizeof(*ctx));
     if (!ctx) {
@@ -156,19 +262,9 @@ HIDAPI_DriverXboxOne_Init(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor
     }
     *context = ctx;
 
-    /* Send the controller init data */
-    for (i = 0; i < SDL_arraysize(xboxone_init_packets); ++i) {
-        const SDL_DriverXboxOne_InitPacket *packet = &xboxone_init_packets[i];
-        if (!packet->vendor_id || (vendor_id == packet->vendor_id && product_id == packet->product_id)) {
-            SDL_memcpy(init_packet, packet->data, packet->size);
-            init_packet[2] = ctx->sequence++;
-            if (hid_write(dev, init_packet, packet->size) != packet->size) {
-                SDL_SetError("Couldn't write Xbox One initialization packet");
-                SDL_free(ctx);
-                return SDL_FALSE;
-            }
-        }
-    }
+    ctx->vendor_id = vendor_id;
+    ctx->product_id = product_id;
+    ctx->start_time = SDL_GetTicks();
 
     /* Initialize the joystick capabilities */
     joystick->nbuttons = SDL_CONTROLLER_BUTTON_MAX;
@@ -184,15 +280,14 @@ HIDAPI_DriverXboxOne_Rumble(SDL_Joystick *joystick, hid_device *dev, void *conte
     SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)context;
     Uint8 rumble_packet[] = { 0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF };
 
-    /* The Rock Candy Xbox One Controller limits the range of
-         low frequency rumble strength in the range of [0 - 0x99]
-         high frequency rumble strength in the range of [0 - 0x82]
+    if (!ctx->initialized) {
+        return 0;
+    }
 
-       I think the valid range of rumble at the firmware level is [0 - 0x7F]
-    */
+    /* Magnitude is 1..100 so scale the 16-bit input here */
     rumble_packet[2] = ctx->sequence++;
-    rumble_packet[8] = (low_frequency_rumble >> 9);
-    rumble_packet[9] = (high_frequency_rumble >> 9);
+    rumble_packet[8] = low_frequency_rumble / 655;
+    rumble_packet[9] = high_frequency_rumble / 655;
 
     if (hid_write(dev, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
         return SDL_SetError("Couldn't send rumble packet");
@@ -273,7 +368,26 @@ HIDAPI_DriverXboxOne_Update(SDL_Joystick *joystick, hid_device *dev, void *conte
     Uint8 data[USB_PACKET_LENGTH];
     int size;
 
+    if (!ctx->initialized) {
+        if (SDL_TICKS_PASSED(SDL_GetTicks(), ctx->start_time + CONTROLLER_INIT_DELAY_MS)) {
+            if (!SendControllerInit(dev, ctx)) {
+                return SDL_FALSE;
+            }
+            ctx->initialized = SDL_TRUE;
+        }
+    }
+
     while ((size = hid_read_timeout(dev, data, sizeof(data), 0)) > 0) {
+#ifdef DEBUG_XBOX_PROTOCOL
+        SDL_Log("Xbox One packet: size = %d\n"
+                "                 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n"
+                "                 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n"
+                "                 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
+                    size,
+                    data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7],
+                    data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15],
+                    data[16], data[17], data[18], data[19]);
+#endif
         switch (data[0]) {
         case 0x20:
             HIDAPI_DriverXboxOne_HandleStatePacket(joystick, dev, ctx, data, size);

+ 22 - 2
sdl.mod/SDL/src/joystick/hidapi/SDL_hidapijoystick.c

@@ -31,6 +31,7 @@
 #include "SDL_joystick.h"
 #include "../SDL_sysjoystick.h"
 #include "SDL_hidapijoystick_c.h"
+#include "../../SDL_hints_c.h"
 
 #if defined(__WIN32__)
 #include "../../core/windows/SDL_windows.h"
@@ -409,11 +410,16 @@ HIDAPI_XboxControllerName(Uint16 vendor_id, Uint16 product_id)
         { MAKE_VIDPID(0x045e, 0x028e), "Microsoft X-Box 360 pad" },
         { MAKE_VIDPID(0x045e, 0x028f), "Microsoft X-Box 360 pad v2" },
         { MAKE_VIDPID(0x045e, 0x0291), "Xbox 360 Wireless Receiver (XBOX)" },
+        { MAKE_VIDPID(0x045e, 0x02a1), "Microsoft X-Box 360 pad" },
         { MAKE_VIDPID(0x045e, 0x02d1), "Microsoft X-Box One pad" },
         { MAKE_VIDPID(0x045e, 0x02dd), "Microsoft X-Box One pad (Firmware 2015)" },
+        { MAKE_VIDPID(0x045e, 0x02e0), "Microsoft X-Box One S pad" },
         { MAKE_VIDPID(0x045e, 0x02e3), "Microsoft X-Box One Elite pad" },
         { MAKE_VIDPID(0x045e, 0x02ea), "Microsoft X-Box One S pad" },
-        { MAKE_VIDPID(0x045e, 0x02ff), "Microsoft X-Box One pad" },
+        { MAKE_VIDPID(0x045e, 0x02fd), "Microsoft X-Box One S pad" },
+        { MAKE_VIDPID(0x045e, 0x02ff), "Microsoft X-Box One Elite pad" },
+        { MAKE_VIDPID(0x045e, 0x0b00), "Microsoft X-Box One Elite Series 2 pad" },
+        { MAKE_VIDPID(0x045e, 0x0b05), "Microsoft X-Box One Elite Series 2 pad" },
         { MAKE_VIDPID(0x045e, 0x0719), "Xbox 360 Wireless Receiver" },
         { MAKE_VIDPID(0x046d, 0xc21d), "Logitech Gamepad F310" },
         { MAKE_VIDPID(0x046d, 0xc21e), "Logitech Gamepad F510" },
@@ -460,6 +466,7 @@ HIDAPI_XboxControllerName(Uint16 vendor_id, Uint16 product_id)
         { MAKE_VIDPID(0x0e6f, 0x021f), "Rock Candy Gamepad for Xbox 360" },
         { MAKE_VIDPID(0x0e6f, 0x0246), "Rock Candy Gamepad for Xbox One 2015" },
         { MAKE_VIDPID(0x0e6f, 0x02a4), "PDP Wired Controller for Xbox One - Stealth Series" },
+        { MAKE_VIDPID(0x0e6f, 0x02a6), "PDP Wired Controller for Xbox One - Camo Series" },
         { MAKE_VIDPID(0x0e6f, 0x02ab), "PDP Controller for Xbox One" },
         { MAKE_VIDPID(0x0e6f, 0x0301), "Logic3 Controller" },
         { MAKE_VIDPID(0x0e6f, 0x0346), "Rock Candy Gamepad for Xbox One 2016" },
@@ -475,6 +482,11 @@ HIDAPI_XboxControllerName(Uint16 vendor_id, Uint16 product_id)
         { MAKE_VIDPID(0x0f0d, 0x0063), "Hori Real Arcade Pro Hayabusa (USA) Xbox One" },
         { MAKE_VIDPID(0x0f0d, 0x0067), "HORIPAD ONE" },
         { MAKE_VIDPID(0x0f0d, 0x0078), "Hori Real Arcade Pro V Kai Xbox One" },
+        { MAKE_VIDPID(0x0f0d, 0x0084), "HORI Fighting Commander" },
+        { MAKE_VIDPID(0x0f0d, 0x0085), "HORI Fighting Commander" },
+        { MAKE_VIDPID(0x0f0d, 0x0086), "HORI Fighting Commander" },
+        { MAKE_VIDPID(0x1038, 0x1430), "SteelSeries Stratus Duo" },
+        { MAKE_VIDPID(0x1038, 0x1431), "SteelSeries Stratus Duo" },
         { MAKE_VIDPID(0x11c9, 0x55f0), "Nacon GC-100XF" },
         { MAKE_VIDPID(0x12ab, 0x0004), "Honey Bee Xbox360 dancepad" },
         { MAKE_VIDPID(0x12ab, 0x0301), "PDP AFTERGLOW AX.1" },
@@ -544,13 +556,21 @@ HIDAPI_XboxControllerName(Uint16 vendor_id, Uint16 product_id)
         { MAKE_VIDPID(0x24c6, 0x5506), "Hori SOULCALIBUR V Stick" },
         { MAKE_VIDPID(0x24c6, 0x550d), "Hori GEM Xbox controller" },
         { MAKE_VIDPID(0x24c6, 0x550e), "Hori Real Arcade Pro V Kai 360" },
+        { MAKE_VIDPID(0x24c6, 0x5510), "Hori Fighting Commander ONE" },
         { MAKE_VIDPID(0x24c6, 0x551a), "PowerA FUSION Pro Controller" },
         { MAKE_VIDPID(0x24c6, 0x561a), "PowerA FUSION Controller" },
+        { MAKE_VIDPID(0x24c6, 0x591a), "PowerA FUSION Pro Controller" },
         { MAKE_VIDPID(0x24c6, 0x5b00), "ThrustMaster Ferrari 458 Racing Wheel" },
         { MAKE_VIDPID(0x24c6, 0x5b02), "Thrustmaster, Inc. GPX Controller" },
         { MAKE_VIDPID(0x24c6, 0x5b03), "Thrustmaster Ferrari 458 Racing Wheel" },
         { MAKE_VIDPID(0x24c6, 0x5d04), "Razer Sabertooth" },
+        { MAKE_VIDPID(0x24c6, 0x791a), "PowerA Fusion Fight Pad" },
+        { MAKE_VIDPID(0x24c6, 0xfafa), "Aplay Controller" },
+        { MAKE_VIDPID(0x24c6, 0xfafb), "Aplay Controller" },
+        { MAKE_VIDPID(0x24c6, 0xfafc), "Afterglow Gamepad 1" },
+        { MAKE_VIDPID(0x24c6, 0xfafd), "Afterglow Gamepad 3" },
         { MAKE_VIDPID(0x24c6, 0xfafe), "Rock Candy Gamepad for Xbox 360" },
+        { MAKE_VIDPID(0x2e24, 0x1688), "Hyperkin X91" },
     };
     int i;
     Uint32 vidpid = MAKE_VIDPID(vendor_id, product_id);
@@ -641,7 +661,7 @@ SDL_HIDAPIDriverHintChanged(void *userdata, const char *name, const char *oldVal
 {
     int i;
     SDL_HIDAPI_Device *device = SDL_HIDAPI_devices;
-    SDL_bool enabled = (!hint || !*hint || ((*hint != '0') && (SDL_strcasecmp(hint, "false") != 0)));
+    SDL_bool enabled = SDL_GetStringBoolean(hint, SDL_TRUE);
 
     if (SDL_strcmp(name, SDL_HINT_JOYSTICK_HIDAPI) == 0) {
         for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {

+ 18 - 16
sdl.mod/SDL/src/joystick/iphoneos/SDL_sysjoystick.m

@@ -129,6 +129,9 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
 
     if (controller.extendedGamepad) {
         GCExtendedGamepad *gamepad = controller.extendedGamepad;
+        BOOL is_xbox = [controller.vendorName containsString: @"Xbox"];
+        BOOL is_ps4 = [controller.vendorName containsString: @"DUALSHOCK"];
+        BOOL is_MFi = (!is_xbox && !is_ps4);
         int nbuttons = 0;
 
         /* These buttons are part of the original MFi spec */
@@ -155,20 +158,24 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
             device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_BACK);
             ++nbuttons;
         }
-        if ([gamepad respondsToSelector:@selector(buttonMenu)] && gamepad.buttonMenu) {
-            device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
-            ++nbuttons;
-        } else {
-            device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
-            ++nbuttons;
+        BOOL has_direct_menu = [gamepad respondsToSelector:@selector(buttonMenu)] && gamepad.buttonMenu;
+#if TARGET_OS_TV
+        /* On tvOS MFi controller menu button brings you to the home screen */
+        if (is_MFi) {
+            has_direct_menu = FALSE;
+        }
+#endif
+        device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
+        ++nbuttons;
+        if (!has_direct_menu) {
             device->uses_pause_handler = SDL_TRUE;
         }
 #pragma clang diagnostic pop
 
-        if ([controller.vendorName containsString: @"Xbox"]) {
+        if (is_xbox) {
             vendor = VENDOR_MICROSOFT;
             product = 0x02E0; /* Assume Xbox One S BLE Controller unless/until GCController flows VID/PID */
-        } else if ([controller.vendorName containsString: @"DUALSHOCK"]) {
+        } else if (is_ps4) {
             vendor = VENDOR_SONY;
             product = 0x09CC; /* Assume DS4 Slim unless/until GCController flows VID/PID */
         } else {
@@ -211,14 +218,9 @@ IOS_AddMFIJoystickDevice(SDL_JoystickDeviceItem *device, GCController *controlle
         device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_B); /* Button X on microGamepad */
         nbuttons += 2;
 
-        if ([gamepad respondsToSelector:@selector(buttonMenu)] && gamepad.buttonMenu) {
-            device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
-            ++nbuttons;
-        } else {
-            device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
-            ++nbuttons;
-            device->uses_pause_handler = SDL_TRUE;
-        }
+        device->button_mask |= (1 << SDL_CONTROLLER_BUTTON_START);
+        ++nbuttons;
+        device->uses_pause_handler = SDL_TRUE;
 
         vendor = VENDOR_APPLE;
         product = 3;

+ 25 - 13
sdl.mod/SDL/src/joystick/linux/SDL_sysjoystick.c

@@ -80,7 +80,8 @@ static SDL_joylist_item *SDL_joylist_tail = NULL;
 static int numjoysticks = 0;
 
 #if !SDL_USE_LIBUDEV
-static Uint32 last_joy_detect_time = 0;
+static Uint32 last_joy_detect_time;
+static time_t last_input_dir_mtime;
 #endif
 
 #define test_bit(nr, addr) \
@@ -421,21 +422,28 @@ LINUX_JoystickDetect(void)
     Uint32 now = SDL_GetTicks();
 
     if (!last_joy_detect_time || SDL_TICKS_PASSED(now, last_joy_detect_time + SDL_JOY_DETECT_INTERVAL_MS)) {
-        DIR *folder;
-        struct dirent *dent;
-
-        folder = opendir("/dev/input");
-        if (folder) {
-            while ((dent = readdir(folder))) {
-                int len = SDL_strlen(dent->d_name);
-                if (len > 5 && SDL_strncmp(dent->d_name, "event", 5) == 0) {
-                    char path[PATH_MAX];
-                    SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", dent->d_name);
-                    MaybeAddDevice(path);
+        struct stat sb;
+
+        /* Opening input devices can generate synchronous device I/O, so avoid it if we can */
+        if (stat("/dev/input", &sb) == 0 && sb.st_mtime != last_input_dir_mtime) {
+            DIR *folder;
+            struct dirent *dent;
+
+            folder = opendir("/dev/input");
+            if (folder) {
+                while ((dent = readdir(folder))) {
+                    int len = SDL_strlen(dent->d_name);
+                    if (len > 5 && SDL_strncmp(dent->d_name, "event", 5) == 0) {
+                        char path[PATH_MAX];
+                        SDL_snprintf(path, SDL_arraysize(path), "/dev/input/%s", dent->d_name);
+                        MaybeAddDevice(path);
+                    }
                 }
+
+                closedir(folder);
             }
 
-            closedir(folder);
+            last_input_dir_mtime = sb.st_mtime;
         }
 
         last_joy_detect_time = now;
@@ -483,6 +491,10 @@ LINUX_JoystickInit(void)
     /* Force a scan to build the initial device list */
     SDL_UDEV_Scan();
 #else
+    /* Force immediate joystick detection */
+    last_joy_detect_time = 0;
+    last_input_dir_mtime = 0;
+
     /* Report all devices currently present */
     LINUX_JoystickDetect();
 #endif

+ 146 - 29
sdl.mod/SDL/src/joystick/windows/SDL_dinputjoystick.c

@@ -235,42 +235,149 @@ SetDIerror(const char *function, HRESULT code)
     return SDL_SetError("%s() DirectX error 0x%8.8lx", function, code);
 }
 
+#if 0 /* Microsoft recommended implementation, but slower than checking raw devices */
+#define COBJMACROS
+#include <wbemidl.h>
+#include <oleauto.h>
+
+static const IID CLSID_WbemLocator = { 0x4590f811, 0x1d3a, 0x11d0,{ 0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } };
+static const IID IID_IWbemLocator = { 0xdc12a687, 0x737f, 0x11cf,{ 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24 } };
+
 static SDL_bool
-SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
+WIN_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
 {
-    static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
-    static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
-    static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
-    static GUID IID_XOneWiredGamepad = { MAKELONG(0x045E, 0x02FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
-    static GUID IID_XOneWirelessGamepad = { MAKELONG(0x045E, 0x02DD), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
-    static GUID IID_XOneNewWirelessGamepad = { MAKELONG(0x045E, 0x02D1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
-    static GUID IID_XOneSWirelessGamepad = { MAKELONG(0x045E, 0x02EA), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
-    static GUID IID_XOneSBluetoothGamepad = { MAKELONG(0x045E, 0x02E0), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
-    static GUID IID_XOneEliteWirelessGamepad = { MAKELONG(0x045E, 0x02E3), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } };
-
-    static const GUID *s_XInputProductGUID[] = {
-        &IID_ValveStreamingGamepad,
-        &IID_X360WiredGamepad,         /* Microsoft's wired X360 controller for Windows. */
-        &IID_X360WirelessGamepad,      /* Microsoft's wireless X360 controller for Windows. */
-        &IID_XOneWiredGamepad,         /* Microsoft's wired Xbox One controller for Windows. */
-        &IID_XOneWirelessGamepad,      /* Microsoft's wireless Xbox One controller for Windows. */
-        &IID_XOneNewWirelessGamepad,   /* Microsoft's updated wireless Xbox One controller (w/ 3.5 mm jack) for Windows. */
-        &IID_XOneSWirelessGamepad,     /* Microsoft's wireless Xbox One S controller for Windows. */
-        &IID_XOneSBluetoothGamepad,    /* Microsoft's Bluetooth Xbox One S controller for Windows. */
-        &IID_XOneEliteWirelessGamepad  /* Microsoft's wireless Xbox One Elite controller for Windows. */
-    };
+    IWbemLocator*           pIWbemLocator = NULL;
+    IEnumWbemClassObject*   pEnumDevices = NULL;
+    IWbemClassObject*       pDevices[20];
+    IWbemServices*          pIWbemServices = NULL;
+    BSTR                    bstrNamespace = NULL;
+    BSTR                    bstrDeviceID = NULL;
+    BSTR                    bstrClassName = NULL;
+    DWORD                   uReturned = 0;
+    SDL_bool                bIsXinputDevice = SDL_FALSE;
+    UINT                    iDevice = 0;
+    VARIANT                 var;
+    HRESULT                 hr;
+
+    SDL_zeroa(pDevices);
+
+    // Create WMI
+    hr = CoCreateInstance(&CLSID_WbemLocator,
+        NULL,
+        CLSCTX_INPROC_SERVER,
+        &IID_IWbemLocator,
+        (LPVOID*)&pIWbemLocator);
+    if (FAILED(hr) || pIWbemLocator == NULL)
+        goto LCleanup;
+
+    bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup;
+    bstrClassName = SysAllocString(L"Win32_PNPEntity");   if (bstrClassName == NULL) goto LCleanup;
+    bstrDeviceID = SysAllocString(L"DeviceID");          if (bstrDeviceID == NULL)  goto LCleanup;
+
+    // Connect to WMI 
+    hr = IWbemLocator_ConnectServer(pIWbemLocator, bstrNamespace, NULL, NULL, 0L,
+        0L, NULL, NULL, &pIWbemServices);
+    if (FAILED(hr) || pIWbemServices == NULL) {
+        goto LCleanup;
+    }
+
+    // Switch security level to IMPERSONATE. 
+    CoSetProxyBlanket((IUnknown *)pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
+        RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
+
+    hr = IWbemServices_CreateInstanceEnum(pIWbemServices, bstrClassName, 0, NULL, &pEnumDevices);
+    if (FAILED(hr) || pEnumDevices == NULL)
+        goto LCleanup;
+
+    // Loop over all devices
+    for (;;) {
+        // Get 20 at a time
+        hr = IEnumWbemClassObject_Next(pEnumDevices, 10000, SDL_arraysize(pDevices), pDevices, &uReturned);
+        if (FAILED(hr)) {
+            goto LCleanup;
+        }
+        if (uReturned == 0) {
+            break;
+        }
+
+        for (iDevice = 0; iDevice < uReturned; iDevice++) {
+            // For each device, get its device ID
+            hr = IWbemClassObject_Get(pDevices[iDevice], bstrDeviceID, 0L, &var, NULL, NULL);
+            if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) {
+                // Check if the device ID contains "IG_".  If it does, then it's an XInput device
+                // This information can not be found from DirectInput 
+                if (SDL_wcsstr(var.bstrVal, L"IG_")) {
+                    char *bstrVal = WIN_StringToUTF8(var.bstrVal);
+
+                    // If it does, then get the VID/PID from var.bstrVal
+                    DWORD dwPid = 0, dwVid = 0, dwVidPid;
+                    const char *strVid, *strPid;
+                    strVid = SDL_strstr(bstrVal, "VID_");
+                    if (strVid && SDL_sscanf(strVid, "VID_%4X", &dwVid) != 1)
+                        dwVid = 0;
+                    strPid = SDL_strstr(bstrVal, "PID_");
+                    if (strPid && SDL_sscanf(strPid, "PID_%4X", &dwPid) != 1)
+                        dwPid = 0;
+
+                    SDL_free(bstrVal);
+
+                    // Compare the VID/PID to the DInput device
+                    dwVidPid = MAKELONG(dwVid, dwPid);
+                    if (dwVidPid == pGuidProductFromDirectInput->Data1) {
+                        bIsXinputDevice = SDL_TRUE;
+                        goto LCleanup;
+                    }
+                }
+            }
+            IWbemClassObject_Release(pDevices[iDevice]);
+        }
+    }
+
+LCleanup:
+    if (bstrNamespace) {
+        SysFreeString(bstrNamespace);
+    }
+    if (bstrDeviceID) {
+        SysFreeString(bstrDeviceID);
+    }
+    if (bstrClassName) {
+        SysFreeString(bstrClassName);
+    }
+    for (iDevice = 0; iDevice < SDL_arraysize(pDevices); iDevice++) {
+        if (pDevices[iDevice]) {
+            IWbemClassObject_Release(pDevices[iDevice]);
+        }
+    }
+    if (pEnumDevices) {
+        IEnumWbemClassObject_Release(pEnumDevices);
+    }
+    if (pIWbemLocator) {
+        IWbemLocator_Release(pIWbemLocator);
+    }
+    if (pIWbemServices) {
+        IWbemServices_Release(pIWbemServices);
+    }
 
-    size_t iDevice;
+    return bIsXinputDevice;
+}
+#endif /* 0 */
+
+static SDL_bool
+SDL_IsXInputDevice(const GUID* pGuidProductFromDirectInput)
+{
     UINT i;
 
     if (!SDL_XINPUT_Enabled()) {
         return SDL_FALSE;
     }
 
-    /* Check for well known XInput device GUIDs */
-    /* 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. */
-    for (iDevice = 0; iDevice < SDL_arraysize(s_XInputProductGUID); ++iDevice) {
-        if (SDL_memcmp(pGuidProductFromDirectInput, s_XInputProductGUID[iDevice], sizeof(GUID)) == 0) {
+    if (SDL_memcmp(&pGuidProductFromDirectInput->Data4[2], "PIDVID", 6) == 0) {
+        Uint16 vendor_id = (Uint16)LOWORD(pGuidProductFromDirectInput->Data1);
+        Uint16 product_id = (Uint16)HIWORD(pGuidProductFromDirectInput->Data1);
+        SDL_GameControllerType type = SDL_GetJoystickGameControllerType(vendor_id, product_id, "");
+        if (type == SDL_CONTROLLER_TYPE_XBOX360 ||
+            type == SDL_CONTROLLER_TYPE_XBOXONE ||
+            (vendor_id == 0x28DE && product_id == 0x11FF)) {
             return SDL_TRUE;
         }
     }
@@ -504,8 +611,7 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
         return DIENUM_CONTINUE; /* better luck next time? */
     }
 
-    SDL_memcpy(&(pNewJoystick->dxdevice), pdidInstance,
-        sizeof(DIDEVICEINSTANCE));
+    SDL_memcpy(&pNewJoystick->dxdevice, pdidInstance, sizeof(DIDEVICEINSTANCE));
 
     SDL_memset(pNewJoystick->guid.data, 0, sizeof(pNewJoystick->guid.data));
 
@@ -529,7 +635,17 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
         SDL_strlcpy((char*)guid16, pNewJoystick->joystickname, sizeof(pNewJoystick->guid.data) - 4);
     }
 
+    if (SDL_strstr(pNewJoystick->joystickname, " XINPUT ") != NULL) {
+        /* This is a duplicate interface for a controller that will show up with XInput,
+           e.g. Xbox One Elite Series 2 in Bluetooth mode.
+         */
+        SDL_free(pNewJoystick->joystickname);
+        SDL_free(pNewJoystick);
+        return DIENUM_CONTINUE;
+    }
+
     if (SDL_ShouldIgnoreJoystick(pNewJoystick->joystickname, pNewJoystick->guid)) {
+        SDL_free(pNewJoystick->joystickname);
         SDL_free(pNewJoystick);
         return DIENUM_CONTINUE;
     }
@@ -537,6 +653,7 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext)
 #ifdef SDL_JOYSTICK_HIDAPI
     if (HIDAPI_IsDevicePresent(vendor, product, 0, pNewJoystick->joystickname)) {
         /* The HIDAPI driver is taking care of this device */
+        SDL_free(pNewJoystick->joystickname);
         SDL_free(pNewJoystick);
         return DIENUM_CONTINUE;
     }

+ 58 - 29
sdl.mod/SDL/src/joystick/windows/SDL_xinputjoystick.c

@@ -26,6 +26,7 @@
 
 #include "SDL_assert.h"
 #include "SDL_hints.h"
+#include "SDL_log.h"
 #include "SDL_timer.h"
 #include "SDL_windowsjoystick_c.h"
 #include "SDL_xinputjoystick_c.h"
@@ -138,6 +139,28 @@ GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
         return;  /* oh well. */
     }
 
+    /* First see if we have a cached entry for this index */
+    if (s_arrXInputDevicePath[userid]) {
+        for (i = 0; i < device_count; i++) {
+            RID_DEVICE_INFO rdi;
+            char devName[128];
+            UINT rdiSize = sizeof(rdi);
+            UINT nameSize = SDL_arraysize(devName);
+
+            rdi.cbSize = sizeof(rdi);
+            if (devices[i].dwType == RIM_TYPEHID &&
+                GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 &&
+                GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) {
+                if (SDL_strcmp(devName, s_arrXInputDevicePath[userid]) == 0) {
+                    *pVID = (Uint16)rdi.hid.dwVendorId;
+                    *pPID = (Uint16)rdi.hid.dwProductId;
+                    *pVersion = (Uint16)rdi.hid.dwVersionNumber;
+                    return;
+                }
+            }
+        }
+    }
+
     for (i = 0; i < device_count; i++) {
         RID_DEVICE_INFO rdi;
         char devName[128];
@@ -145,44 +168,50 @@ GuessXInputDevice(Uint8 userid, Uint16 *pVID, Uint16 *pPID, Uint16 *pVersion)
         UINT nameSize = SDL_arraysize(devName);
 
         rdi.cbSize = sizeof(rdi);
-        if ((devices[i].dwType == RIM_TYPEHID) &&
-            (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
-            (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
-            (SDL_strstr(devName, "IG_") != NULL)) {
-            SDL_bool found = SDL_FALSE;
-            for (j = 0; j < SDL_arraysize(s_arrXInputDevicePath); ++j) {
-                if (j == userid) {
-                    continue;
+        if (devices[i].dwType == RIM_TYPEHID &&
+            GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != (UINT)-1 &&
+            GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != (UINT)-1) {
+#ifdef DEBUG_JOYSTICK
+            SDL_Log("Raw input device: VID = 0x%x, PID = 0x%x, %s\n", rdi.hid.dwVendorId, rdi.hid.dwProductId, devName);
+#endif
+            if (SDL_strstr(devName, "IG_") != NULL) {
+                SDL_bool found = SDL_FALSE;
+                for (j = 0; j < SDL_arraysize(s_arrXInputDevicePath); ++j) {
+                    if (!s_arrXInputDevicePath[j]) {
+                        continue;
+                    }
+                    if (SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) {
+                        found = SDL_TRUE;
+                        break;
+                    }
                 }
-                if (!s_arrXInputDevicePath[j]) {
+                if (found) {
+                    /* We already have this device in our XInput device list */
                     continue;
                 }
-                if (SDL_strcmp(devName, s_arrXInputDevicePath[j]) == 0) {
-                    found = SDL_TRUE;
-                    break;
-                }
-            }
-            if (found) {
-                /* We already have this device in our XInput device list */
-                continue;
-            }
 
-            /* We don't actually know if this is the right device for this
-             * userid, but we'll record it so we'll at least be consistent
-             * when the raw device list changes.
-             */
-            *pVID = (Uint16)rdi.hid.dwVendorId;
-            *pPID = (Uint16)rdi.hid.dwProductId;
-            *pVersion = (Uint16)rdi.hid.dwVersionNumber;
-            if (s_arrXInputDevicePath[userid]) {
-                SDL_free(s_arrXInputDevicePath[userid]);
+                /* We don't actually know if this is the right device for this
+                 * userid, but we'll record it so we'll at least be consistent
+                 * when the raw device list changes.
+                 */
+                *pVID = (Uint16)rdi.hid.dwVendorId;
+                *pPID = (Uint16)rdi.hid.dwProductId;
+                *pVersion = (Uint16)rdi.hid.dwVersionNumber;
+                if (s_arrXInputDevicePath[userid]) {
+                    SDL_free(s_arrXInputDevicePath[userid]);
+                }
+                s_arrXInputDevicePath[userid] = SDL_strdup(devName);
+                return;
             }
-            s_arrXInputDevicePath[userid] = SDL_strdup(devName);
-            break;
         }
     }
     SDL_free(devices);
 #endif  /* ifndef __WINRT__ */
+
+    /* The device wasn't in the raw HID device list, it's probably Bluetooth */
+    *pVID = 0x045e; /* Microsoft */
+    *pPID = 0x02fd; /* XBox One S Bluetooth */
+    *pVersion = 0;
 }
 
 static void

+ 18 - 2
sdl.mod/SDL/src/main/haiku/SDL_BApp.h

@@ -228,7 +228,23 @@ private:
             return;
         }
         win = GetSDLWindow(winID);
-        SDL_SendMouseMotion(win, 0, 0, x, y);
+
+		// Simple relative mode support for mouse.
+		if (SDL_GetMouse()->relative_mode) {
+			int winWidth, winHeight, winPosX, winPosY;
+			SDL_GetWindowSize(win, &winWidth, &winHeight);
+			SDL_GetWindowPosition(win, &winPosX, &winPosY);
+			int dx = x - (winWidth / 2);
+			int dy = y - (winHeight / 2);
+			SDL_SendMouseMotion(win, 0, SDL_GetMouse()->relative_mode, dx, dy);
+			set_mouse_position((winPosX + winWidth / 2), (winPosY + winHeight / 2));
+			if (!be_app->IsCursorHidden())
+				be_app->HideCursor();
+		} else {
+			SDL_SendMouseMotion(win, 0, 0, x, y);
+			if (SDL_ShowCursor(-1) && be_app->IsCursorHidden())
+				be_app->ShowCursor();
+		}
 
         /* Tell the application that the mouse passed over, redraw needed */
         HAIKU_UpdateWindowFramebuffer(NULL,win,NULL,-1);
@@ -261,7 +277,7 @@ private:
             return;
         }
         win = GetSDLWindow(winID);
-        SDL_SendMouseWheel(win, 0, xTicks, yTicks, SDL_MOUSEWHEEL_NORMAL);
+        SDL_SendMouseWheel(win, 0, xTicks, -yTicks, SDL_MOUSEWHEEL_NORMAL);
     }
 
     void _HandleKey(BMessage *msg) {

+ 3 - 2
sdl.mod/SDL/src/main/haiku/SDL_BeApp.cc

@@ -48,13 +48,14 @@ extern "C" {
 static int SDL_BeAppActive = 0;
 static SDL_Thread *SDL_AppThread = NULL;
 
+/* Default application signature */
+const char *signature = "application/x-SDL-executable";
+
 static int
 StartBeApp(void *unused)
 {
     BApplication *App;
 
-    // default application signature
-    const char *signature = "application/x-SDL-executable";
     // dig resources for correct signature
     image_info info;
     int32 cookie = 0;

+ 3 - 0
sdl.mod/SDL/src/main/haiku/SDL_BeApp.h

@@ -31,6 +31,9 @@ extern int SDL_InitBeApp(void);
 /* Quit the Be Application, if there's nothing left to do */
 extern void SDL_QuitBeApp(void);
 
+/* Be Application Signature*/
+extern const char *signature;
+
 /* vi: set ts=4 sw=4 expandtab: */
 
 #ifdef __cplusplus

+ 27 - 21
sdl.mod/SDL/src/render/direct3d11/SDL_render_d3d11.c

@@ -1728,82 +1728,88 @@ D3D11_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture *
     float minx, miny, maxx, maxy;
     float minu, maxu, minv, maxv;
 
+    if (!verts) {
+        return -1;
+    }
+
+    cmd->data.draw.count = 1;
+
+    minx = -center->x;
+    maxx = dstrect->w - center->x;
+    miny = -center->y;
+    maxy = dstrect->h - center->y;
+
     if (flip & SDL_FLIP_HORIZONTAL) {
-        minu = (float) srcrect->x / texture->w;
-        maxu = (float) (srcrect->x + srcrect->w) / texture->w;
-    } else {
         minu = (float) (srcrect->x + srcrect->w) / texture->w;
         maxu = (float) srcrect->x / texture->w;
+    } else {
+        minu = (float) srcrect->x / texture->w;
+        maxu = (float) (srcrect->x + srcrect->w) / texture->w;
     }
 
     if (flip & SDL_FLIP_VERTICAL) {
-        minv = (float) srcrect->y / texture->h;
-        maxv = (float) (srcrect->y + srcrect->h) / texture->h;
-    } else {
         minv = (float) (srcrect->y + srcrect->h) / texture->h;
         maxv = (float) srcrect->y / texture->h;
+    } else {
+        minv = (float) srcrect->y / texture->h;
+        maxv = (float) (srcrect->y + srcrect->h) / texture->h;
     }
 
-    minx = -center->x;
-    maxx = dstrect->w - center->x;
-    miny = -center->y;
-    maxy = dstrect->h - center->y;
 
-    cmd->data.draw.count = 1;
 
     verts->pos.x = minx;
     verts->pos.y = miny;
     verts->pos.z = 0.0f;
-    verts->tex.x = minu;
-    verts->tex.y = minv;
     verts->color.x = r;
     verts->color.y = g;
     verts->color.z = b;
     verts->color.w = a;
+    verts->tex.x = minu;
+    verts->tex.y = minv;
     verts++;
 
     verts->pos.x = minx;
     verts->pos.y = maxy;
     verts->pos.z = 0.0f;
-    verts->tex.x = minu;
-    verts->tex.y = maxv;
     verts->color.x = r;
     verts->color.y = g;
     verts->color.z = b;
     verts->color.w = a;
+    verts->tex.x = minu;
+    verts->tex.y = maxv;
     verts++;
 
     verts->pos.x = maxx;
     verts->pos.y = miny;
     verts->pos.z = 0.0f;
-    verts->tex.x = maxu;
-    verts->tex.y = minv;
     verts->color.x = r;
     verts->color.y = g;
     verts->color.z = b;
     verts->color.w = a;
+    verts->tex.x = maxu;
+    verts->tex.y = minv;
     verts++;
 
     verts->pos.x = maxx;
     verts->pos.y = maxy;
     verts->pos.z = 0.0f;
-    verts->tex.x = maxu;
-    verts->tex.y = maxv;
     verts->color.x = r;
     verts->color.y = g;
     verts->color.z = b;
     verts->color.w = a;
+    verts->tex.x = maxu;
+    verts->tex.y = maxv;
     verts++;
 
     verts->pos.x = dstrect->x + center->x;  /* X translation */
     verts->pos.y = dstrect->y + center->y;  /* Y translation */
     verts->pos.z = (float)(M_PI * (float) angle / 180.0f);  /* rotation */
-    verts->tex.x = 0.0f;
-    verts->tex.y = 0.0f;
     verts->color.x = 0;
     verts->color.y = 0;
     verts->color.z = 0;
     verts->color.w = 0;
+    verts->tex.x = 0.0f;
+    verts->tex.y = 0.0f;
     verts++;
 
     return 0;

+ 44 - 11
sdl.mod/SDL/src/stdlib/SDL_string.c

@@ -421,17 +421,6 @@ SDL_strlen(const char *string)
 #endif /* HAVE_STRLEN */
 }
 
-wchar_t *
-SDL_wcsdup(const wchar_t *string)
-{
-    size_t len = ((SDL_wcslen(string) + 1) * sizeof(wchar_t));
-    wchar_t *newstr = (wchar_t *)SDL_malloc(len);
-    if (newstr) {
-        SDL_memcpy(newstr, string, len);
-    }
-    return newstr;
-}
-
 size_t
 SDL_wcslen(const wchar_t * string)
 {
@@ -477,6 +466,34 @@ SDL_wcslcat(SDL_INOUT_Z_CAP(maxlen) wchar_t *dst, const wchar_t *src, size_t max
 #endif /* HAVE_WCSLCAT */
 }
 
+wchar_t *
+SDL_wcsdup(const wchar_t *string)
+{
+    size_t len = ((SDL_wcslen(string) + 1) * sizeof(wchar_t));
+    wchar_t *newstr = (wchar_t *)SDL_malloc(len);
+    if (newstr) {
+        SDL_memcpy(newstr, string, len);
+    }
+    return newstr;
+}
+
+wchar_t *
+SDL_wcsstr(const wchar_t *haystack, const wchar_t *needle)
+{
+#if defined(HAVE_WCSSTR)
+    return SDL_const_cast(wchar_t*,wcsstr(haystack, needle));
+#else
+    size_t length = SDL_wcslen(needle);
+    while (*haystack) {
+        if (SDL_wcsncmp(haystack, needle, length) == 0) {
+            return (wchar_t *)haystack;
+        }
+        ++haystack;
+    }
+    return NULL;
+#endif /* HAVE_WCSSTR */
+}
+
 int
 SDL_wcscmp(const wchar_t *str1, const wchar_t *str2)
 {
@@ -493,6 +510,22 @@ SDL_wcscmp(const wchar_t *str1, const wchar_t *str2)
 #endif /* HAVE_WCSCMP */
 }
 
+int
+SDL_wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t maxlen)
+{
+#if defined(HAVE_WCSNCMP)
+    return wcsncmp(str1, str2, maxlen);
+#else
+    while (*str1 && *str2) {
+        if (*str1 != *str2)
+            break;
+        ++str1;
+        ++str2;
+    }
+    return (int)(*str1 - *str2);
+#endif /* HAVE_WCSNCMP */
+}
+
 size_t
 SDL_strlcpy(SDL_OUT_Z_CAP(maxlen) char *dst, const char *src, size_t maxlen)
 {

+ 103 - 0
sdl.mod/SDL/src/stdlib/SDL_strtokr.c

@@ -0,0 +1,103 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2019 Sam Lantinga <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+#if defined(__clang_analyzer__)
+#define SDL_DISABLE_ANALYZE_MACROS 1
+#endif
+
+#include "../SDL_internal.h"
+
+#include "SDL_stdinc.h"
+
+char *SDL_strtokr(char *s1, const char *s2, char **ptr)
+{
+#if defined(HAVE_STRTOK_R)
+    return strtok_r(s1, s2, ptr);
+
+#elif defined(_MSC_VER) && defined(HAVE_STRTOK_S)
+    return strtok_s(s1, s2, ptr);
+
+#else /* SDL implementation */
+/*
+ * Adapted from _PDCLIB_strtok() of PDClib library at
+ * https://github.com/DevSolar/pdclib.git
+ *
+ * The code was under CC0 license:
+ * https://creativecommons.org/publicdomain/zero/1.0/legalcode :
+ *
+ *                        No Copyright
+ *
+ * The person who associated a work with this deed has dedicated the
+ * work to the public domain by waiving all of his or her rights to
+ * the work worldwide under copyright law, including all related and
+ * neighboring rights, to the extent allowed by law.
+ *
+ * You can copy, modify, distribute and perform the work, even for
+ * commercial purposes, all without asking permission. See Other
+ * Information below.
+ */
+    const char *p = s2;
+
+    if (!s2 || !ptr || (!s1 && !*ptr)) return NULL;
+
+    if (s1 != NULL) {  /* new string */
+        *ptr = s1;
+    } else { /* old string continued */
+        if (*ptr == NULL) {
+        /* No old string, no new string, nothing to do */
+            return NULL;
+        }
+        s1 = *ptr;
+    }
+
+    /* skip leading s2 characters */
+    while (*p && *s1) {
+        if (*s1 == *p) {
+        /* found separator; skip and start over */
+            ++s1;
+            p = s2;
+            continue;
+        }
+        ++p;
+    }
+
+    if (! *s1) { /* no more to parse */
+        *ptr = s1;
+        return NULL;
+    }
+
+    /* skipping non-s2 characters */
+    *ptr = s1;
+    while (**ptr) {
+        p = s2;
+        while (*p) {
+            if (**ptr == *p++) {
+            /* found separator; overwrite with '\0', position *ptr, return */
+                *((*ptr)++) = '\0';
+                return s1;
+            }
+        }
+        ++(*ptr);
+    }
+
+    /* parsed to end of string */
+    return s1;
+#endif
+}

+ 3 - 0
sdl.mod/SDL/src/test/SDL_test_common.c

@@ -577,6 +577,9 @@ SDLTest_PrintPixelFormat(char *text, size_t maxlen, Uint32 format)
     case SDL_PIXELFORMAT_RGB444:
         SDL_snprintfcat(text, maxlen, "RGB444");
         break;
+    case SDL_PIXELFORMAT_BGR444:
+        SDL_snprintfcat(text, maxlen, "BGR444");
+        break;
     case SDL_PIXELFORMAT_RGB555:
         SDL_snprintfcat(text, maxlen, "RGB555");
         break;

+ 7 - 0
sdl.mod/SDL/src/video/SDL_pixels.c

@@ -94,6 +94,7 @@ SDL_GetPixelFormatName(Uint32 format)
     CASE(SDL_PIXELFORMAT_INDEX8)
     CASE(SDL_PIXELFORMAT_RGB332)
     CASE(SDL_PIXELFORMAT_RGB444)
+    CASE(SDL_PIXELFORMAT_BGR444)
     CASE(SDL_PIXELFORMAT_RGB555)
     CASE(SDL_PIXELFORMAT_BGR555)
     CASE(SDL_PIXELFORMAT_ARGB4444)
@@ -321,6 +322,12 @@ SDL_MasksToPixelFormatEnum(int bpp, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask,
             Amask == 0x0000) {
             return SDL_PIXELFORMAT_RGB444;
         }
+        if (Rmask == 0x000F &&
+            Gmask == 0x00F0 &&
+            Bmask == 0x0F00 &&
+            Amask == 0x0000) {
+            return SDL_PIXELFORMAT_BGR444;
+        }
         break;
     case 15:
         if (Rmask == 0) {

+ 1 - 0
sdl.mod/SDL/src/video/SDL_sysvideo.h

@@ -439,6 +439,7 @@ extern int SDL_GetIndexOfDisplay(SDL_VideoDisplay *display);
 extern SDL_VideoDisplay *SDL_GetDisplay(int displayIndex);
 extern SDL_VideoDisplay *SDL_GetDisplayForWindow(SDL_Window *window);
 extern void *SDL_GetDisplayDriverData( int displayIndex );
+extern SDL_bool SDL_IsVideoContextExternal(void);
 
 extern void SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor);
 

+ 18 - 2
sdl.mod/SDL/src/video/SDL_video.c

@@ -664,6 +664,12 @@ SDL_GetDisplayDriverData(int displayIndex)
     return _this->displays[displayIndex].driverdata;
 }
 
+SDL_bool
+SDL_IsVideoContextExternal(void)
+{
+    return SDL_GetHintBoolean(SDL_HINT_VIDEO_EXTERNAL_CONTEXT, SDL_FALSE);
+}
+
 const char *
 SDL_GetDisplayName(int displayIndex)
 {
@@ -1437,7 +1443,7 @@ SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags)
 
     /* Some platforms have OpenGL enabled by default */
 #if (SDL_VIDEO_OPENGL && __MACOSX__) || __IPHONEOS__ || __ANDROID__ || __NACL__
-    if (!_this->is_dummy && !(flags & SDL_WINDOW_VULKAN)) {
+    if (!_this->is_dummy && !(flags & SDL_WINDOW_VULKAN) && !SDL_IsVideoContextExternal()) {
         flags |= SDL_WINDOW_OPENGL;
     }
 #endif
@@ -3846,9 +3852,12 @@ SDL_IsScreenKeyboardShown(SDL_Window *window)
 #if SDL_VIDEO_DRIVER_X11
 #include "x11/SDL_x11messagebox.h"
 #endif
+#if SDL_VIDEO_DRIVER_HAIKU
+#include "haiku/SDL_bmessagebox.h"
+#endif
 
 
-#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11
+#if SDL_VIDEO_DRIVER_WINDOWS || SDL_VIDEO_DRIVER_WINRT || SDL_VIDEO_DRIVER_COCOA || SDL_VIDEO_DRIVER_UIKIT || SDL_VIDEO_DRIVER_X11 || SDL_VIDEO_DRIVER_HAIKU
 static SDL_bool SDL_MessageboxValidForDriver(const SDL_MessageBoxData *messageboxdata, SDL_SYSWM_TYPE drivertype)
 {
     SDL_SysWMinfo info;
@@ -3940,6 +3949,13 @@ SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
         X11_ShowMessageBox(messageboxdata, buttonid) == 0) {
         retval = 0;
     }
+#endif
+#if SDL_VIDEO_DRIVER_HAIKU
+    if (retval == -1 &&
+        SDL_MessageboxValidForDriver(messageboxdata, SDL_SYSWM_HAIKU) &&
+        HAIKU_ShowMessageBox(messageboxdata, buttonid) == 0) {
+        retval = 0;
+    }
 #endif
     if (retval == -1) {
         SDL_SetError("No message system available");

+ 15 - 8
sdl.mod/SDL/src/video/android/SDL_androidevents.c

@@ -26,6 +26,7 @@
 #include "SDL_events.h"
 #include "SDL_androidkeyboard.h"
 #include "SDL_androidwindow.h"
+#include "../SDL_sysvideo.h"
 
 /* Can't include sysaudio "../../audio/android/SDL_androidaudio.h"
  * because of THIS redefinition */
@@ -95,11 +96,14 @@ Android_PumpEvents_Blocking(_THIS)
     SDL_VideoData *videodata = (SDL_VideoData *)_this->driverdata;
 
     if (videodata->isPaused) {
+        SDL_bool isContextExternal = SDL_IsVideoContextExternal();
 
         /* Make sure this is the last thing we do before pausing */
-        SDL_LockMutex(Android_ActivityMutex);
-        android_egl_context_backup(Android_Window);
-        SDL_UnlockMutex(Android_ActivityMutex);
+        if (!isContextExternal) {
+            SDL_LockMutex(Android_ActivityMutex);
+            android_egl_context_backup(Android_Window);
+            SDL_UnlockMutex(Android_ActivityMutex);
+        }
 
         ANDROIDAUDIO_PauseDevices();
         openslES_PauseDevices();
@@ -112,7 +116,7 @@ Android_PumpEvents_Blocking(_THIS)
             openslES_ResumeDevices();
 
             /* Restore the GL Context from here, as this operation is thread dependent */
-            if (!SDL_HasEvent(SDL_QUIT)) {
+            if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) {
                 SDL_LockMutex(Android_ActivityMutex);
                 android_egl_context_restore(Android_Window);
                 SDL_UnlockMutex(Android_ActivityMutex);
@@ -146,11 +150,14 @@ Android_PumpEvents_NonBlocking(_THIS)
 
     if (videodata->isPaused) {
 
+        SDL_bool isContextExternal = SDL_IsVideoContextExternal();
         if (backup_context) {
 
-            SDL_LockMutex(Android_ActivityMutex);
-            android_egl_context_backup(Android_Window);
-            SDL_UnlockMutex(Android_ActivityMutex);
+            if (!isContextExternal) {
+                SDL_LockMutex(Android_ActivityMutex);
+                android_egl_context_backup(Android_Window);
+                SDL_UnlockMutex(Android_ActivityMutex);
+            }
 
             ANDROIDAUDIO_PauseDevices();
             openslES_PauseDevices();
@@ -167,7 +174,7 @@ Android_PumpEvents_NonBlocking(_THIS)
             openslES_ResumeDevices();
 
             /* Restore the GL Context from here, as this operation is thread dependent */
-            if (!SDL_HasEvent(SDL_QUIT)) {
+            if (!isContextExternal && !SDL_HasEvent(SDL_QUIT)) {
                 SDL_LockMutex(Android_ActivityMutex);
                 android_egl_context_restore(Android_Window);
                 SDL_UnlockMutex(Android_ActivityMutex);

+ 1 - 1
sdl.mod/SDL/src/video/android/SDL_androidwindow.c

@@ -82,7 +82,7 @@ Android_CreateWindow(_THIS, SDL_Window * window)
 
     /* Do not create EGLSurface for Vulkan window since it will then make the window
        incompatible with vkCreateAndroidSurfaceKHR */
-    if ((window->flags & SDL_WINDOW_VULKAN) == 0) {
+    if ((window->flags & SDL_WINDOW_OPENGL) != 0) {
         data->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) data->native_window);
 
         if (data->egl_surface == EGL_NO_SURFACE) {

+ 30 - 2
sdl.mod/SDL/src/video/cocoa/SDL_cocoaevents.m

@@ -267,6 +267,25 @@ GetApplicationName(void)
     return appName;
 }
 
+static bool
+LoadMainMenuNibIfAvailable(void)
+{
+    NSDictionary *infoDict;
+    NSString *mainNibFileName;
+    bool success = false;
+    
+    infoDict = [[NSBundle mainBundle] infoDictionary];
+    if (infoDict) {
+        mainNibFileName = [infoDict valueForKey:@"NSMainNibFile"];
+        
+        if (mainNibFileName) {
+            success = [[NSBundle mainBundle] loadNibNamed:mainNibFileName owner:[NSApplication sharedApplication] topLevelObjects:nil];
+        }
+    }
+    
+    return success;
+}
+
 static void
 CreateApplicationMenus(void)
 {
@@ -281,7 +300,7 @@ CreateApplicationMenus(void)
     if (NSApp == nil) {
         return;
     }
-
+    
     mainMenu = [[NSMenu alloc] init];
 
     /* Create the main menu bar */
@@ -385,8 +404,17 @@ Cocoa_RegisterApp(void)
             [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
         }
 
+        /* If there aren't already menus in place, look to see if there's
+         * a nib we should use. If not, then manually create the basic
+         * menus we meed.
+         */
         if ([NSApp mainMenu] == nil) {
-            CreateApplicationMenus();
+            bool nibLoaded;
+            
+            nibLoaded = LoadMainMenuNibIfAvailable();
+            if (!nibLoaded) {
+                CreateApplicationMenus();
+            }
         }
         [NSApp finishLaunching];
         if ([NSApp delegate]) {

+ 21 - 7
sdl.mod/SDL/src/video/cocoa/SDL_cocoamodes.m

@@ -443,27 +443,41 @@ Cocoa_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect)
 
 int
 Cocoa_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi)
+{ @autoreleasepool
 {
     const float MM_IN_INCH = 25.4f;
 
     SDL_DisplayData *data = (SDL_DisplayData *) display->driverdata;
 
-    CGSize displaySize = CGDisplayScreenSize(data->display);
-    int pixelWidth =  (int) CGDisplayPixelsWide(data->display);
-    int pixelHeight = (int) CGDisplayPixelsHigh(data->display);
+    /* we need the backingScaleFactor for Retina displays, which is only exposed through NSScreen, not CGDisplay, afaik, so find our screen... */
+    CGFloat scaleFactor = 1.0f;
+    NSArray *screens = [NSScreen screens];
+    for (NSScreen *screen in screens) {
+        const CGDirectDisplayID dpyid = (const CGDirectDisplayID ) [[[screen deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
+        if (dpyid == data->display) {
+            if ([screen respondsToSelector:@selector(backingScaleFactor)]) {  // Mac OS X 10.7 and later
+                scaleFactor = [screen backingScaleFactor];
+                break;
+            }
+        }
+    }
+
+    const CGSize displaySize = CGDisplayScreenSize(data->display);
+    const int pixelWidth =  (int) CGDisplayPixelsWide(data->display);
+    const int pixelHeight = (int) CGDisplayPixelsHigh(data->display);
 
     if (ddpi) {
-        *ddpi = SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH);
+        *ddpi = (SDL_ComputeDiagonalDPI(pixelWidth, pixelHeight, displaySize.width / MM_IN_INCH, displaySize.height / MM_IN_INCH)) * scaleFactor;
     }
     if (hdpi) {
-        *hdpi = pixelWidth * MM_IN_INCH / displaySize.width;
+        *hdpi = (pixelWidth * MM_IN_INCH / displaySize.width) * scaleFactor;
     }
     if (vdpi) {
-        *vdpi = pixelHeight * MM_IN_INCH / displaySize.height;
+        *vdpi = (pixelHeight * MM_IN_INCH / displaySize.height) * scaleFactor;
     }
 
     return 0;
-}
+}}
 
 void
 Cocoa_GetDisplayModes(_THIS, SDL_VideoDisplay * display)

+ 19 - 27
sdl.mod/SDL/src/video/haiku/SDL_BWin.h

@@ -86,6 +86,7 @@ class SDL_BWin:public BDirectWindow
         _buffer_locker = new BLocker();
         _bitmap = NULL;
         _clips = NULL;
+        _num_clips = 0;
 
 #ifdef DRAWTHREAD
         _draw_thread_id = spawn_thread(HAIKU_DrawThread, "drawing_thread",
@@ -139,6 +140,7 @@ class SDL_BWin:public BDirectWindow
             _gl_type = gl_flags;
         }
         AddChild(_SDL_GLView);
+        _SDL_GLView->SetEventMask(B_POINTER_EVENTS | B_KEYBOARD_EVENTS, B_NO_POINTER_HISTORY);
         _SDL_GLView->EnableDirectMode(true);
         _SDL_GLView->LockGL();  /* "New" GLViews are created */
         Unlock();
@@ -179,13 +181,17 @@ class SDL_BWin:public BDirectWindow
             _connected = true;
 
         case B_DIRECT_MODIFY:
-            if(_clips) {
-                free(_clips);
-                _clips = NULL;
+            if (info->clip_list_count > _num_clips)
+            {
+                if(_clips) {
+                    free(_clips);
+                    _clips = NULL;
+                }
             }
 
             _num_clips = info->clip_list_count;
-            _clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect));
+            if (_clips == NULL)
+                _clips = (clipping_rect *)malloc(_num_clips*sizeof(clipping_rect));
             if(_clips) {
                 memcpy(_clips, info->clip_list,
                     _num_clips*sizeof(clipping_rect));
@@ -314,22 +320,17 @@ class SDL_BWin:public BDirectWindow
                 && msg->FindInt32("be:transit", &transit) == B_OK) {
                 _MouseMotionEvent(where, transit);
             }
+            break;
 
-            /* FIXME: Apparently a button press/release event might be dropped
-               if made before before a different button is released.  Does
-               B_MOUSE_MOVED have the data needed to check if a mouse button
-               state has changed? */
+        case B_MOUSE_DOWN:
             if (msg->FindInt32("buttons", &buttons) == B_OK) {
-                _MouseButtonEvent(buttons);
+                _MouseButtonEvent(buttons, SDL_PRESSED);
             }
             break;
 
-        case B_MOUSE_DOWN:
         case B_MOUSE_UP:
-            /* _MouseButtonEvent() detects any and all buttons that may have
-               changed state, as well as that button's new state */
             if (msg->FindInt32("buttons", &buttons) == B_OK) {
-                _MouseButtonEvent(buttons);
+                _MouseButtonEvent(buttons, SDL_RELEASED);
             }
             break;
 
@@ -492,26 +493,17 @@ private:
  if true:  SDL_SetCursor(NULL); */
     }
 
-    void _MouseButtonEvent(int32 buttons) {
+    void _MouseButtonEvent(int32 buttons, Uint8 state) {
         int32 buttonStateChange = buttons ^ _last_buttons;
 
-        /* Make sure at least one button has changed state */
-        if( !(buttonStateChange) ) {
-            return;
-        }
-
-        /* Add any mouse button events */
         if(buttonStateChange & B_PRIMARY_MOUSE_BUTTON) {
-            _SendMouseButton(SDL_BUTTON_LEFT, buttons &
-                B_PRIMARY_MOUSE_BUTTON);
+            _SendMouseButton(SDL_BUTTON_LEFT, state);
         }
         if(buttonStateChange & B_SECONDARY_MOUSE_BUTTON) {
-            _SendMouseButton(SDL_BUTTON_RIGHT, buttons &
-                B_PRIMARY_MOUSE_BUTTON);
+            _SendMouseButton(SDL_BUTTON_RIGHT, state);
         }
         if(buttonStateChange & B_TERTIARY_MOUSE_BUTTON) {
-            _SendMouseButton(SDL_BUTTON_MIDDLE, buttons &
-                B_PRIMARY_MOUSE_BUTTON);
+            _SendMouseButton(SDL_BUTTON_MIDDLE, state);
         }
 
         _last_buttons = buttons;
@@ -652,7 +644,7 @@ private:
     clipping_rect   _bounds;
     BLocker        *_buffer_locker;
     clipping_rect  *_clips;
-    int32           _num_clips;
+    uint32          _num_clips;
     int32           _bytes_per_px;
     thread_id       _draw_thread_id;
 

+ 425 - 0
sdl.mod/SDL/src/video/haiku/SDL_bmessagebox.cc

@@ -0,0 +1,425 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2019 Sam Lantinga <[email protected]>
+  Copyright (C) 2018-2019 EXL <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU
+
+#include "SDL_messagebox.h"
+
+/* For application signature. */
+#include "../../main/haiku/SDL_BeApp.h"
+
+#include <Alert.h>
+#include <Application.h>
+#include <Button.h>
+#include <Font.h>
+#include <Layout.h>
+#include <String.h>
+#include <TextView.h>
+#include <View.h>
+#include <Window.h>
+
+#include <InterfaceDefs.h>
+#include <SupportDefs.h>
+#include <GraphicsDefs.h>
+
+#include <new>
+#include <vector>
+#include <algorithm>
+
+enum
+{
+	G_CLOSE_BUTTON_ID   = -1,
+	G_DEFAULT_BUTTON_ID = 0,
+	G_MAX_STRING_LENGTH_BYTES = 120
+};
+
+class HAIKU_SDL_MessageBox : public BAlert
+{
+	float fComputedMessageBoxWidth;
+
+	BTextView *fMessageBoxTextView;
+
+	int fCloseButton;
+	int fDefaultButton;
+
+	bool fCustomColorScheme;
+	bool fThereIsLongLine;
+	rgb_color fTextColor;
+
+	const char *fTitle;
+	const char *HAIKU_SDL_DefTitle;
+	const char *HAIKU_SDL_DefMessage;
+	const char *HAIKU_SDL_DefButton;
+
+	std::vector<const SDL_MessageBoxButtonData *> fButtons;
+
+	static bool
+	SortButtonsPredicate(const SDL_MessageBoxButtonData *aButtonLeft,
+	                                 const SDL_MessageBoxButtonData *aButtonRight)
+	{
+		return aButtonLeft->buttonid < aButtonRight->buttonid;
+	}
+
+	alert_type
+	ConvertMessageBoxType(const SDL_MessageBoxFlags aWindowType) const
+	{
+		switch (aWindowType)
+		{
+			default:
+			case SDL_MESSAGEBOX_WARNING:
+			{
+				return B_WARNING_ALERT;
+			}
+			case SDL_MESSAGEBOX_ERROR:
+			{
+				return B_STOP_ALERT;
+			}
+			case SDL_MESSAGEBOX_INFORMATION:
+			{
+				return B_INFO_ALERT;
+			}
+		}
+	}
+
+	rgb_color
+	ConvertColorType(const SDL_MessageBoxColor *aColor) const
+	{
+		rgb_color color = { aColor->r, aColor->g, aColor->b, color.alpha = 255 };
+		return color;
+	}
+
+	int32
+	GetLeftPanelWidth(void) const
+	{
+		// See file "haiku/src/kits/interface/Alert.cpp" for this magic numbers.
+		//    IconStripeWidth = 30 * Scale
+		//    IconSize = 32 * Scale
+		//    Scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16)
+		//    RealWidth = (IconStripeWidth * Scale) + (IconSize * Scale)
+
+		int32 scale = max_c(1, ((int32)be_plain_font->Size() + 15) / 16);
+		return (30 * scale) + (32 * scale);
+	}
+
+	void
+	UpdateTextViewWidth(void)
+	{
+		fComputedMessageBoxWidth = fMessageBoxTextView->PreferredSize().Width() + GetLeftPanelWidth();
+	}
+
+	void
+	ParseSdlMessageBoxData(const SDL_MessageBoxData *aMessageBoxData)
+	{
+		if (aMessageBoxData == NULL)
+		{
+			SetTitle(HAIKU_SDL_DefTitle);
+			SetMessageText(HAIKU_SDL_DefMessage);
+			AddButton(HAIKU_SDL_DefButton);
+			return;
+		}
+
+		if (aMessageBoxData->numbuttons <= 0)
+		{
+			AddButton(HAIKU_SDL_DefButton);
+		}
+		else
+		{
+			AddSdlButtons(aMessageBoxData->buttons, aMessageBoxData->numbuttons);
+		}
+
+		if (aMessageBoxData->colorScheme != NULL)
+		{
+			fCustomColorScheme = true;
+			ApplyAndParseColorScheme(aMessageBoxData->colorScheme);
+		}
+
+		(aMessageBoxData->title != NULL) ?
+			SetTitle(aMessageBoxData->title) : SetTitle(HAIKU_SDL_DefTitle);
+		(aMessageBoxData->message != NULL) ?
+			SetMessageText(aMessageBoxData->message) : SetMessageText(HAIKU_SDL_DefMessage);
+
+		SetType(ConvertMessageBoxType(static_cast<SDL_MessageBoxFlags>(aMessageBoxData->flags)));
+	}
+
+	void
+	ApplyAndParseColorScheme(const SDL_MessageBoxColorScheme *aColorScheme)
+	{
+		SetBackgroundColor(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BACKGROUND]);
+		fTextColor = ConvertColorType(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT]);
+		SetButtonColors(&aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BORDER],
+		                &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND],
+		                &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_TEXT],
+		                &aColorScheme->colors[SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED]);
+	}
+
+	void
+	SetButtonColors(const SDL_MessageBoxColor *aBorderColor,
+	                const SDL_MessageBoxColor *aBackgroundColor,
+	                const SDL_MessageBoxColor *aTextColor,
+	                const SDL_MessageBoxColor *aSelectedColor)
+	{
+		if (fCustomColorScheme)
+		{
+			int32 countButtons = CountButtons();
+			for (int i = 0; i < countButtons; ++i)
+			{
+				ButtonAt(i)->SetViewColor(ConvertColorType(aBorderColor));
+				ButtonAt(i)->SetLowColor(ConvertColorType(aBackgroundColor));
+
+				// This doesn't work. See this why:
+				// https://github.com/haiku/haiku/commit/de9c53f8f5008c7b3b0af75d944a628e17f6dffe
+				// Let it remain.
+				ButtonAt(i)->SetHighColor(ConvertColorType(aTextColor));
+			}
+		}
+		// TODO: Not Implemented.
+		// Is it even necessary?!
+		(void)aSelectedColor;
+	}
+
+	void
+	SetBackgroundColor(const SDL_MessageBoxColor *aColor)
+	{
+		rgb_color background = ConvertColorType(aColor);
+
+		GetLayout()->View()->SetViewColor(background);
+		// See file "haiku/src/kits/interface/Alert.cpp", the "TAlertView" is the internal name of the left panel.
+		FindView("TAlertView")->SetViewColor(background);
+		fMessageBoxTextView->SetViewColor(background);
+	}
+
+	bool
+	CheckLongLines(const char *aMessage)
+	{
+		int final = 0;
+
+		// This UTF-8 friendly.
+		BString message = aMessage;
+		int32 length = message.CountChars();
+
+		for (int i = 0, c = 0; i < length; ++i)
+		{
+			c++;
+			if (*(message.CharAt(i)) == '\n')
+			{
+				c = 0;
+			}
+			if (c > final)
+			{
+				final = c;
+			}
+		}
+
+		return (final > G_MAX_STRING_LENGTH_BYTES);
+	}
+
+	void
+	SetMessageText(const char *aMessage)
+	{
+		fThereIsLongLine = CheckLongLines(aMessage);
+		if (fThereIsLongLine)
+		{
+			fMessageBoxTextView->SetWordWrap(true);
+		}
+
+		rgb_color textColor = ui_color(B_PANEL_TEXT_COLOR);
+		if (fCustomColorScheme)
+		{
+			textColor = fTextColor;
+		}
+
+		/*
+		if (fNoTitledWindow)
+		{
+			fMessageBoxTextView->SetFontAndColor(be_bold_font);
+			fMessageBoxTextView->Insert(fTitle);
+			fMessageBoxTextView->Insert("\n\n");
+			fMessageBoxTextView->SetFontAndColor(be_plain_font);
+		}
+		*/
+
+		fMessageBoxTextView->SetFontAndColor(be_plain_font, B_FONT_ALL, &textColor);
+		fMessageBoxTextView->Insert(aMessage);
+
+		// Be sure to call update width method.
+		UpdateTextViewWidth();
+	}
+
+	void
+	AddSdlButtons(const SDL_MessageBoxButtonData *aButtons, int aNumButtons)
+	{
+		for (int i = 0; i < aNumButtons; ++i)
+		{
+			fButtons.push_back(&aButtons[i]);
+		}
+
+		std::sort(fButtons.begin(), fButtons.end(), &HAIKU_SDL_MessageBox::SortButtonsPredicate);
+
+		size_t countButtons = fButtons.size();
+		for (size_t i = 0; i < countButtons; ++i)
+		{
+			switch (fButtons[i]->flags)
+			{
+				case SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT:
+				{
+					fCloseButton = static_cast<int>(i);
+					break;
+				}
+				case SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT:
+				{
+					fDefaultButton = static_cast<int>(i);
+					break;
+				}
+				default:
+				{
+					break;
+				}
+			}
+			AddButton(fButtons[i]->text);
+		}
+
+		SetDefaultButton(ButtonAt(fDefaultButton));
+	}
+
+public:
+	explicit
+	HAIKU_SDL_MessageBox(const SDL_MessageBoxData *aMessageBoxData)
+		: BAlert(NULL, NULL, NULL, NULL, NULL, B_WIDTH_FROM_LABEL, B_WARNING_ALERT),
+		  fComputedMessageBoxWidth(0.0f),
+		  fCloseButton(G_CLOSE_BUTTON_ID), fDefaultButton(G_DEFAULT_BUTTON_ID),
+		  fCustomColorScheme(false), fThereIsLongLine(false),
+		  HAIKU_SDL_DefTitle("SDL2 MessageBox"),
+		  HAIKU_SDL_DefMessage("Some information has been lost."),
+		  HAIKU_SDL_DefButton("OK")
+	{
+		// MessageBox settings.
+		// We need a title to display it.
+		SetLook(B_TITLED_WINDOW_LOOK);
+		SetFlags(Flags() | B_CLOSE_ON_ESCAPE);
+
+		// MessageBox TextView settings.
+		fMessageBoxTextView = TextView();
+		fMessageBoxTextView->SetWordWrap(false);
+		fMessageBoxTextView->SetStylable(true);
+
+		ParseSdlMessageBoxData(aMessageBoxData);
+	}
+
+	int
+	GetCloseButtonId(void) const
+	{
+		return fCloseButton;
+	}
+
+	virtual
+	~HAIKU_SDL_MessageBox(void)
+	{
+		fButtons.clear();
+	}
+
+protected:
+	virtual void
+	FrameResized(float aNewWidth, float aNewHeight)
+	{
+		if (fComputedMessageBoxWidth > aNewWidth)
+		{
+			ResizeTo(fComputedMessageBoxWidth, aNewHeight);
+		}
+		else
+		{
+			BAlert::FrameResized(aNewWidth, aNewHeight);
+		}
+	}
+
+	virtual void
+	SetTitle(const char* aTitle)
+	{
+		fTitle = aTitle;
+		BAlert::SetTitle(aTitle);
+	}
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int
+HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid)
+{
+	// Initialize button by closed or error value first.
+	*buttonid = G_CLOSE_BUTTON_ID;
+
+	// We need to check "be_app" pointer to "NULL". The "messageboxdata->window" pointer isn't appropriate here
+	// because it is possible to create a MessageBox from another thread. This fixes the following errors:
+	// "You need a valid BApplication object before interacting with the app_server."
+	// "2 BApplication objects were created. Only one is allowed."
+	BApplication *application = NULL;
+	if (be_app == NULL)
+	{
+		application = new(std::nothrow) BApplication(signature);
+		if (application == NULL)
+		{
+			return SDL_SetError("Cannot create the BApplication object. Lack of memory?");
+		}
+	}
+
+	HAIKU_SDL_MessageBox *SDL_MessageBox = new(std::nothrow) HAIKU_SDL_MessageBox(messageboxdata);
+	if (SDL_MessageBox == NULL)
+	{
+		return SDL_SetError("Cannot create the HAIKU_SDL_MessageBox (BAlert inheritor) object. Lack of memory?");
+	}
+	const int closeButton = SDL_MessageBox->GetCloseButtonId();
+	int pushedButton = SDL_MessageBox->Go();
+
+	// The close button is equivalent to pressing Escape.
+	if (closeButton != G_CLOSE_BUTTON_ID && pushedButton == G_CLOSE_BUTTON_ID)
+	{
+		pushedButton = closeButton;
+	}
+
+	// It's deleted by itself after the "Go()" method was executed.
+	/*
+	if (messageBox != NULL)
+	{
+		delete messageBox;
+	}
+	*/
+	if (application != NULL)
+	{
+		delete application;
+	}
+
+	// Initialize button by real pushed value then.
+	*buttonid = pushedButton;
+
+	return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU */
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 45 - 0
sdl.mod/SDL/src/video/haiku/SDL_bmessagebox.h

@@ -0,0 +1,45 @@
+/*
+  Simple DirectMedia Layer
+  Copyright (C) 1997-2019 Sam Lantinga <[email protected]>
+  Copyright (C) 2018-2019 EXL <[email protected]>
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+*/
+
+#ifndef SDL_BMESSAGEBOX_H
+#define SDL_BMESSAGEBOX_H
+
+#include "../../SDL_internal.h"
+
+#if SDL_VIDEO_DRIVER_HAIKU
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int
+HAIKU_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDL_VIDEO_DRIVER_HAIKU */
+
+#endif
+
+/* vi: set ts=4 sw=4 expandtab: */

+ 2 - 2
sdl.mod/SDL/src/video/haiku/SDL_bopengl.cc

@@ -54,7 +54,7 @@ int HAIKU_GL_LoadLibrary(_THIS, const char *path)
         if( get_image_symbol(info.id, "glBegin", B_SYMBOL_TYPE_ANY,
                 &location) == B_OK) {
 
-            _this->gl_config.dll_handle = (void *) (size_t) info.id;
+            _this->gl_config.dll_handle = (void *) (addr_t) info.id;
             _this->gl_config.driver_loaded = 1;
             SDL_strlcpy(_this->gl_config.driver_path, "libGL.so",
                     SDL_arraysize(_this->gl_config.driver_path));
@@ -69,7 +69,7 @@ void *HAIKU_GL_GetProcAddress(_THIS, const char *proc)
         void *location = NULL;
         status_t err;
         if ((err =
-            get_image_symbol((image_id) (size_t) _this->gl_config.dll_handle,
+            get_image_symbol((image_id) (addr_t) _this->gl_config.dll_handle,
                               proc, B_SYMBOL_TYPE_ANY,
                               &location)) == B_OK) {
             return location;

+ 30 - 0
sdl.mod/SDL/src/video/haiku/SDL_bvideo.cc

@@ -19,6 +19,7 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 #include "../../SDL_internal.h"
+#include "../../main/haiku/SDL_BApp.h"
 
 #if SDL_VIDEO_DRIVER_HAIKU
 
@@ -132,6 +133,33 @@ void HAIKU_DeleteDevice(SDL_VideoDevice * device)
     SDL_free(device);
 }
 
+static int HAIKU_ShowCursor(SDL_Cursor *cur)
+{
+	SDL_Mouse *mouse = SDL_GetMouse();
+	int show;
+	if (!mouse)
+		return 0;
+	show = (cur || !mouse->focus);
+	if (show) {
+		if (be_app->IsCursorHidden())
+			be_app->ShowCursor();
+	} else {
+		if (!be_app->IsCursorHidden())
+			be_app->HideCursor();
+	}
+	return 0;
+}
+
+static void HAIKU_MouseInit(_THIS)
+{
+	SDL_Mouse *mouse = SDL_GetMouse();
+	if (!mouse)
+		return;
+	mouse->ShowCursor = HAIKU_ShowCursor;
+	mouse->cur_cursor = (SDL_Cursor*)0x1;
+	mouse->def_cursor = (SDL_Cursor*)0x2;
+}
+
 int HAIKU_VideoInit(_THIS)
 {
     /* Initialize the Be Application for appserver interaction */
@@ -145,6 +173,8 @@ int HAIKU_VideoInit(_THIS)
     /* Init the keymap */
     HAIKU_InitOSKeymap();
 
+    HAIKU_MouseInit(_this);
+
 #if SDL_VIDEO_OPENGL
         /* testgl application doesn't load library, just tries to load symbols */
         /* is it correct? if so we have to load library here */

+ 11 - 1
sdl.mod/SDL/src/video/haiku/SDL_bwindow.cc

@@ -26,6 +26,8 @@
 #include "SDL_BWin.h"
 #include <new>
 
+#include "SDL_syswm.h"
+
 /* Define a path to window's BWIN data */
 #ifdef __cplusplus
 extern "C" {
@@ -217,7 +219,15 @@ void HAIKU_DestroyWindow(_THIS, SDL_Window * window) {
 SDL_bool HAIKU_GetWindowWMInfo(_THIS, SDL_Window * window,
                                     struct SDL_SysWMinfo *info) {
     /* FIXME: What is the point of this? What information should be included? */
-    return SDL_FALSE;
+	if (info->version.major == SDL_MAJOR_VERSION &&
+	    info->version.minor == SDL_MINOR_VERSION) {
+	    info->subsystem = SDL_SYSWM_HAIKU;
+	    return SDL_TRUE;
+	} else {
+	    SDL_SetError("Application not compiled with SDL %d.%d",
+	                 SDL_MAJOR_VERSION, SDL_MINOR_VERSION);
+	    return SDL_FALSE;
+	}
 }
 
 

+ 2 - 0
sdl.mod/SDL/src/video/uikit/SDL_uikitevents.m

@@ -65,7 +65,9 @@ UIKit_PumpEvents(_THIS)
     } while(result == kCFRunLoopRunHandledSource);
 
     /* See the comment in the function definition. */
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     UIKit_GL_RestoreCurrentContext();
+#endif
 }
 
 #endif /* SDL_VIDEO_DRIVER_UIKIT */

+ 4 - 0
sdl.mod/SDL/src/video/uikit/SDL_uikitmodes.h

@@ -27,7 +27,10 @@
 
 @interface SDL_DisplayData : NSObject
 
+- (instancetype)init;
+
 @property (nonatomic, strong) UIScreen *uiscreen;
+@property (nonatomic) float screenDPI;
 
 @end
 
@@ -41,6 +44,7 @@ extern SDL_bool UIKit_IsDisplayLandscape(UIScreen *uiscreen);
 
 extern int UIKit_InitModes(_THIS);
 extern void UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display);
+extern int UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi);
 extern int UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
 extern void UIKit_QuitModes(_THIS);
 extern int UIKit_GetDisplayUsableBounds(_THIS, SDL_VideoDisplay * display, SDL_Rect * rect);

+ 163 - 3
sdl.mod/SDL/src/video/uikit/SDL_uikitmodes.m

@@ -27,9 +27,150 @@
 
 #include "../../events/SDL_events_c.h"
 
+#import <sys/utsname.h>
+
 @implementation SDL_DisplayData
 
+- (instancetype)initWithScreen:(UIScreen*)screen
+{
+    if (self = [super init]) {
+        self.uiscreen = screen;
+
+        /*
+         * A well up to date list of device info can be found here:
+         * https://github.com/lmirosevic/GBDeviceInfo/blob/master/GBDeviceInfo/GBDeviceInfo_iOS.m
+         */
+        NSDictionary* devices = @{
+            @"iPhone1,1": @163,
+            @"iPhone1,2": @163,
+            @"iPhone2,1": @163,
+            @"iPhone3,1": @326,
+            @"iPhone3,2": @326,
+            @"iPhone3,3": @326,
+            @"iPhone4,1": @326,
+            @"iPhone5,1": @326,
+            @"iPhone5,2": @326,
+            @"iPhone5,3": @326,
+            @"iPhone5,4": @326,
+            @"iPhone6,1": @326,
+            @"iPhone6,2": @326,
+            @"iPhone7,1": @401,
+            @"iPhone7,2": @326,
+            @"iPhone8,1": @326,
+            @"iPhone8,2": @401,
+            @"iPhone8,4": @326,
+            @"iPhone9,1": @326,
+            @"iPhone9,2": @401,
+            @"iPhone9,3": @326,
+            @"iPhone9,4": @401,
+            @"iPhone10,1": @326,
+            @"iPhone10,2": @401,
+            @"iPhone10,3": @458,
+            @"iPhone10,4": @326,
+            @"iPhone10,5": @401,
+            @"iPhone10,6": @458,
+            @"iPhone11,2": @458,
+            @"iPhone11,4": @458,
+            @"iPhone11,6": @458,
+            @"iPhone11,8": @326,
+            @"iPhone12,1": @326,
+            @"iPhone12,3": @458,
+            @"iPhone12,5": @458,
+            @"iPad1,1": @132,
+            @"iPad2,1": @132,
+            @"iPad2,2": @132,
+            @"iPad2,3": @132,
+            @"iPad2,4": @132,
+            @"iPad2,5": @163,
+            @"iPad2,6": @163,
+            @"iPad2,7": @163,
+            @"iPad3,1": @264,
+            @"iPad3,2": @264,
+            @"iPad3,3": @264,
+            @"iPad3,4": @264,
+            @"iPad3,5": @264,
+            @"iPad3,6": @264,
+            @"iPad4,1": @264,
+            @"iPad4,2": @264,
+            @"iPad4,3": @264,
+            @"iPad4,4": @326,
+            @"iPad4,5": @326,
+            @"iPad4,6": @326,
+            @"iPad4,7": @326,
+            @"iPad4,8": @326,
+            @"iPad4,9": @326,
+            @"iPad5,1": @326,
+            @"iPad5,2": @326,
+            @"iPad5,3": @264,
+            @"iPad5,4": @264,
+            @"iPad6,3": @264,
+            @"iPad6,4": @264,
+            @"iPad6,7": @264,
+            @"iPad6,8": @264,
+            @"iPad6,11": @264,
+            @"iPad6,12": @264,
+            @"iPad7,1": @264,
+            @"iPad7,2": @264,
+            @"iPad7,3": @264,
+            @"iPad7,4": @264,
+            @"iPad7,5": @264,
+            @"iPad7,6": @264,
+            @"iPad7,11": @264,
+            @"iPad7,12": @264,
+            @"iPad8,1": @264,
+            @"iPad8,2": @264,
+            @"iPad8,3": @264,
+            @"iPad8,4": @264,
+            @"iPad8,5": @264,
+            @"iPad8,6": @264,
+            @"iPad8,7": @264,
+            @"iPad8,8": @264,
+            @"iPad11,1": @326,
+            @"iPad11,2": @326,
+            @"iPad11,3": @326,
+            @"iPad11,4": @326,
+            @"iPod1,1": @163,
+            @"iPod2,1": @163,
+            @"iPod3,1": @163,
+            @"iPod4,1": @326,
+            @"iPod5,1": @326,
+            @"iPod7,1": @326,
+            @"iPod9,1": @326,
+        };
+
+        struct utsname systemInfo;
+        uname(&systemInfo);
+        NSString* deviceName =
+            [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
+        id foundDPI = devices[deviceName];
+        if (foundDPI) {
+            self.screenDPI = (float)[foundDPI integerValue];
+        } else {
+            /*
+             * Estimate the DPI based on the screen scale multiplied by the base DPI for the device
+             * type (e.g. based on iPhone 1 and iPad 1)
+             */
+    #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000
+            float scale = (float)screen.nativeScale;
+    #else
+            float scale = (float)screen.scale;
+    #endif
+            float defaultDPI;
+            if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
+                defaultDPI = 132.0f;
+            } else if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
+                defaultDPI = 163.0f;
+            } else {
+                defaultDPI = 160.0f;
+            }
+            self.screenDPI = scale * defaultDPI;
+        }
+    }
+    return self;
+}
+
 @synthesize uiscreen;
+@synthesize screenDPI;
 
 @end
 
@@ -153,14 +294,12 @@ UIKit_AddDisplay(UIScreen *uiscreen)
     display.current_mode = mode;
 
     /* Allocate the display data */
-    SDL_DisplayData *data = [[SDL_DisplayData alloc] init];
+    SDL_DisplayData *data = [[SDL_DisplayData alloc] initWithScreen:uiscreen];
     if (!data) {
         UIKit_FreeDisplayModeData(&display.desktop_mode);
         return SDL_OutOfMemory();
     }
 
-    data.uiscreen = uiscreen;
-
     display.driverdata = (void *) CFBridgingRetain(data);
     SDL_AddVideoDisplay(&display);
 
@@ -243,6 +382,27 @@ UIKit_GetDisplayModes(_THIS, SDL_VideoDisplay * display)
     }
 }
 
+int
+UIKit_GetDisplayDPI(_THIS, SDL_VideoDisplay * display, float * ddpi, float * hdpi, float * vdpi)
+{
+    @autoreleasepool {
+        SDL_DisplayData *data = (__bridge SDL_DisplayData *) display->driverdata;
+        float dpi = data.screenDPI;
+
+        if (ddpi) {
+            *ddpi = dpi * (float)SDL_sqrt(2.0);
+        }
+        if (hdpi) {
+            *hdpi = dpi;
+        }
+        if (vdpi) {
+            *vdpi = dpi;
+        }
+    }
+
+    return 0;
+}
+
 int
 UIKit_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
 {

+ 4 - 0
sdl.mod/SDL/src/video/uikit/SDL_uikitopengles.h

@@ -21,6 +21,8 @@
 #ifndef SDL_uikitopengles_
 #define SDL_uikitopengles_
 
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+
 #include "../SDL_sysvideo.h"
 
 extern int UIKit_GL_MakeCurrent(_THIS, SDL_Window * window,
@@ -35,6 +37,8 @@ extern int UIKit_GL_LoadLibrary(_THIS, const char *path);
 
 extern void UIKit_GL_RestoreCurrentContext(void);
 
+#endif // SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+
 #endif /* SDL_uikitopengles_ */
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 1 - 1
sdl.mod/SDL/src/video/uikit/SDL_uikitopengles.m

@@ -20,7 +20,7 @@
 */
 #include "../../SDL_internal.h"
 
-#if SDL_VIDEO_DRIVER_UIKIT
+#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2)
 
 #include "SDL_uikitopengles.h"
 #import "SDL_uikitopenglview.h"

+ 4 - 0
sdl.mod/SDL/src/video/uikit/SDL_uikitopenglview.h

@@ -19,6 +19,8 @@
   3. This notice may not be removed or altered from any source distribution.
 */
 
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+
 #import <UIKit/UIKit.h>
 #import <OpenGLES/EAGL.h>
 #import <OpenGLES/ES3/gl.h>
@@ -57,4 +59,6 @@
 
 @end
 
+#endif // SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
+
 /* vi: set ts=4 sw=4 expandtab: */

+ 1 - 1
sdl.mod/SDL/src/video/uikit/SDL_uikitopenglview.m

@@ -20,7 +20,7 @@
 */
 #include "../../SDL_internal.h"
 
-#if SDL_VIDEO_DRIVER_UIKIT
+#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2)
 
 #include <OpenGLES/EAGLDrawable.h>
 #include <OpenGLES/ES2/glext.h>

+ 2 - 0
sdl.mod/SDL/src/video/uikit/SDL_uikitvideo.m

@@ -116,6 +116,7 @@ UIKit_CreateDevice(int devindex)
         device->HasClipboardText = UIKit_HasClipboardText;
 
         /* OpenGL (ES) functions */
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
         device->GL_MakeCurrent      = UIKit_GL_MakeCurrent;
         device->GL_GetDrawableSize  = UIKit_GL_GetDrawableSize;
         device->GL_SwapWindow       = UIKit_GL_SwapWindow;
@@ -123,6 +124,7 @@ UIKit_CreateDevice(int devindex)
         device->GL_DeleteContext    = UIKit_GL_DeleteContext;
         device->GL_GetProcAddress   = UIKit_GL_GetProcAddress;
         device->GL_LoadLibrary      = UIKit_GL_LoadLibrary;
+#endif
         device->free = UIKit_DeleteDevice;
 
 #if SDL_VIDEO_VULKAN

+ 2 - 0
sdl.mod/SDL/src/video/uikit/SDL_uikitviewcontroller.m

@@ -180,7 +180,9 @@ SDL_HideHomeIndicatorHintChanged(void *userdata, const char *name, const char *o
     /* Don't run the game loop while a messagebox is up */
     if (!UIKit_ShowingMessageBox()) {
         /* See the comment in the function definition. */
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
         UIKit_GL_RestoreCurrentContext();
+#endif
 
         animationCallback(animationCallbackParam);
     }

+ 4 - 0
sdl.mod/SDL/src/video/uikit/SDL_uikitwindow.m

@@ -364,12 +364,16 @@ UIKit_GetWindowWMInfo(_THIS, SDL_Window * window, SDL_SysWMinfo * info)
 
             /* These struct members were added in SDL 2.0.4. */
             if (versionnum >= SDL_VERSIONNUM(2,0,4)) {
+#if SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
                 if ([data.viewcontroller.view isKindOfClass:[SDL_uikitopenglview class]]) {
                     SDL_uikitopenglview *glview = (SDL_uikitopenglview *)data.viewcontroller.view;
                     info->info.uikit.framebuffer = glview.drawableFramebuffer;
                     info->info.uikit.colorbuffer = glview.drawableRenderbuffer;
                     info->info.uikit.resolveFramebuffer = glview.msaaResolveFramebuffer;
                 } else {
+#else
+                {
+#endif
                     info->info.uikit.framebuffer = 0;
                     info->info.uikit.colorbuffer = 0;
                     info->info.uikit.resolveFramebuffer = 0;

+ 1 - 1
sdl.mod/SDL/src/video/x11/SDL_x11events.c

@@ -433,8 +433,8 @@ X11_DispatchFocusOut(_THIS, SDL_WindowData *data)
 static void
 X11_DispatchMapNotify(SDL_WindowData *data)
 {
-    SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
     SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_RESTORED, 0, 0);
+    SDL_SendWindowEvent(data->window, SDL_WINDOWEVENT_SHOWN, 0, 0);
 }
 
 static void

+ 0 - 2
sdl.mod/SDL/src/video/x11/SDL_x11window.c

@@ -637,7 +637,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
     ) {
 #if SDL_VIDEO_OPENGL_EGL  
         if (!_this->egl_data) {
-            X11_XDestroyWindow(display, w);
             return -1;
         }
 
@@ -645,7 +644,6 @@ X11_CreateWindow(_THIS, SDL_Window * window)
         windowdata->egl_surface = SDL_EGL_CreateSurface(_this, (NativeWindowType) w);
 
         if (windowdata->egl_surface == EGL_NO_SURFACE) {
-            X11_XDestroyWindow(display, w);
             return SDL_SetError("Could not create GLES window surface");
         }
 #else

+ 1 - 0
sdl.mod/source.bmx

@@ -74,6 +74,7 @@ Import "SDL/src/stdlib/SDL_malloc.c"
 Import "SDL/src/stdlib/SDL_qsort.c"
 Import "SDL/src/stdlib/SDL_stdlib.c"
 Import "SDL/src/stdlib/SDL_string.c"
+Import "SDL/src/stdlib/SDL_strtokr.c"
 Import "SDL/src/thread/SDL_thread.c"
 Import "SDL/src/timer/SDL_timer.c"
 Import "SDL/src/video/dummy/SDL_nullevents.c"