GML Why doesn't this gamepad code read these buttons?

hogwater

Member
This is from the step event of a "button listener" object used for a controller config option. It's intended to recognize buttons 0-17 on the pad, then drop those values into variables. It works well for most pads I have.

However with the wired Hori Switch Pro Controller, I can't get anything from the dpad or the Y button.

Using https://gamepad-tester.com/ I see the dpad as buttons 12-15, and the Y button as button 2. The gamepad setup utility in Windows 10 sees the dpad as pov hat directions, and the Y button as button 1.

Wat do?

Code:
/// @description listen for buttons and grab the one pressed

if gamepad_button_check_pressed(global.player1,0)
{
global.listener_button = 0;
global.display_gbutton = "Dpad Up"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,1)
{
global.listener_button = 1;
global.display_gbutton = "Dpad Down"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,2)
{
global.listener_button = 2;
global.display_gbutton = "Dpad Left"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,3)
{
global.listener_button = 3;
global.display_gbutton = "Dpad Right"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,14)
{
global.listener_button = 14;
global.display_gbutton = "X"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,12)
{
global.listener_button = 12;
global.display_gbutton = "A";
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,15)
{
global.listener_button = 15;
global.display_gbutton = "Y"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,13)
{
global.listener_button = 13;
global.display_gbutton = "B"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,8)
{
global.listener_button = 8;
global.display_gbutton = "LB"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,9)
{
global.listener_button = 9;
global.display_gbutton = "RB"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,10)
{
global.listener_button = 10;
global.display_gbutton = "LT"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,11)
{
global.listener_button = 11;
global.display_gbutton = "RT"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,5)
{
global.listener_button = 5;
global.display_gbutton = "Select"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,4)
{
global.listener_button = 4;
global.display_gbutton = "Start"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,6)
{
global.listener_button = 6;
global.display_gbutton = "LS"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,7)
{
global.listener_button = 7;
global.display_gbutton = "RS"
instance_destroy();
}

//extras just in case

if gamepad_button_check_pressed(global.player1,16)
{
global.listener_button = 16;
global.display_gbutton = "B 16"
instance_destroy();
}

if gamepad_button_check_pressed(global.player1,17)
{
global.listener_button = 17;
global.display_gbutton = "B 17"
instance_destroy();
}
 

hogwater

Member
OK scratch the Y button. But I am confused about how to use the pov hat functions in order to grab a "button" that corresponds with each direction.
 

Evanski

Raccoon Lord
Forum Staff
Moderator
So game maker and switch controller are kinda of a tricky thing, @Samuel Venable was running into issues with them as well, from what I personally understand (i dont have a switch license and I havent signed a NDA) so Im going to speak freely about what I know/assume
The switch controller doesn't work natively with game maker, which sort of make sense if you think about it as the only thing the switch controller is "made for" is the switch, where as other controller dual work for pc/console

I think an easy why around this is to have a blank project and have gamemaker tell you the value it receives from each individual button press, this would be magic numbers but assuming it works after a cache clear and compiling it would work.

I might be 99% wrong about all of that but, its worth a shot to try my suggestion. maybe Samuel knows more then I though
 

hogwater

Member
GM sees the dpad as buttons 14-17 based on a GM pad tester tool. In any case, this would be covered by my code. POV Hats could be the issue, but as I said I don't see how I can use the functions available to store the directional press as a button.

I wrote this input system quite a while ago, before the gamepad mapping functions existed. I'm excited to have that functionality, but I'm not sure if they will solve this issue.
 

kburkhart84

Firehammer Games
As far as I know, Gamemaker uses SDL under the hood except for XInput devices. It is possible that SDL is not supporting this thing, as I've seen other people have issues as well. I also seem to remember someone mentioning that the stuff would show up in the Windows control panel, but that the inputs weren't actually working there, and were rather glitchy and flashing the buttons instead of actually being responsive.

Another thing, not sure how much it would help...but you mention that Windows is reading part of it as a POV hat...none of your code is reading a POV hat. There is a separate function for that, and it doesn't working the same as the buttons do, rather the value is a bit-wise combined group of flags that tell you what direction it's pointed/tilted. You will need to read the function in the manual.
 

