SDL Game controller button mapping issue

I’ve ben working with Generic USB Controllers & vJoy virtual controller on my application. Lately I bought an PS4 Wireless controller but it seems some mapping/binding characterictics are differerent regarding button mapping.

My purpose is to have 1-1 button and axes mapping with physical and virtual controller, say when I press button no X on physical, virtual should also behave as if button X is pressed and I validate this behaviour by using PES 2016 conttroller visualisation tool (see last image).

I’m using SDL_GameControllerGetBindForAxis() and SDL_GameControllerGetBindForButton() functions to decide mapping of each physical controller. This is an example mapping image I get from one of these Generic controllers.

Button0 => Bind Button 2
Button 1 => Bind BUtton 1
Button 2 => Bind Button 3
Button 3 => Bind Button 0

As my understanding, this mapping means the corresponding (vJoy) button number when SDL_GameControllerGetButton() method is called. For example if I call SDL_GameControllerGetButton(controller, (SDL_GameControllerButton)0),I read the button value at index 0 which means button_2, because of button mapping(see image above). Since 0 maps to 2, I command vJoy controller button 2 to be high. With this method, all of my generic controllers were working fine even if they have different mappings.

The issue is My PS4 controller returns 1-1 mapping for buttons, which means after calling SDL_GameControllerGetBindForButton() for each button I get this:
Button0 => Bind Button 0
Button 1 => Bind Button 1
Button 2 => Bind Button 2
Button 3 => Bind Button 3

I try what I did with generic ones but buttons are scrambled this time. They are not corresponding to same buttons. I suspect SDL or my mapping method is source of the problem because buttons are 1-1 identical on PES 2016 controller when I press PS4 physical buttons. e.g when I press Triangle, Button Y is highlighted (because controller is XBox image, Triangle => Y) and it corresponds to button 3, which is correct… Same for the rest… This means PES tool can understand controler inputs correctly, while SDL & 1-1 mapping method generates incorrect mapping.

My validation method is like this: I use PES 2016 Controller visualisation tool.
I switch controller between physical and virtual ones through combobox and observing if same buttons are highlighted when I press one of the buttons of physical controller.

You shouldn’t need to do any kind of mapping between SDL gamepad input and virtual gamepad output. Assuming that all of the buttons and axes are present on both the real and virtual controllers, you can pass the gamepad buttons and axes directly to the virtual controller without any remapping.

e.g. SDL_JoystickSetVirtualButton(virtual_joystick, event.cbutton.button, event.cbutton.state);

Hi. Thanks for quick response.
I tried that but it seems not working in that way.

As my understanding, that button mapping describes input&output relation. If you want to do some processing on “Button0”, you should find which input button mapping mapping maps to Button 0 and then use that input value for processing. If “input button2” => BindedTo(Button0), then you should do stuff with “input button2”, at the end you should send it as button0. I’m not certain but this is how I managed 1-1 mapping with generic controllers.

Issue could be related with gamecontrollerdb.txt. I played with that file and it effects button mappings of my controller. Also the reason why I get 1-1 mapping is my controller entry cannot be found inside this file… However I couldn’t find correct mapping for my controller even by using sdl-gamepad-mapper.

I think Controller mappings changes the index<=>button correspondance (it might be mapping’s purpose already)

With a generic USB controller, this is what I get as controller input by using SDL

A => 0 (When I press A on physical controller, I get corresponsing result at index 0)
B => 1 (When I press B on physical controller, I get corresponsing result at index 1)
X => 2 (When I press X on physical controller, I get corresponsing result at index 2)
Y => 3 (When I press Y on physical controller, I get corresponsing result at index 3)

Since this is the result of button states with a corresponding controller mapping, I think I’m receiving this result ordered because SDL already filters/reorders it before I read the inputs. I’m saying that way because when I use PES or Windows’s visualisations, I get this result:

A => 2 (When I press A on physical controller, I get button 2 as pressed)
B => 1 (When I press B on physical controller, I get button 1 as pressed)
X => 3 (When I press X on physical controller, I get button 3 as pressed)
Y => 0 (When I press Y on physical controller, I get button 0 as pressed)

(In the image, buttons are starting from 1 not 0, I’m pressing X which highlights button 4)


Can I read button/axis values as raw (as windows case), even though there is a corresponsing mapping found inside SDL?