libretro / libretro/RetroArch

[xinput driver] binds not applied to correct controller port

Open
#12,436 10 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug: input bug: xinput input
Dominant language
C
Stars
14.1k
Forks
2.2k
Avg merge
7h 35m
Merged PRs (30d)
51

Description

The following input issues occur regardless of the core selected, and have persisted for at least the last 2 weeks (may be much longer).

I have been testing how RA handles up to 4 players (all wireless gamepads). Note that I use two DS4 controllers and emulate them as XBox 360 gamepads via DS4Windows. The other 2 controllers are XBox One gamepads. I am quite confident that the emulated gamepads are not casuing problems here, as I often see RA get muddled and swap controllers when I just test with my two XBox One gamepads.

Description

RA gets very confused about attached XInput devices when the Input Driver is set to XInput and multiple gamepads are attached (only tested with all wireless gamepads). I have been testing this extensively in recent weeks and will happily elaborate and perform further testing.

360 gamepads often get confused for XBox One gamepads. i.e. When one looks at the 'Port X Controls' screen, the Device Index may state that a player is assigned to a 360 pad, but by attempting to bind buttons, one realises that player is in fact assigned to an XBox One controller. The opposite can happen just as frequently.

Sometimes, a gamepad that is marked as the first instance (e.g. "Controller (XBOX 360 for Windows)(#1)") in RA is fact the #2 gamepad, and vicaversa.

In other words: RA seems to toss a coin each time it tries to assign a gamepad to a user, such is the randomness.

Expected behavior

Two things:

  1. I certainly do not expect the XBox One and XBox 360 devices to get mixed up, but this happens more often than not and is not just a superficial / visual error. I will often go into, say, 'Port 2 Controls' and see that 'Device Index' is set as an XBox 360 controller. But - when I try to bind the controls to verify this - I notice that it is in fact bound to an XBox One gamepad, or even the other 360 gamepad. There is no rhyme or reason to how these devices are polled, and they are consistently muddled up.

  2. I would expect the devices to be mapped in either DInput order (the order they appear in the Windows' 'Game Controllers' tool (joy.cpl), or by XInput UserIndex order. As one scrolls through the 'Device Index' in a 'Port X Controls' screen, they do indeed appear to be in DInput order, but gamepads are very quickly shown to be in an unexpected order as soon as one starts binding individual buttons.

Actual behavior

360 gamepads often get confused for XBox One gamepads.

Sometimes, a gamepad that is marked as the first instance (e.g. "Controller (XBOX 360 for Windows)(#1)") in RA is fact the #2 gamepad, and vicaversa.

The assignment of XInput devices to players literally seems random.

Steps to reproduce the bug

From a 'cold start' (i.e. all gamepads should be switched off and Retroarch not started), do the following:

  1. Connect 2x XBox One gamepads wirelessly, and 2x DS4 gamepads wirelessly (via DS4Windows). (Obvioulsy - doesn't have to be this exact combination, but multiple XInput gamepads are needed).
  2. Launch a 4 player game (say, Mario Kart 64 on Mupen64 plus core).
  3. Go into Settings > Input > and look through the 'Port X Controls' for each player.

More often than not, at least 2 of the controllers will be muddled up (a 360 might appear as an XBox One, or the gamepad you'd expect to be player #1 is in fact player #2 etc). This can be shown to be the case by trying to bind keys for each of the 4 players: you will often find that keys from the expected gamepad are not registered, and that another controller is in fact being detected.

You can repeat the above steps multiple times, and if the gamepads get added by Windows in a slightly different order (as can easily happen with DInput) as they are switched on, the result when binding keys in RA will show different gamepad mapping once again.

Bisect Results

I have tried all sorts trying to figure out how gamepads are assigned in RA when the XInput driver is selected. I have been able to rule out:

  1. DInput ordering (the order gamepads appear in the Windows 'Game Controllers' tool).
  2. XInput UserIndex ordering.
  3. Raw Input / HID ordering.
  4. Any form of alphabetical ordering, be that by HID device path name (e.g. "\\?\hid#vid_045e&pid_028e&ig...'') or pid + vid combinations, etc.

Thanks for reading. I'm keen to get to the bottom of this. My hope is to reach a stage where I can be sure how gamepads will be assigned to players and write scripts to automatically set the configuration files for 'input_player1_joypad_index' through to 'input_player4_joypad_index'.

Version/Commit

RA 1.9.3 stable. All cores tested were updated in last 24 hours.

Environment information

Windows 10, x64.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the issue through Settings > Input > Port X Controls with four wireless XInput gamepads, using the XInput input driver and the described Mupen64 Plus scenario. Compare each displayed Device Index with the controller that receives a binding; done means controller-to-port assignments are deterministic and match the documented ordering expectation.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
desktop, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
42/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.