hogwater

Member
OK, so I'm on my way to a solution.

Using https://www.generalarcade.com/gamepadtool/ this tool I was able to create a mapping for the Switch controller, and after loading that with gamepad_test_mapping I got the dpad buttons working.

Is there a way to add my newly created mapping to the database GM2 comes with? Or is each mapping that I have to create myself going to be a new edge case for the async event that I need to check for by GUID?
 

kburkhart84

Firehammer Games
OK, so I'm on my way to a solution.

Using https://www.generalarcade.com/gamepadtool/ this tool I was able to create a mapping for the Switch controller, and after loading that with gamepad_test_mapping I got the dpad buttons working.

Is there a way to add my newly created mapping to the database GM2 comes with? Or is each mapping that I have to create myself going to be a new edge case for the async event that I need to check for by GUID?
If SDL is indeed picking up ALL of the buttons and axes(making it viable for actual use), then you could submit it to Yoyogames. Maybe they could add it to the SDL gamepad database code page they have. I'm not seeing any other way to do it.

Were you not able to check the thing using the built-in POV Hat functions?! They work just fine for controllers that I know have them in my experience.
 
If SDL is indeed picking up ALL of the buttons and axes(making it viable for actual use), then you could submit it to Yoyogames. Maybe they could add it to the SDL gamepad database code page they have. I'm not seeing any other way to do it
seems it's only there for Linux and Android... But I wonder if it makes sense since Nintendo has no support whatsoever for Pro Controllers on Windows/Mac, according to their official forums.
050000000d0f0000f600000001000000,Wireless HORIPAD 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,platform:Linux,
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,platform:Android,
 

kburkhart84

Firehammer Games
seems it's only there for Linux and Android... But I wonder if it makes sense since Nintendo has no support whatsoever for Pro Controllers on Windows/Mac, according to their official forums.
That makes sense to me. I don't know of course, but since Microsoft is technically a direct competitor to Nintendo in the console field...maybe that has something to do with it. Remember that Playstation controllers have similar issues and require specific drivers to be installed to work on Windows, but IIRC those ALSO work normally on Linux and Mac(though not on Android last I heard).
 
That makes sense to me. I don't know of course, but since Microsoft is technically a direct competitor to Nintendo in the console field...maybe that has something to do with it. Remember that Playstation controllers have similar issues and require specific drivers to be installed to work on Windows, but IIRC those ALSO work normally on Linux and Mac(though not on Android last I heard).
Yep, maybe has to do with the buisness side of thing, who knows?
But really, you there's no shame in straight telling this guy to get your extension, my Switch Pro controller works perfectly with it, lol šŸ¤£
 

hogwater

Member
If SDL is indeed picking up ALL of the buttons and axes(making it viable for actual use), then you could submit it to Yoyogames. Maybe they could add it to the SDL gamepad database code page they have. I'm not seeing any other way to do it.

