UPDATE devel/sdl2 - add ability to change gamecontroller mapping with environment variable

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

UPDATE devel/sdl2 - add ability to change gamecontroller mapping with environment variable

Thomas Frohwein
Hi,

The way that SDL2's gamecontroller API was enabled with the 2.0.7 upgrade
hardcoded one controller mapping at compile time (which was an upgrade from
not being able to use it all in FNA games, reportedly also PPSSPP before that).

SDL2 *should* however be able to map the controller layout at runtime based on
1) the SDL_GAMECONTROLLERCONFIG environment variable, and 2) files with
controller layout specifications, in several applications called
gamecontrollerdb.txt.

The below diff adds the ability to assign controller mapping at runtime via the
SDL_GAMECONTROLLERCONFIG env variable. It is a workaround because it is not
clear yet where the upstream SDL2 code fails to achieve this. Reading mapping
from file is not (yet) possible.

The diff only changes a handful of lines (see below). I tested it completely
remapping a Logitech Dual Action gamepad, including D-pad. The first 2 parts of
the string (guid and device name) don't have any functional impact at this
point when passed via the SDL_GAMECONTROLLERCONFIG.

My suggested approach at the moment is using the port sdl-jstest to display the
mapping string with 'sdl2-jstest -l', adjusting the buttons, axes, and dpad
from there and pass it into the SDL_GAMECONTROLLERCONfIG environment variable.

Empty SDL_GAMECONTROLLERCONFIG keeps default mappings. An invalid mapping
string seems to disable the gamepad in the application based on my testing.

Thanks.

Index: Makefile
===================================================================
RCS file: /cvs/ports/devel/sdl2/Makefile,v
retrieving revision 1.20
diff -u -p -r1.20 Makefile
--- Makefile 12 Jan 2018 19:32:54 -0000 1.20
+++ Makefile 21 Jan 2018 23:40:12 -0000
@@ -9,7 +9,7 @@ DISTNAME= SDL2-${V}
 PKGNAME= sdl2-${V}
 CATEGORIES= devel
 MASTER_SITES= https://www.libsdl.org/release/
-REVISION= 0
+REVISION= 1
 
 SHARED_LIBS= SDL2 0.4 # 0.7
 
Index: patches/patch-src_joystick_SDL_gamecontroller_c
===================================================================
RCS file: /cvs/ports/devel/sdl2/patches/patch-src_joystick_SDL_gamecontroller_c,v
retrieving revision 1.1
diff -u -p -r1.1 patch-src_joystick_SDL_gamecontroller_c
--- patches/patch-src_joystick_SDL_gamecontroller_c 7 Jan 2018 22:56:46 -0000 1.1
+++ patches/patch-src_joystick_SDL_gamecontroller_c 21 Jan 2018 23:40:12 -0000
@@ -5,11 +5,12 @@ also disable checking string "Xbox 360 W
 everything will be Xbox360 controller (works with generic joysticks)
 - note: the actual Xbox360 controller has buttons and axes messed up on
          openbsd with these mappings
+map to SDL_GAMECONTROLLERCONFIG envvar if available
 
 Index: src/joystick/SDL_gamecontroller.c
 --- src/joystick/SDL_gamecontroller.c.orig
 +++ src/joystick/SDL_gamecontroller.c
-@@ -884,15 +884,15 @@ static ControllerMapping_t *SDL_PrivateGetControllerMa
+@@ -884,15 +884,21 @@ static ControllerMapping_t *SDL_PrivateGetControllerMa
  #else
      (void) s_pEmscriptenMapping;  /* pacify ARMCC */
  #endif
@@ -20,10 +21,17 @@ Index: src/joystick/SDL_gamecontroller.c
 +        //if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
              /* The Linux driver xpad.c maps the wireless dpad to buttons */
              SDL_bool existing;
-             mapping = SDL_PrivateAddMappingForGUID(guid,
+-            mapping = SDL_PrivateAddMappingForGUID(guid,
++    char guid_str[1024];
++            SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));
++    if (SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG) == NULL) {
++    mapping = SDL_PrivateAddMappingForGUID(guid,
  "none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
                            &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
 -        }
++    } else {
++    mapping = SDL_PrivateAddMappingForGUID(guid, SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG), &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
++    }
 +        //}
      }
  #endif /* __LINUX__ */

Reply | Threaded
Open this post in threaded view
|

Re: UPDATE devel/sdl2 - add ability to change gamecontroller mapping with environment variable

Thomas Frohwein
ping - any takers who would import this? It's a brief and easy update and makes
SDL2 gamepad use much more enjoyable.

On Sun, Jan 21, 2018 at 04:13:29PM -0800, Thomas Frohwein wrote:

