godot: Right stick up-down input not working properly with Xbox Elite Wireless Controller Series 2

Godot version

v4.1.1.stable.official [bd6af8e0e]

System information

Godot v4.1.1.stable - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 4090 (NVIDIA; 31.0.15.3713) - 13th Gen Intel® Core™ i7-13700K (24 Threads)

Issue description

When I move right stick to right-top corner I expect to see Right Stick Up, but actual is Right Stick Down. I’ve tested controller in another games and programs and it works as expected.

Controller: Xbox Elite Wireless Controller Series 2 Connection type: wireless

upd. I’ve tested controller using wire and it works well, so problem with wireless only

Steps to reproduce

  1. Create inputs:

    • joy_look_up - Joypad Axis 3 (Right Stick Up, … - All Devices)
    • joy_look_down - Joypad Axis 3 (Rgith Stick Down, … - All Devices)
  2. Add simple debug info inside _process(delta):

# Debug info
if Input.is_action_pressed("joy_look_up"):
	print("up %f" % Input.get_action_strength("joy_look_up", true))
if Input.is_action_pressed("joy_look_down"):
	print("down %f" % Input.get_action_strength("joy_look_down", true))
  1. Move right stick to right-top and see down in chat (but expected up only)

Video Demo

Minimal reproduction project

controller.zip

About this issue

  • Original URL
  • State: closed
  • Created 9 months ago
  • Comments: 18 (8 by maintainers)

Most upvoted comments

Thanks for verifying!

Opened PR #82508

I’m wondering if there is something different going on between XInput and DirectInput in Windows. SDL has two separate GUIDs for the Series 2 Elite controller, but Godot has just one. Also the Godot IID_XOneEliteWirelessGamepad matches the SDL GUID for ‘Xbox One Wired Controller’.

I have not tested this in XInput yet, but I found reports that it only works when the window is in focus, so maybe your controller, as wireless, is being processed as a Raw Device and not recognized by GUID, and then when switching focus it instead is going through the DirectInput library to process input.

Can you (@s-titov or @KarpDevStudio) compare the GUIDs you’re getting through Device Manager to those listed in Godot and SDL? I’m not sure exactly how to compare (should be able to from fields in Device Mananger, just not sure which exactly), and I’m not home at the moment, but I will check with my own controllers when I am.

If you can confirm the Elite Series 2 you’re using is not listed in Godot, then that might lead to something here. Also, are you able to compile Godot from source? You’ll need to in order to test a fix (adding the GUID if it’s missing), or otherwise someone will have to provide you a binary to test with.

Okay, got it. Here is my fork with the added XInput device, so you can build it from source if you’d like.

If not, here is one I built using the current 4.1.2 source, and here is the updated version with the added device ID. I’m including both in case there’s some oddity in what I used to build it (Visual Studio 2022 on Windows 11) and whatever the official release was built with, so if the update works, please verify that the one built from the original source does not work (as expected).

Well this is getting more interesting…I’m seeing two devices showing up in device manager for each controller, though that makes sense if one registers through XInput (as their name implies) and the other with DirectInput.

You can verify the VID_XXXX and PID_XXXX values in the Details tab for the device properties match with the MAKELONG(0x045E, 0x02FF values there.

I have three different models, and when connected with USB, all had VID_045E and PID_02FF for the XInput Compatible HID Device. Here’s what I got overall:

Model DeviceCategory DeviceName HID PID
1537 Xbox Peripherals Xbox One Controller 045E 02D1
1537 Human Interface Devices XInput compatible HID device 045E 02FF
1697 Xbox Peripherals Xbox One Controller 045E 02DD
1697 Human Interface Devices XInput compatible HID device 045E 02FF
1708 Xbox Peripherals Xbox One Controller 045E 02EA
1708 Human Interface Devices XInput compatible HID device 045E 02FF
1708 Human Interface Devices Bluetooth XInput compatible Input device 045E 02E0

Those are all listed in Godot. If they’re not all going through XInput, I don’t know if they should be listed for XInput, but then those also wouldn’t be used, assuming those values wouldn’t show through XInput.

When either of you get a chance, please verify the HID and PID values for your Elite Series 2. When wired, you’ll probably see it listed under Xbox Peripherals at the bottom of the list in Device Manager, as well as the generic XInput Compatible HID Device under Human Interface Devices. When connected wirelessly, you should see something like Xbox Controller under Bluetooth Devices which has a device ID (the Bluetooth MAC address), and then also a Bluetooth XInput compatible Input device under Human Interface Devices, which will have a normal VID and PID listed.

I’m also experiencing this with an Xbox controller using PopOS with 4.2 dev 5.

  1. With the wireless dongle using xone
  2. As well as the same model Xbox controller using xpadneo over bluetooth and wired.

The controllers work correctly in games over Steam and such.

It seems as though the input axis are being registered opposite where left and right on the right stick will output up and down and vice versa and also there is another axis being used for some reason for up and down. I only have one controller attached and the correct and expected joystick inputs are already set in the screenshots:

When I move the right stick…

To the right:

image

To the left:

image

Right stick up:

image

Right stick down:

image

Upon further testing, it actually appears that the issue only happens when the game window is selected, not when the node is selected as I thought. If you focus on any other window, even not the Godot editor, the game receives the joystick input properly. This goes for both my project and the fresh project I uploaded.

https://github.com/godotengine/godot/assets/91380170/535b11a8-8263-49bf-b5d8-29dd6208598d

I’ve also run into this issue using an Xbox Elite Controller in my project, but only wireless as mentioned. When plugged in, it behaves normally, but wireless, the vertical axis value seems to jump around wildly. Moving the same input maps for the joystick and code that I use to get the values into a fresh project also causes the same issue.

https://github.com/godotengine/godot/assets/91380170/d9ecfb6e-e312-4156-8e4e-5774bdd03c03

I’ve tried moving it from _Process to _PhysicsProcess and updating the controller to no avail. One additional weird thing I caught was that sometimes when I selected the node that had the script retrieving the value, it would begin to read those values properly. It wouldn’t do it every time, but I caught a video of it in my personal project and it did happen in this fresh project.

https://github.com/godotengine/godot/assets/91380170/f9f30831-4f86-4860-b7f6-50bd49826849

Here’s a ZIP file for the new project that should show everything from the first video.

GD Gamepad Test.zip

Of note, I don’t use any external software to modify my controller or any input mappings.

Have you tried the controller in a different program and confirmed it works there?

@AThousandShips Yes, I’ve played few games to test it before + you can check video, another program detects it correctly.

Which controller model are you using (and with which connection mode)? Try another controller and see if its mappings are correct.

@Calinou Xbox Elite Wireless Controller Series 2. I use it wireless. Unfourtanetly I don’t have another controller to test, but it works well in another programs and games.

Which controller model are you using (and with which connection mode)? Try another controller and see if its mappings are correct.