Added stubs for simple Steam Controller support
authorSam Lantinga <slouken@libsdl.org>
Fri, 22 Sep 2017 08:30:52 -0700
changeset 115324af4e3986438
parent 11531 84793b17a0d2
child 11533 78846363e865
Added stubs for simple Steam Controller support
Android.mk
Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj
configure
configure.in
src/joystick/SDL_gamecontroller.c
src/joystick/SDL_gamecontrollerdb.h
src/joystick/android/SDL_sysjoystick.c
src/joystick/android/SDL_sysjoystick_c.h
src/joystick/iphoneos/SDL_sysjoystick.m
src/joystick/iphoneos/SDL_sysjoystick_c.h
src/joystick/linux/SDL_sysjoystick.c
src/joystick/linux/SDL_sysjoystick_c.h
src/joystick/steam/SDL_steamcontroller.c
     1.1 --- a/Android.mk	Fri Sep 22 08:30:46 2017 -0700
     1.2 +++ b/Android.mk	Fri Sep 22 08:30:52 2017 -0700
     1.3 @@ -31,6 +31,8 @@
     1.4  	$(wildcard $(LOCAL_PATH)/src/haptic/android/*.c) \
     1.5  	$(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
     1.6  	$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
     1.7 +	$(LOCAL_PATH)/src/joystick/steam/SDL_steamcontroller.c \
     1.8 +	$(LOCAL_PATH)/src/joystick/steam/steamcontroller_hidapi.c \
     1.9  	$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \
    1.10  	$(wildcard $(LOCAL_PATH)/src/power/*.c) \
    1.11  	$(wildcard $(LOCAL_PATH)/src/power/android/*.c) \
    1.12 @@ -44,7 +46,9 @@
    1.13  	$(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \
    1.14  	$(wildcard $(LOCAL_PATH)/src/video/*.c) \
    1.15  	$(wildcard $(LOCAL_PATH)/src/video/android/*.c) \
    1.16 -	$(wildcard $(LOCAL_PATH)/src/test/*.c))
    1.17 +	$(wildcard $(LOCAL_PATH)/src/test/*.c)) \
    1.18 +
    1.19 +LOCAL_SHARED_LIBRARIES := hidapi
    1.20  
    1.21  LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES
    1.22  LOCAL_LDLIBS := -ldl -lGLESv1_CM -lGLESv2 -llog -landroid
     2.1 --- a/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj	Fri Sep 22 08:30:46 2017 -0700
     2.2 +++ b/Xcode-iOS/SDL/SDL.xcodeproj/project.pbxproj	Fri Sep 22 08:30:52 2017 -0700
     2.3 @@ -90,6 +90,8 @@
     2.4  		56F9D5601DF73BA400C15B5D /* SDL_dataqueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 566726431DF72CF5001DD3DB /* SDL_dataqueue.c */; };
     2.5  		93CB792313FC5E5200BD3E05 /* SDL_uikitviewcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = 93CB792213FC5E5200BD3E05 /* SDL_uikitviewcontroller.h */; };
     2.6  		93CB792613FC5F5300BD3E05 /* SDL_uikitviewcontroller.m in Sources */ = {isa = PBXBuildFile; fileRef = 93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */; };
     2.7 +		A7A9EEA91F702631002A5589 /* SDL_steamcontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = A7A9EEA71F702631002A5589 /* SDL_steamcontroller.c */; };
     2.8 +		A7A9EEAA1F702631002A5589 /* SDL_steamcontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = A7A9EEA81F702631002A5589 /* SDL_steamcontroller.h */; };
     2.9  		AA0AD06216647BBB00CE5896 /* SDL_gamecontroller.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */; };
    2.10  		AA0AD06516647BD400CE5896 /* SDL_gamecontroller.h in Headers */ = {isa = PBXBuildFile; fileRef = AA0AD06416647BD400CE5896 /* SDL_gamecontroller.h */; };
    2.11  		AA0F8495178D5F1A00823F9D /* SDL_systls.c in Sources */ = {isa = PBXBuildFile; fileRef = AA0F8494178D5F1A00823F9D /* SDL_systls.c */; };
    2.12 @@ -393,6 +395,8 @@
    2.13  		56ED04E2118A8EFD00A56AA6 /* SDL_syspower.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDL_syspower.m; path = ../../src/power/uikit/SDL_syspower.m; sourceTree = SOURCE_ROOT; };
    2.14  		93CB792213FC5E5200BD3E05 /* SDL_uikitviewcontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_uikitviewcontroller.h; sourceTree = "<group>"; };
    2.15  		93CB792513FC5F5300BD3E05 /* SDL_uikitviewcontroller.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDL_uikitviewcontroller.m; sourceTree = "<group>"; };
    2.16 +		A7A9EEA71F702631002A5589 /* SDL_steamcontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_steamcontroller.c; sourceTree = "<group>"; };
    2.17 +		A7A9EEA81F702631002A5589 /* SDL_steamcontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_steamcontroller.h; sourceTree = "<group>"; };
    2.18  		AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_gamecontroller.c; sourceTree = "<group>"; };
    2.19  		AA0AD06416647BD400CE5896 /* SDL_gamecontroller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_gamecontroller.h; sourceTree = "<group>"; };
    2.20  		AA0F8494178D5F1A00823F9D /* SDL_systls.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_systls.c; sourceTree = "<group>"; };
    2.21 @@ -725,6 +729,15 @@
    2.22  			name = uikit;
    2.23  			sourceTree = "<group>";
    2.24  		};
    2.25 +		A7A9EEA61F702607002A5589 /* steam */ = {
    2.26 +			isa = PBXGroup;
    2.27 +			children = (
    2.28 +				A7A9EEA71F702631002A5589 /* SDL_steamcontroller.c */,
    2.29 +				A7A9EEA81F702631002A5589 /* SDL_steamcontroller.h */,
    2.30 +			);
    2.31 +			path = steam;
    2.32 +			sourceTree = "<group>";
    2.33 +		};
    2.34  		FD3F4A6F0DEA620800C5B771 /* stdlib */ = {
    2.35  			isa = PBXGroup;
    2.36  			children = (
    2.37 @@ -742,6 +755,7 @@
    2.38  		FD5F9D080E0E08B3008E885B /* joystick */ = {
    2.39  			isa = PBXGroup;
    2.40  			children = (
    2.41 +				A7A9EEA61F702607002A5589 /* steam */,
    2.42  				FD689EFF0E26E5B600F90B21 /* iphoneos */,
    2.43  				AA0AD06116647BBB00CE5896 /* SDL_gamecontroller.c */,
    2.44  				FD5F9D1E0E0E08B3008E885B /* SDL_joystick.c */,
    2.45 @@ -1124,6 +1138,7 @@
    2.46  				04F7807E12FB751400FC43C0 /* SDL_drawline.h in Headers */,
    2.47  				04F7808012FB751400FC43C0 /* SDL_drawpoint.h in Headers */,
    2.48  				04F7808412FB753F00FC43C0 /* SDL_nullframebuffer_c.h in Headers */,
    2.49 +				A7A9EEAA1F702631002A5589 /* SDL_steamcontroller.h in Headers */,
    2.50  				0442EC5012FE1C1E004C9285 /* SDL_render_sw_c.h in Headers */,
    2.51  				FA1DC2721C62BE65008F99A0 /* SDL_uikitclipboard.h in Headers */,
    2.52  				0402A85A12FE70C600CECEE3 /* SDL_shaders_gles2.h in Headers */,
    2.53 @@ -1398,6 +1413,7 @@
    2.54  			files = (
    2.55  				FD6526810DE8FCDD002AD96B /* SDL_systimer.c in Sources */,
    2.56  				FD6526800DE8FCDD002AD96B /* SDL_timer.c in Sources */,
    2.57 +				A7A9EEA91F702631002A5589 /* SDL_steamcontroller.c in Sources */,
    2.58  				FD3F4A7B0DEA620800C5B771 /* SDL_string.c in Sources */,
    2.59  				FD6526660DE8FCDD002AD96B /* SDL_dummyaudio.c in Sources */,
    2.60  				FD6526670DE8FCDD002AD96B /* SDL_audio.c in Sources */,
     3.1 --- a/configure	Fri Sep 22 08:30:46 2017 -0700
     3.2 +++ b/configure	Fri Sep 22 08:30:52 2017 -0700
     3.3 @@ -16846,6 +16846,7 @@
     3.4  SOURCES="$SOURCES $srcdir/src/*.c"
     3.5  SOURCES="$SOURCES $srcdir/src/atomic/*.c"
     3.6  SOURCES="$SOURCES $srcdir/src/audio/*.c"
     3.7 +SOURCES="$SOURCES $srcdir/src/audio/marvell/*.c"
     3.8  SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c"
     3.9  SOURCES="$SOURCES $srcdir/src/dynapi/*.c"
    3.10  SOURCES="$SOURCES $srcdir/src/events/*.c"
    3.11 @@ -23839,6 +23840,7 @@
    3.12  $as_echo "#define SDL_JOYSTICK_LINUX 1" >>confdefs.h
    3.13  
    3.14                  SOURCES="$SOURCES $srcdir/src/joystick/linux/*.c"
    3.15 +                SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c"
    3.16                  have_joystick=yes
    3.17              ;;
    3.18              android)
     4.1 --- a/configure.in	Fri Sep 22 08:30:46 2017 -0700
     4.2 +++ b/configure.in	Fri Sep 22 08:30:52 2017 -0700
     4.3 @@ -325,6 +325,7 @@
     4.4  SOURCES="$SOURCES $srcdir/src/*.c"
     4.5  SOURCES="$SOURCES $srcdir/src/atomic/*.c"
     4.6  SOURCES="$SOURCES $srcdir/src/audio/*.c"
     4.7 +SOURCES="$SOURCES $srcdir/src/audio/marvell/*.c"
     4.8  SOURCES="$SOURCES $srcdir/src/cpuinfo/*.c"
     4.9  SOURCES="$SOURCES $srcdir/src/dynapi/*.c"
    4.10  SOURCES="$SOURCES $srcdir/src/events/*.c"
    4.11 @@ -3360,6 +3361,7 @@
    4.12              linux)
    4.13                  AC_DEFINE(SDL_JOYSTICK_LINUX, 1, [ ])
    4.14                  SOURCES="$SOURCES $srcdir/src/joystick/linux/*.c"
    4.15 +                SOURCES="$SOURCES $srcdir/src/joystick/steam/*.c"
    4.16                  have_joystick=yes
    4.17              ;;
    4.18              android)
     5.1 --- a/src/joystick/SDL_gamecontroller.c	Fri Sep 22 08:30:46 2017 -0700
     5.2 +++ b/src/joystick/SDL_gamecontroller.c	Fri Sep 22 08:30:52 2017 -0700
     5.3 @@ -33,6 +33,11 @@
     5.4  #include "../events/SDL_events_c.h"
     5.5  #endif
     5.6  
     5.7 +#if defined(__ANDROID__)
     5.8 +#include "SDL_system.h"
     5.9 +#endif
    5.10 +
    5.11 +
    5.12  #define SDL_CONTROLLER_PLATFORM_FIELD "platform:"
    5.13  
    5.14  /* a list of currently opened game controllers */
    5.15 @@ -1158,11 +1163,29 @@
    5.16  }
    5.17  
    5.18  /*
    5.19 + * Fill the given buffer with the expected controller mapping filepath. 
    5.20 + * Usually this will just be CONTROLLER_MAPPING_FILE, but for Android,
    5.21 + * we want to get the internal storage path.
    5.22 + */
    5.23 +static SDL_bool SDL_GetControllerMappingFilePath(char *path, size_t size)
    5.24 +{
    5.25 +#ifdef CONTROLLER_MAPPING_FILE
    5.26 +#define STRING(X) SDL_STRINGIFY_ARG(X)
    5.27 +    return SDL_strlcpy(path, STRING(CONTROLLER_MAPPING_FILE), size) < size;
    5.28 +#elif defined(__ANDROID__)
    5.29 +    return SDL_snprintf(path, size, "%s/controller_map.txt", SDL_AndroidGetInternalStoragePath()) < size;
    5.30 +#else
    5.31 +    return SDL_FALSE;
    5.32 +#endif
    5.33 +}
    5.34 +
    5.35 +/*
    5.36   * Initialize the game controller system, mostly load our DB of controller config mappings
    5.37   */
    5.38  int
    5.39  SDL_GameControllerInitMappings(void)
    5.40  {
    5.41 +    char szControllerMapPath[1024];
    5.42      int i = 0;
    5.43      const char *pMappingString = NULL;
    5.44      pMappingString = s_ControllerMappings[i];
    5.45 @@ -1173,6 +1196,10 @@
    5.46          pMappingString = s_ControllerMappings[i];
    5.47      }
    5.48  
    5.49 +    if (SDL_GetControllerMappingFilePath(szControllerMapPath, sizeof(szControllerMapPath))) {
    5.50 +        SDL_GameControllerAddMappingsFromFile(szControllerMapPath);        
    5.51 +    }
    5.52 +
    5.53      /* load in any user supplied config */
    5.54      SDL_GameControllerLoadHints();
    5.55  
     6.1 --- a/src/joystick/SDL_gamecontrollerdb.h	Fri Sep 22 08:30:46 2017 -0700
     6.2 +++ b/src/joystick/SDL_gamecontrollerdb.h	Fri Sep 22 08:30:52 2017 -0700
     6.3 @@ -191,6 +191,10 @@
     6.4      "03000000a30600000cff000010010000,Saitek P2500 Force Rumble Pad,a:b2,b:b3,back:b11,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b8,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b9,righttrigger:b7,rightx:a3,righty:a2,x:b0,y:b1,",
     6.5      "03000000a30600000b04000000010000,Saitek P990 Dual Analog Pad,a:b1,b:b2,back:b9,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:a2,start:b8,x:b0,y:b3,",
     6.6      "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,",
     6.7 +    "05000000de2800000511000001000000,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,",
     6.8 +    "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,",
     6.9 +    "05000000de2800000212000001000000,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,",
    6.10 +    "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,",
    6.11      "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
    6.12      "03000000de280000ff11000001000000,Steam Virtual 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,",
    6.13      "xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
    6.14 @@ -201,13 +205,18 @@
    6.15      "03000000830500006020000010010000,iBuffalo SNES Controller,a:b1,b:b0,back:b6,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b4,rightshoulder:b5,start:b7,x:b3,y:b2,",
    6.16  #endif
    6.17  #if defined(__ANDROID__)
    6.18 +    "64633436313965656664373634323364,Microsoft X-Box 360 pad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,x:b2,y:b3,",
    6.19      "4e564944494120436f72706f72617469,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
    6.20 +    "61363931656135336130663561616264,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
    6.21 +    "37336435666338653565313731303834,NVIDIA Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b9,leftstick:b7,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a5,rightx:a2,righty:a3,start:b6,x:b2,y:b3,",
    6.22 +    "35643031303033326130316330353564,PS4 Controller,a:b1,b:b17,back:b15,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,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,",
    6.23 +    "05000000de2800000511000001000000,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,",
    6.24 +    "34356136633366613530316338376136,Xbox Wireless Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b3,leftstick:b15,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b18,rightstick:b16,righttrigger:a5,rightx:a3,righty:a4,x:b17,y:b2,",
    6.25  #endif
    6.26  #if defined(SDL_JOYSTICK_MFI)
    6.27      "4d466947616d65706164010000000000,MFi Extended Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:a5,rightx:a3,righty:a4,start:b6,x:b2,y:b3,",
    6.28      "4d466947616d65706164020000000000,MFi Gamepad,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,rightshoulder:b5,start:b6,x:b2,y:b3,",
    6.29 -    "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,",
    6.30 -    "03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
    6.31 +    "05000000de2800000511000001000000,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,",
    6.32  #endif
    6.33  #if defined(SDL_JOYSTICK_EMSCRIPTEN)
    6.34      "emscripten,Standard Gamepad,a:b0,b:b1,back:b8,dpdown:b13,dpleft:b14,dpright:b15,dpup:b12,guide:b16,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,",
     7.1 --- a/src/joystick/android/SDL_sysjoystick.c	Fri Sep 22 08:30:46 2017 -0700
     7.2 +++ b/src/joystick/android/SDL_sysjoystick.c	Fri Sep 22 08:30:52 2017 -0700
     7.3 @@ -35,6 +35,7 @@
     7.4  #include "SDL_sysjoystick_c.h"
     7.5  #include "../SDL_joystick_c.h"
     7.6  #include "../../core/android/SDL_android.h"
     7.7 +#include "../steam/SDL_steamcontroller.h"
     7.8  
     7.9  #include "android/keycodes.h"
    7.10  
    7.11 @@ -216,7 +217,7 @@
    7.12      /* Android gives joy info normalized as [-1.0, 1.0] or [0.0, 1.0] */
    7.13      SDL_joylist_item *item = JoystickByDeviceId(device_id);
    7.14      if (item && item->joystick) {
    7.15 -        SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16) (32767.*value) );
    7.16 +        SDL_PrivateJoystickAxis(item->joystick, axis, (Sint16) (32767.*value));
    7.17      }
    7.18      
    7.19      return 0;
    7.20 @@ -234,7 +235,7 @@
    7.21      if (x >= -1 && x <=1 && y >= -1 && y <= 1) {
    7.22          SDL_joylist_item *item = JoystickByDeviceId(device_id);
    7.23          if (item && item->joystick) {
    7.24 -            SDL_PrivateJoystickHat(item->joystick, hat_id, position_map[y+1][x+1] );
    7.25 +            SDL_PrivateJoystickHat(item->joystick, hat_id, position_map[y+1][x+1]);
    7.26          }
    7.27          return 0;
    7.28      }
    7.29 @@ -254,8 +255,8 @@
    7.30      }
    7.31      
    7.32      /* the GUID is just the first 16 chars of the name for now */
    7.33 -    SDL_zero( guid );
    7.34 -    SDL_memcpy( &guid, desc, SDL_min( sizeof(guid), SDL_strlen( desc) ) );
    7.35 +    SDL_zero(guid);
    7.36 +    SDL_memcpy(&guid, desc, SDL_min(sizeof(guid), SDL_strlen(desc)));
    7.37  
    7.38      item = (SDL_joylist_item *) SDL_malloc(sizeof (SDL_joylist_item));
    7.39      if (item == NULL) {
    7.40 @@ -266,7 +267,7 @@
    7.41      item->guid = guid;
    7.42      item->device_id = device_id;
    7.43      item->name = SDL_strdup(name);
    7.44 -    if ( item->name == NULL ) {
    7.45 +    if (item->name == NULL) {
    7.46           SDL_free(item);
    7.47           return -1;
    7.48      }
    7.49 @@ -349,6 +350,79 @@
    7.50  }
    7.51  
    7.52  
    7.53 +static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance)
    7.54 +{
    7.55 +    SDL_joylist_item *item;
    7.56 +    
    7.57 +    item = (SDL_joylist_item *)SDL_calloc(1, sizeof (SDL_joylist_item));
    7.58 +    if (item == NULL) {
    7.59 +        return SDL_FALSE;
    7.60 +    }
    7.61 +
    7.62 +    *device_instance = item->device_instance = instance_counter++;
    7.63 +    item->device_id = -1;
    7.64 +    item->name = SDL_strdup(name);
    7.65 +    item->guid = guid;
    7.66 +    SDL_GetSteamControllerInputs(&item->nbuttons,
    7.67 +                                 &item->naxes,
    7.68 +                                 &item->nhats);
    7.69 +    item->m_bSteamController = SDL_TRUE;
    7.70 +
    7.71 +    if (SDL_joylist_tail == NULL) {
    7.72 +        SDL_joylist = SDL_joylist_tail = item;
    7.73 +    } else {
    7.74 +        SDL_joylist_tail->next = item;
    7.75 +        SDL_joylist_tail = item;
    7.76 +    }
    7.77 +
    7.78 +    /* Need to increment the joystick count before we post the event */
    7.79 +    ++numjoysticks;
    7.80 +
    7.81 +    SDL_PrivateJoystickAdded(numjoysticks - 1);
    7.82 +
    7.83 +    return SDL_TRUE;
    7.84 +}
    7.85 +
    7.86 +static void SteamControllerDisconnectedCallback(int device_instance)
    7.87 +{
    7.88 +    SDL_joylist_item *item = SDL_joylist;
    7.89 +    SDL_joylist_item *prev = NULL;
    7.90 +    
    7.91 +    while (item != NULL) {
    7.92 +        if (item->device_instance == device_instance) {
    7.93 +            break;
    7.94 +        }
    7.95 +        prev = item;
    7.96 +        item = item->next;
    7.97 +    }
    7.98 +    
    7.99 +    if (item == NULL) {
   7.100 +        return;
   7.101 +    }
   7.102 +
   7.103 +    if (item->joystick) {
   7.104 +        item->joystick->hwdata = NULL;
   7.105 +    }
   7.106 +        
   7.107 +    if (prev != NULL) {
   7.108 +        prev->next = item->next;
   7.109 +    } else {
   7.110 +        SDL_assert(SDL_joylist == item);
   7.111 +        SDL_joylist = item->next;
   7.112 +    }
   7.113 +    if (item == SDL_joylist_tail) {
   7.114 +        SDL_joylist_tail = prev;
   7.115 +    }
   7.116 +
   7.117 +    /* Need to decrement the joystick count before we post the event */
   7.118 +    --numjoysticks;
   7.119 +
   7.120 +    SDL_PrivateJoystickRemoved(item->device_instance);
   7.121 +
   7.122 +    SDL_free(item->name);
   7.123 +    SDL_free(item);
   7.124 +}
   7.125 +
   7.126  int
   7.127  SDL_SYS_JoystickInit(void)
   7.128  {
   7.129 @@ -359,6 +433,9 @@
   7.130          Android_AddJoystick(ANDROID_ACCELEROMETER_DEVICE_ID, ANDROID_ACCELEROMETER_NAME, ANDROID_ACCELEROMETER_NAME, SDL_TRUE, 0, 3, 0, 0);
   7.131      }
   7.132     
   7.133 +    SDL_InitSteamControllers(SteamControllerConnectedCallback,
   7.134 +                             SteamControllerDisconnectedCallback);
   7.135 +
   7.136      return (numjoysticks);
   7.137  
   7.138  }
   7.139 @@ -381,6 +458,8 @@
   7.140          timeout = SDL_GetTicks() + 3000;
   7.141          Android_JNI_PollInputDevices();
   7.142      }
   7.143 +
   7.144 +    SDL_UpdateSteamControllers();
   7.145  }
   7.146  
   7.147  static SDL_joylist_item *
   7.148 @@ -449,7 +528,7 @@
   7.149  {
   7.150      SDL_joylist_item *item = JoystickByDevIndex(device_index);
   7.151  
   7.152 -    if (item == NULL ) {
   7.153 +    if (item == NULL) {
   7.154          return SDL_SetError("No such device");
   7.155      }
   7.156      
   7.157 @@ -477,30 +556,34 @@
   7.158  void
   7.159  SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
   7.160  {
   7.161 -    int i;
   7.162 -    Sint16 value;
   7.163 -    float values[3];
   7.164 -    SDL_joylist_item *item = SDL_joylist;
   7.165 +    SDL_joylist_item *item = (SDL_joylist_item *) joystick->hwdata;
   7.166  
   7.167 -    while (item) {
   7.168 -        if (item->is_accelerometer) {
   7.169 -            if (item->joystick) {
   7.170 -                if (Android_JNI_GetAccelerometerValues(values)) {
   7.171 -                    for ( i = 0; i < 3; i++ ) {
   7.172 -                        if (values[i] > 1.0f) {
   7.173 -                            values[i] = 1.0f;
   7.174 -                        } else if (values[i] < -1.0f) {
   7.175 -                            values[i] = -1.0f;
   7.176 -                        }
   7.177 +    if (item == NULL) {
   7.178 +        return;
   7.179 +    }
   7.180 + 
   7.181 +    if (item->m_bSteamController) {
   7.182 +        SDL_UpdateSteamController(joystick);
   7.183 +        return;
   7.184 +    }
   7.185  
   7.186 -                        value = (Sint16)(values[i] * 32767.0f);
   7.187 -                        SDL_PrivateJoystickAxis(item->joystick, i, value);
   7.188 -                    }
   7.189 +    if (item->is_accelerometer) {
   7.190 +        int i;
   7.191 +        Sint16 value;
   7.192 +        float values[3];
   7.193 +
   7.194 +        if (Android_JNI_GetAccelerometerValues(values)) {
   7.195 +            for (i = 0; i < 3; i++) {
   7.196 +                if (values[i] > 1.0f) {
   7.197 +                    values[i] = 1.0f;
   7.198 +                } else if (values[i] < -1.0f) {
   7.199 +                    values[i] = -1.0f;
   7.200                  }
   7.201 +
   7.202 +                value = (Sint16)(values[i] * 32767.0f);
   7.203 +                SDL_PrivateJoystickAxis(item->joystick, i, value);
   7.204              }
   7.205 -            break;
   7.206          }
   7.207 -        item = item->next;
   7.208      }
   7.209  }
   7.210  
   7.211 @@ -518,6 +601,10 @@
   7.212  void
   7.213  SDL_SYS_JoystickQuit(void)
   7.214  {
   7.215 +/* We don't have any way to scan for joysticks at init, so don't wipe the list
   7.216 + * of joysticks here in case this is a reinit.
   7.217 + */
   7.218 +#if 0
   7.219      SDL_joylist_item *item = NULL;
   7.220      SDL_joylist_item *next = NULL;
   7.221  
   7.222 @@ -531,9 +618,12 @@
   7.223  
   7.224      numjoysticks = 0;
   7.225      instance_counter = 0;
   7.226 +#endif /* 0 */
   7.227 +
   7.228 +    SDL_QuitSteamControllers();
   7.229  }
   7.230  
   7.231 -SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
   7.232 +SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int device_index)
   7.233  {
   7.234      return JoystickByDevIndex(device_index)->guid;
   7.235  }
     8.1 --- a/src/joystick/android/SDL_sysjoystick_c.h	Fri Sep 22 08:30:46 2017 -0700
     8.2 +++ b/src/joystick/android/SDL_sysjoystick_c.h	Fri Sep 22 08:30:52 2017 -0700
     8.3 @@ -46,6 +46,9 @@
     8.4      SDL_Joystick *joystick;
     8.5      int nbuttons, naxes, nhats, nballs;
     8.6      
     8.7 +    /* Steam Controller support */
     8.8 +    SDL_bool m_bSteamController;
     8.9 +
    8.10      struct SDL_joylist_item *next;
    8.11  } SDL_joylist_item;
    8.12  
     9.1 --- a/src/joystick/iphoneos/SDL_sysjoystick.m	Fri Sep 22 08:30:46 2017 -0700
     9.2 +++ b/src/joystick/iphoneos/SDL_sysjoystick.m	Fri Sep 22 08:30:52 2017 -0700
     9.3 @@ -26,12 +26,15 @@
     9.4  /* needed for SDL_IPHONE_MAX_GFORCE macro */
     9.5  #include "SDL_config_iphoneos.h"
     9.6  
     9.7 +#include "SDL_assert.h"
     9.8  #include "SDL_events.h"
     9.9  #include "SDL_joystick.h"
    9.10  #include "SDL_hints.h"
    9.11  #include "SDL_stdinc.h"
    9.12  #include "../SDL_sysjoystick.h"
    9.13  #include "../SDL_joystick_c.h"
    9.14 +#include "../steam/SDL_steamcontroller.h"
    9.15 +
    9.16  
    9.17  #if !SDL_EVENTS_DISABLED
    9.18  #include "../../events/SDL_events_c.h"
    9.19 @@ -242,7 +245,7 @@
    9.20  
    9.21      --numjoysticks;
    9.22  
    9.23 -	SDL_PrivateJoystickRemoved(device->instance_id);
    9.24 +    SDL_PrivateJoystickRemoved(device->instance_id);
    9.25  
    9.26      SDL_free(device->name);
    9.27      SDL_free(device);
    9.28 @@ -266,6 +269,50 @@
    9.29  }
    9.30  #endif /* TARGET_OS_TV */
    9.31  
    9.32 +static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance)
    9.33 +{
    9.34 +    SDL_JoystickDeviceItem *device = (SDL_JoystickDeviceItem *)SDL_calloc(1, sizeof(SDL_JoystickDeviceItem));
    9.35 +    if (device == NULL) {
    9.36 +        return SDL_FALSE;
    9.37 +    }
    9.38 +
    9.39 +    *device_instance = device->instance_id = instancecounter++;
    9.40 +	device->name = SDL_strdup(name);
    9.41 +	device->guid = guid;
    9.42 +	SDL_GetSteamControllerInputs(&device->nbuttons,
    9.43 +								 &device->naxes,
    9.44 +								 &device->nhats);
    9.45 +    device->m_bSteamController = SDL_TRUE;
    9.46 +
    9.47 +    if (deviceList == NULL) {
    9.48 +        deviceList = device;
    9.49 +    } else {
    9.50 +        SDL_JoystickDeviceItem *lastdevice = deviceList;
    9.51 +        while (lastdevice->next != NULL) {
    9.52 +            lastdevice = lastdevice->next;
    9.53 +        }
    9.54 +        lastdevice->next = device;
    9.55 +    }
    9.56 +
    9.57 +    ++numjoysticks;
    9.58 +
    9.59 +    SDL_PrivateJoystickAdded(numjoysticks - 1);
    9.60 +
    9.61 +    return SDL_TRUE;
    9.62 +}
    9.63 +
    9.64 +static void SteamControllerDisconnectedCallback(int device_instance)
    9.65 +{
    9.66 +    SDL_JoystickDeviceItem *item;
    9.67 +
    9.68 +	for (item = deviceList; item; item = item->next) {
    9.69 +        if (item->instance_id == device_instance) {
    9.70 +			SDL_SYS_RemoveJoystickDevice(item);
    9.71 +			break;
    9.72 +        }
    9.73 +    }
    9.74 +}
    9.75 +
    9.76  /* Function to scan the system for joysticks.
    9.77   * Joystick 0 should be the system default joystick.
    9.78   * It should return 0, or -1 on an unrecoverable fatal error.
    9.79 @@ -276,6 +323,9 @@
    9.80      @autoreleasepool {
    9.81          NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
    9.82  
    9.83 +        SDL_InitSteamControllers(SteamControllerConnectedCallback,
    9.84 +                                 SteamControllerDisconnectedCallback);
    9.85 +
    9.86  #if !TARGET_OS_TV
    9.87          if (SDL_GetHintBoolean(SDL_HINT_ACCELEROMETER_AS_JOYSTICK, SDL_TRUE)) {
    9.88              /* Default behavior, accelerometer as joystick */
    9.89 @@ -335,6 +385,7 @@
    9.90  void
    9.91  SDL_SYS_JoystickDetect(void)
    9.92  {
    9.93 +    SDL_UpdateSteamControllers();
    9.94  }
    9.95  
    9.96  /* Function to get the device-dependent name of a joystick */
    9.97 @@ -628,6 +679,11 @@
    9.98      if (device == NULL) {
    9.99          return;
   9.100      }
   9.101 +    
   9.102 +    if (device->m_bSteamController) {
   9.103 +        SDL_UpdateSteamController(joystick);
   9.104 +        return;
   9.105 +    }
   9.106  
   9.107      if (device->accelerometer) {
   9.108          SDL_SYS_AccelerometerUpdate(joystick);
   9.109 @@ -696,6 +752,8 @@
   9.110  #endif /* !TARGET_OS_TV */
   9.111      }
   9.112  
   9.113 +    SDL_QuitSteamControllers();
   9.114 +
   9.115      numjoysticks = 0;
   9.116  }
   9.117  
    10.1 --- a/src/joystick/iphoneos/SDL_sysjoystick_c.h	Fri Sep 22 08:30:46 2017 -0700
    10.2 +++ b/src/joystick/iphoneos/SDL_sysjoystick_c.h	Fri Sep 22 08:30:52 2017 -0700
    10.3 @@ -44,6 +44,9 @@
    10.4      int nbuttons;
    10.5      int nhats;
    10.6  
    10.7 +    /* Steam Controller support */
    10.8 +    SDL_bool m_bSteamController;
    10.9 +
   10.10      struct joystick_hwdata *next;
   10.11  } joystick_hwdata;
   10.12  
    11.1 --- a/src/joystick/linux/SDL_sysjoystick.c	Fri Sep 22 08:30:46 2017 -0700
    11.2 +++ b/src/joystick/linux/SDL_sysjoystick.c	Fri Sep 22 08:30:52 2017 -0700
    11.3 @@ -38,8 +38,10 @@
    11.4  #include "SDL_assert.h"
    11.5  #include "SDL_joystick.h"
    11.6  #include "SDL_endian.h"
    11.7 +#include "../../events/SDL_events_c.h"
    11.8  #include "../SDL_sysjoystick.h"
    11.9  #include "../SDL_joystick_c.h"
   11.10 +#include "../steam/SDL_steamcontroller.h"
   11.11  #include "SDL_sysjoystick_c.h"
   11.12  
   11.13  /* This isn't defined in older Linux kernel headers */
   11.14 @@ -66,6 +68,9 @@
   11.15      dev_t devnum;
   11.16      struct joystick_hwdata *hwdata;
   11.17      struct SDL_joylist_item *next;
   11.18 +
   11.19 +    /* Steam Controller support */
   11.20 +    SDL_bool m_bSteamController;
   11.21  } SDL_joylist_item;
   11.22  
   11.23  static SDL_joylist_item *SDL_joylist = NULL;
   11.24 @@ -73,6 +78,7 @@
   11.25  static int numjoysticks = 0;
   11.26  static int instance_counter = 0;
   11.27  
   11.28 +
   11.29  #define test_bit(nr, addr) \
   11.30      (((1UL << ((nr) % (sizeof(long) * 8))) & ((addr)[(nr) / (sizeof(long) * 8)])) != 0)
   11.31  #define NBITS(x) ((((x)-1)/(sizeof(long) * 8))+1)
   11.32 @@ -428,6 +434,77 @@
   11.33  }
   11.34  #endif
   11.35  
   11.36 +static SDL_bool SteamControllerConnectedCallback(const char *name, SDL_JoystickGUID guid, int *device_instance)
   11.37 +{
   11.38 +    SDL_joylist_item *item;
   11.39 +
   11.40 +    item = (SDL_joylist_item *) SDL_calloc(1, sizeof (SDL_joylist_item));
   11.41 +    if (item == NULL) {
   11.42 +        return SDL_FALSE;
   11.43 +    }
   11.44 +
   11.45 +    item->path = SDL_strdup("");
   11.46 +    item->name = SDL_strdup(name);
   11.47 +    item->guid = guid;
   11.48 +    item->m_bSteamController = SDL_TRUE;
   11.49 +
   11.50 +    if ((item->path == NULL) || (item->name == NULL)) {
   11.51 +         SDL_free(item->path);
   11.52 +         SDL_free(item->name);
   11.53 +         SDL_free(item);
   11.54 +         return SDL_FALSE;
   11.55 +    }
   11.56 +
   11.57 +    *device_instance = item->device_instance = instance_counter++;
   11.58 +    if (SDL_joylist_tail == NULL) {
   11.59 +        SDL_joylist = SDL_joylist_tail = item;
   11.60 +    } else {
   11.61 +        SDL_joylist_tail->next = item;
   11.62 +        SDL_joylist_tail = item;
   11.63 +    }
   11.64 +
   11.65 +    /* Need to increment the joystick count before we post the event */
   11.66 +    ++numjoysticks;
   11.67 +
   11.68 +    SDL_PrivateJoystickAdded(numjoysticks - 1);
   11.69 +
   11.70 +    return SDL_TRUE;
   11.71 +}
   11.72 +
   11.73 +static void SteamControllerDisconnectedCallback(int device_instance)
   11.74 +{
   11.75 +    SDL_joylist_item *item;
   11.76 +    SDL_joylist_item *prev = NULL;
   11.77 +
   11.78 +    for (item = SDL_joylist; item != NULL; item = item->next) {
   11.79 +        /* found it, remove it. */
   11.80 +        if (item->device_instance == device_instance) {
   11.81 +            if (item->hwdata) {
   11.82 +                item->hwdata->item = NULL;
   11.83 +            }
   11.84 +            if (prev != NULL) {
   11.85 +                prev->next = item->next;
   11.86 +            } else {
   11.87 +                SDL_assert(SDL_joylist == item);
   11.88 +                SDL_joylist = item->next;
   11.89 +            }
   11.90 +            if (item == SDL_joylist_tail) {
   11.91 +                SDL_joylist_tail = prev;
   11.92 +            }
   11.93 +
   11.94 +            /* Need to decrement the joystick count before we post the event */
   11.95 +            --numjoysticks;
   11.96 +
   11.97 +            SDL_PrivateJoystickRemoved(item->device_instance);
   11.98 +
   11.99 +            SDL_free(item->name);
  11.100 +            SDL_free(item);
  11.101 +            return;
  11.102 +        }
  11.103 +        prev = item;
  11.104 +    }
  11.105 +}
  11.106 +
  11.107  int
  11.108  SDL_SYS_JoystickInit(void)
  11.109  {
  11.110 @@ -447,6 +524,9 @@
  11.111          SDL_free(envcopy);
  11.112      }
  11.113  
  11.114 +    SDL_InitSteamControllers(SteamControllerConnectedCallback,
  11.115 +                             SteamControllerDisconnectedCallback);
  11.116 +
  11.117  #if SDL_USE_LIBUDEV
  11.118      return JoystickInitWithUdev();
  11.119  #else 
  11.120 @@ -466,7 +546,8 @@
  11.121  #if SDL_USE_LIBUDEV
  11.122      SDL_UDEV_Poll();
  11.123  #endif
  11.124 -    
  11.125 +
  11.126 +    SDL_UpdateSteamControllers();
  11.127  }
  11.128  
  11.129  static SDL_joylist_item *
  11.130 @@ -650,47 +731,53 @@
  11.131  SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
  11.132  {
  11.133      SDL_joylist_item *item = JoystickByDevIndex(device_index);
  11.134 -    char *fname = NULL;
  11.135 -    int fd = -1;
  11.136  
  11.137      if (item == NULL) {
  11.138          return SDL_SetError("No such device");
  11.139      }
  11.140  
  11.141 -    fname = item->path;
  11.142 -    fd = open(fname, O_RDONLY, 0);
  11.143 -    if (fd < 0) {
  11.144 -        return SDL_SetError("Unable to open %s", fname);
  11.145 -    }
  11.146 -
  11.147      joystick->instance_id = item->device_instance;
  11.148      joystick->hwdata = (struct joystick_hwdata *)
  11.149 -        SDL_malloc(sizeof(*joystick->hwdata));
  11.150 +        SDL_calloc(1, sizeof(*joystick->hwdata));
  11.151      if (joystick->hwdata == NULL) {
  11.152 -        close(fd);
  11.153          return SDL_OutOfMemory();
  11.154      }
  11.155 -    SDL_memset(joystick->hwdata, 0, sizeof(*joystick->hwdata));
  11.156      joystick->hwdata->item = item;
  11.157      joystick->hwdata->guid = item->guid;
  11.158 -    joystick->hwdata->fd = fd;
  11.159 -    joystick->hwdata->fname = SDL_strdup(item->path);
  11.160 -    if (joystick->hwdata->fname == NULL) {
  11.161 -        SDL_free(joystick->hwdata);
  11.162 -        joystick->hwdata = NULL;
  11.163 -        close(fd);
  11.164 -        return SDL_OutOfMemory();
  11.165 +    joystick->hwdata->m_bSteamController = item->m_bSteamController;
  11.166 +
  11.167 +    if (item->m_bSteamController) {
  11.168 +        joystick->hwdata->fd = -1;
  11.169 +        SDL_GetSteamControllerInputs(&joystick->nbuttons,
  11.170 +                                     &joystick->naxes,
  11.171 +                                     &joystick->nhats);
  11.172 +    } else {
  11.173 +        int fd = open(item->path, O_RDONLY, 0);
  11.174 +        if (fd < 0) {
  11.175 +            SDL_free(joystick->hwdata);
  11.176 +            joystick->hwdata = NULL;
  11.177 +            return SDL_SetError("Unable to open %s", item->path);
  11.178 +        }
  11.179 +
  11.180 +        joystick->hwdata->fd = fd;
  11.181 +        joystick->hwdata->fname = SDL_strdup(item->path);
  11.182 +        if (joystick->hwdata->fname == NULL) {
  11.183 +            SDL_free(joystick->hwdata);
  11.184 +            joystick->hwdata = NULL;
  11.185 +            close(fd);
  11.186 +            return SDL_OutOfMemory();
  11.187 +        }
  11.188 +
  11.189 +        /* Set the joystick to non-blocking read mode */
  11.190 +        fcntl(fd, F_SETFL, O_NONBLOCK);
  11.191 +
  11.192 +        /* Get the number of buttons and axes on the joystick */
  11.193 +        ConfigJoystick(joystick, fd);
  11.194      }
  11.195  
  11.196      SDL_assert(item->hwdata == NULL);
  11.197      item->hwdata = joystick->hwdata;
  11.198  
  11.199 -    /* Set the joystick to non-blocking read mode */
  11.200 -    fcntl(fd, F_SETFL, O_NONBLOCK);
  11.201 -
  11.202 -    /* Get the number of buttons and axes on the joystick */
  11.203 -    ConfigJoystick(joystick, fd);
  11.204 -
  11.205      /* mark joystick as fresh and ready */
  11.206      joystick->hwdata->fresh = 1;
  11.207  
  11.208 @@ -881,6 +968,11 @@
  11.209  {
  11.210      int i;
  11.211  
  11.212 +    if (joystick->hwdata->m_bSteamController) {
  11.213 +        SDL_UpdateSteamController(joystick);
  11.214 +        return;
  11.215 +    }
  11.216 +
  11.217      HandleInputEvents(joystick);
  11.218  
  11.219      /* Deliver ball motion updates */
  11.220 @@ -902,7 +994,9 @@
  11.221  SDL_SYS_JoystickClose(SDL_Joystick * joystick)
  11.222  {
  11.223      if (joystick->hwdata) {
  11.224 -        close(joystick->hwdata->fd);
  11.225 +        if (joystick->hwdata->fd >= 0) {
  11.226 +            close(joystick->hwdata->fd);
  11.227 +        }
  11.228          if (joystick->hwdata->item) {
  11.229              joystick->hwdata->item->hwdata = NULL;
  11.230          }
  11.231 @@ -936,6 +1030,8 @@
  11.232      SDL_UDEV_DelCallback(joystick_udev_callback);
  11.233      SDL_UDEV_Quit();
  11.234  #endif
  11.235 +
  11.236 +    SDL_QuitSteamControllers();
  11.237  }
  11.238  
  11.239  SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID( int device_index )
    12.1 --- a/src/joystick/linux/SDL_sysjoystick_c.h	Fri Sep 22 08:30:46 2017 -0700
    12.2 +++ b/src/joystick/linux/SDL_sysjoystick_c.h	Fri Sep 22 08:30:52 2017 -0700
    12.3 @@ -52,6 +52,9 @@
    12.4      } abs_correct[ABS_MAX];
    12.5  
    12.6      int fresh;
    12.7 +
    12.8 +    /* Steam Controller support */
    12.9 +    SDL_bool m_bSteamController;
   12.10  };
   12.11  
   12.12  /* vi: set ts=4 sw=4 expandtab: */
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/src/joystick/steam/SDL_steamcontroller.c	Fri Sep 22 08:30:52 2017 -0700
    13.3 @@ -0,0 +1,52 @@
    13.4 +/*
    13.5 +  Simple DirectMedia Layer
    13.6 +  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
    13.7 +
    13.8 +  This software is provided 'as-is', without any express or implied
    13.9 +  warranty.  In no event will the authors be held liable for any damages
   13.10 +  arising from the use of this software.
   13.11 +
   13.12 +  Permission is granted to anyone to use this software for any purpose,
   13.13 +  including commercial applications, and to alter it and redistribute it
   13.14 +  freely, subject to the following restrictions:
   13.15 +
   13.16 +  1. The origin of this software must not be misrepresented; you must not
   13.17 +     claim that you wrote the original software. If you use this software
   13.18 +     in a product, an acknowledgment in the product documentation would be
   13.19 +     appreciated but is not required.
   13.20 +  2. Altered source versions must be plainly marked as such, and must not be
   13.21 +     misrepresented as being the original software.
   13.22 +  3. This notice may not be removed or altered from any source distribution.
   13.23 +*/
   13.24 +#include "../../SDL_internal.h"
   13.25 +
   13.26 +#include "../SDL_sysjoystick.h"
   13.27 +#include "../SDL_joystick_c.h"
   13.28 +#include "SDL_steamcontroller.h"
   13.29 +
   13.30 +
   13.31 +void SDL_InitSteamControllers(SteamControllerConnectedCallback_t connectedCallback,
   13.32 +                              SteamControllerDisconnectedCallback_t disconnectedCallback)
   13.33 +{
   13.34 +}
   13.35 +
   13.36 +void SDL_GetSteamControllerInputs(int *nbuttons, int *naxes, int *nhats)
   13.37 +{
   13.38 +    *nbuttons = 0;
   13.39 +    *naxes = 0;
   13.40 +    *nhats = 0;
   13.41 +}
   13.42 +
   13.43 +void SDL_UpdateSteamControllers()
   13.44 +{
   13.45 +}
   13.46 +
   13.47 +void SDL_UpdateSteamController(SDL_Joystick *joystick)
   13.48 +{
   13.49 +}
   13.50 +
   13.51 +void SDL_QuitSteamControllers()
   13.52 +{
   13.53 +}
   13.54 +
   13.55 +/* vi: set ts=4 sw=4 expandtab: */