> Hi,
>
> The way that SDL2's gamecontroller API was enabled with the 2.0.7 upgrade
> hardcoded one controller mapping at compile time (which was an upgrade from
> not being able to use it all in FNA games, reportedly also PPSSPP before that).
>
> SDL2 *should* however be able to map the controller layout at runtime based on
> 1) the SDL_GAMECONTROLLERCONFIG environment variable, and 2) files with
> controller layout specifications, in several applications called
> gamecontrollerdb.txt.
>
> The below diff adds the ability to assign controller mapping at runtime via the
> SDL_GAMECONTROLLERCONFIG env variable. It is a workaround because it is not
> clear yet where the upstream SDL2 code fails to achieve this. Reading mapping
> from file is not (yet) possible.
>
> The diff only changes a handful of lines (see below). I tested it completely
> remapping a Logitech Dual Action gamepad, including D-pad. The first 2 parts of
> the string (guid and device name) don't have any functional impact at this
> point when passed via the SDL_GAMECONTROLLERCONFIG.
>
> My suggested approach at the moment is using the port sdl-jstest to display the
> mapping string with 'sdl2-jstest -l', adjusting the buttons, axes, and dpad
> from there and pass it into the SDL_GAMECONTROLLERCONfIG environment variable.
>
> Empty SDL_GAMECONTROLLERCONFIG keeps default mappings. An invalid mapping
> string seems to disable the gamepad in the application based on my testing.
>
> Thanks.
>
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/devel/sdl2/Makefile,v
> retrieving revision 1.20
> diff -u -p -r1.20 Makefile
> --- Makefile 12 Jan 2018 19:32:54 -0000 1.20
> +++ Makefile 21 Jan 2018 23:40:12 -0000
> @@ -9,7 +9,7 @@ DISTNAME= SDL2-${V}
>  PKGNAME= sdl2-${V}
>  CATEGORIES= devel
>  MASTER_SITES= https://www.libsdl.org/release/
> -REVISION= 0
> +REVISION= 1
>  
>  SHARED_LIBS= SDL2 0.4 # 0.7
>  
> Index: patches/patch-src_joystick_SDL_gamecontroller_c
> ===================================================================
> RCS file: /cvs/ports/devel/sdl2/patches/patch-src_joystick_SDL_gamecontroller_c,v
> retrieving revision 1.1
> diff -u -p -r1.1 patch-src_joystick_SDL_gamecontroller_c
> --- patches/patch-src_joystick_SDL_gamecontroller_c 7 Jan 2018 22:56:46 -0000 1.1
> +++ patches/patch-src_joystick_SDL_gamecontroller_c 21 Jan 2018 23:40:12 -0000
> @@ -5,11 +5,12 @@ also disable checking string "Xbox 360 W
>  everything will be Xbox360 controller (works with generic joysticks)
>  - note: the actual Xbox360 controller has buttons and axes messed up on
>           openbsd with these mappings
> +map to SDL_GAMECONTROLLERCONFIG envvar if available
>  
>  Index: src/joystick/SDL_gamecontroller.c
>  --- src/joystick/SDL_gamecontroller.c.orig
>  +++ src/joystick/SDL_gamecontroller.c
> -@@ -884,15 +884,15 @@ static ControllerMapping_t *SDL_PrivateGetControllerMa
> +@@ -884,15 +884,21 @@ static ControllerMapping_t *SDL_PrivateGetControllerMa
>   #else
>       (void) s_pEmscriptenMapping;  /* pacify ARMCC */
>   #endif
> @@ -20,10 +21,17 @@ Index: src/joystick/SDL_gamecontroller.c
>  +        //if (SDL_strstr(name, "Xbox 360 Wireless Receiver")) {
>               /* The Linux driver xpad.c maps the wireless dpad to buttons */
>               SDL_bool existing;
> -             mapping = SDL_PrivateAddMappingForGUID(guid,
> +-            mapping = SDL_PrivateAddMappingForGUID(guid,
> ++    char guid_str[1024];
> ++            SDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));
> ++    if (SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG) == NULL) {
> ++    mapping = SDL_PrivateAddMappingForGUID(guid,
>   "none,X360 Wireless Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b11,dpright:b12,dpup:b13,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,",
>                             &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
>  -        }
> ++    } else {
> ++    mapping = SDL_PrivateAddMappingForGUID(guid, SDL_GetHint(SDL_HINT_GAMECONTROLLERCONFIG), &existing, SDL_CONTROLLER_MAPPING_PRIORITY_DEFAULT);
> ++    }
>  +        //}
>       }
>   #endif /* __LINUX__ */
>