Were you not able to check the thing using the built-in POV Hat functions?! They work just fine for controllers that I know have them in my experience.
Well with pov_hat_count I see 1 hat, and with pov_has_value drawn to the screen I can see each direction functioning (displaying 1,2,4,8 for up, right, down, left respectively. I'm just not sure how to use that in the context of "detect button press, save button press to file for config."
 
Well with pov_hat_count I see 1 hat, and with pov_has_value drawn to the screen I can see each direction functioning (displaying 1,2,4,8 for up, right, down, left respectively. I'm just not sure how to use that in the context of "detect button press, save button press to file for config."
when you map, those 1, 2, 4, 8 numbers are the number after the dot (.) when you set them, like there:
dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1
Each value represents a direction, the first number (here 0), is the hat number.
 

kburkhart84

Firehammer Games
Well with pov_hat_count I see 1 hat, and with pov_has_value drawn to the screen I can see each direction functioning (displaying 1,2,4,8 for up, right, down, left respectively. I'm just not sure how to use that in the context of "detect button press, save button press to file for config."
You do them the same way you do with buttons, you just have to access it using different functions. In my input system(which saves action mapping), gamepads have axes, buttons, and POV hats...it's just another subset of input with a different function call. I'm sure you already have different calls for axes vs buttons, the POV hat is just another one in the list.
 
S

Sam (Deleted User)

Guest
So game maker and switch controller are kinda of a tricky thing, @Samuel Venable was running into issues with them as well, from what I personally understand (i dont have a switch license and I havent signed a NDA) so Im going to speak freely about what I know/assume
The switch controller doesn't work natively with game maker, which sort of make sense if you think about it as the only thing the switch controller is "made for" is the switch, where as other controller dual work for pc/console

I think an easy why around this is to have a blank project and have gamemaker tell you the value it receives from each individual button press, this would be magic numbers but assuming it works after a cache clear and compiling it would work.

I might be 99% wrong about all of that but, its worth a shot to try my suggestion. maybe Samuel knows more then I though
I never developed anything switch related.
 

hogwater

Member
Well, for example I have a persistent obj_input. In its step event I poll inputs like this:

Code:
up = gamepad_button_check_pressed(global.player1,global.gup) ||
     gamepad_axis_value(global.player1,gp_axislv) <= -.25 ||     //not user customizable or actually a "pressed" variant
     keyboard_check_pressed(global.kup) ||
     gamepad_hat_value(global.player1,0) == 1;     //not user customizable or actually a "pressed" variant
And my buttons are defined in the option button mapping screen with a "listener object" like so:

Code:
if gamepad_button_check_pressed(global.player1,0)
{
global.listener_button = 0; 
global.display_gbutton = "B0"
instance_destroy();
}
However I have no idea how to say something like this properly:

Code:
if (gamepad_hat_value(global.player1,0) == 1)
{
global.listener_button = what_goes_here?; 
global.display_gbutton = "dpad up"; 
instance_destroy();
}
 

kburkhart84

Firehammer Games
The way I handle this all in my input system is simply to handle the cases separately. So internally, I basically have a index for every possible input supported for these devices. My variable holds that index, and the code that actually checks it uses it to know what kind of input to check(which function to call). There is no reason to not let the user use all of these with no limitations.

It's different for XInput devices, but for other types(DInput devices), it works like this in my system. There are 10 supported axes. I handle all of them(though there is not likely going to be a device with this many axes, you never know). So if the input is between 0 and 19, that's an axes. I handle two directions as if they were separate, even though they are the same axis.

These devices support up to 32 buttons in theory...so I check all of those as well. The input variable ranges from 20 to 51 for those buttons(which are buttons 0 -31).

Finally, these devices support up to 4 POV hats, each one capable of 8 directions(or only 4 in some cases). So for inputs 52 through 59, I check POV Hat 0, the next 8 are POV Hat 1, and so on.

So, my system stores both the gamepad ID, and in the case of DInput IDs, it has a variable that ranges from 0 to 83. 0 - 19 are for axes, 20 to 51 for buttons, and 52 to 83 for the 4 POV hats. Depending on which range the variable is determines which function I'm using to actually check the input. And which actual value within the range it is determines what actual specific thing I'm checking(whether it's the X+ axes, the Z- axis, or for the POV Hats which direction, and so on).

Note that one difference in my case as compared to yours...my code is not having multiple inputs be applying to a single action. It is set up for single inputs to single actions. If you wanted to support multiple things being applied, you could easily just double the actions, and check for either/or on both separate actions. Another difference in my system is that I'm letting the user map basically anything they want to the actions. I'm not forcing any defaults at all. They could easily use shoulder buttons instead of the X/Y axes for movement if they so desired. I'm making a default mapping(which is on the keyboard since not everybody even has gamepads), and then through the options menu, the player can do like in many games, click a button(which prompts them to hit the new input the want for some action, like jumping), then they hit the new button, and it gets assigned to the action.

Supporting DInput devices is slightly more complicated than the XInput devices...but in reality, even XInput devices have both buttons and axes(just no POV Hats). This means that for both cases, you still have to account for all of them.
 
Top