Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HTML5] Use internal implementation of the Gamepad API. #45078

Merged
merged 2 commits into from
Jan 18, 2021

Conversation

Faless
Copy link
Collaborator

@Faless Faless commented Jan 10, 2021

In this PR:

  • Better gamepad axis event injection (see first commit details).
  • Custom Gamepad library to allow remapping.

No longer use emscripten functions for gamepads, implement them as library functions in library_godot_display.js instead.
This allows us to do a better job at "guessing" vendorId, productId, OS, etc. thus allowing us to better identify the remapping needed for the attached controller (when the browser does not apply the standard remapping).

In general, browser are supposed to remap joypads to a default mapping. Browsers do that for famous controllers (official xbox/PS, usually on windows) but most others controllers have unusable mappings.
For this reason, we should start generating unique IDs for them when possible, mapping controllers like done in godotcontrollerdb.txt .

To my research, controller mapping varies per OS but not per browser (with the exception of not all browsers doing the standard remapping).

For this reason I'm asking the community to try the following demo, and if the gamepad is not recognized correctly try to remap it: https://no-war.fales.me/joy/

How to remap:

  • Open the web page, connect your gamepad and press a button.
  • The text top-right of the screen should show it's detected name and ID.
  • If the name is Standard Gamepad Mapping and the ID is standard, it should work out of the box, if it doesn't, it's likely a browser issue, or a driver issue.
  • If the name/ID are something else, first check the current mapping works comparing with the on-screen controller image. If it works you're gold
  • If the current mapping does not work (e.g. wrong buttons/axes), you can try remapping it:
    1. Press the Remap button at the bottom right of the screen
    2. Either use a well-known mapping (only xbox for now), or start the Wizard.
    3. Follow the wizard instructions, at the last step you will be prompted with the remap string. Copy it, test that the controller now works fine (don't refresh the page!) and send it to us (e.g. here as a comment, or on IRC).

Note

Some controllers will have axes values that are outside the [-1, 1] range. That's a bug in the browser, since that's not conformant with the standard, and you won't be able to remap them correctly See here:

All axis values MUST be linearly normalized to the range [-1.0 .. 1.0].

Fixes #39253 .
Will need proper mapping for #32831

@Faless Faless added this to the 4.0 milestone Jan 10, 2021
@Faless Faless marked this pull request as draft January 10, 2021 15:35
@Faless
Copy link
Collaborator Author

Faless commented Jan 10, 2021

I really need to add the git hook for JS linting :)

@snougo
Copy link

snougo commented Jan 11, 2021

on FireFox
standard,Standard Gamepad Mapping,a:b1,b:b2,y:b5,x:b3,back:b8,leftstick:b11,leftshoulder:b5,rightshoulder:b8,dpup:b12,dpleft:b14,dpdown:b13,dpright:b15,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Javascript

on Safari
MacOSX045e02fd,45e-2fd-Xbox Wireless Controller,a:b0,b:b1,y:b4,x:b3,start:b11,leftstick:b13,rightstick:b14,leftshoulder:b6,rightshoulder:b7,leftx:a0,lefty:a1,rightx:a2,righty:a3,platform:Javascript

on chrome, default setting just woks perfectly, every button is right, but remapping window is not working
屏幕快照 2021-01-11 15 08 33

@Faless
Copy link
Collaborator Author

Faless commented Jan 11, 2021

@snougo woah, I'm so glad I found someone to make mappings on OSX. Thanks a lot 🥇 !
I'll add it to the known mappings and check what's wrong on chrome with the viewport/remap window,

@Faless
Copy link
Collaborator Author

Faless commented Jan 11, 2021

Added MacOSX045e02fd to godotcontrollerdb.txt. That controller should work out of the box on Safari too now.

@snougo
Copy link

snougo commented Jan 12, 2021

Added MacOSX045e02fd to godotcontrollerdb.txt. That controller should work out of the box on Safari too now.

right now, the default setting works fine in most button on Safari, but back button/DPad button/LT/RT still can't be recognized. on FireFox the default setting still works badly and after remapping these button(select/LT/RT/rightstick pressed) still can't be recognized or will be recognized as the same joystickList int

@Faless
Copy link
Collaborator Author

Faless commented Jan 12, 2021

right now, the default setting works fine in most button on Safari, but back button/DPad button/LT/RT still can't be recognized

Oh, I see, the mapping provided above seem wrong. It's missing dpads, etc. Can you try again remapping on Safari?

EDIT: Missing values are: back (select) dpup,dpleft,dpright,dpdown (dpad) and lefttrigger,righttrigger (LB/RB). Maybe you accidentally skipped them when remapping?

on FireFox the default setting still works badly

As mentioned, that's likely a browser issue. "Standard" gamepad are supposed to be remapped according to the specs. If the browser maps it as standard but does not follow the spec, it's a browser bug, and should be reported upstream, we can't do anything to fix that. You can also check here if the standard mapping is working correctly on Firefox, but given it doesn't in godot, it will likely be wrong there too, as other "standard" mapped controllers work fine.

In the core input handling code we have checks to make sure that if axis
rapidly change sign we inject mid-points to release any pending inputmap
action.

The function though, did not correctly insert the mid-point causing
dpads mapped to an axis that behaves like tri-state buttons (-1,0,1) to
not be released correctly.

This commit fixes that by including in the check the case where the axis
swtiches from abs(1) to 0.
No longer use emscripten functions for gamepads, implement them as
library functions in library_godot_display.js instead.
This allows us to do a better job at "guessing" vendorId, productId, OS,
etc. thus allowing us to better find the remapping for the controller.
@Faless
Copy link
Collaborator Author

Faless commented Jan 18, 2021

Ready now. Also added a bunch of controllers for OSX,

After a lot of testing, across different OSes and different browsers, I think this is as good as we can get.

Known issues

  • Some browsers still remap some controllers as "standard" but with the wrong mapping. This is a browser issue, and should be reported upstream.
  • Some controllers, on some browsers, returns non-normalized raw values for axis (outside the range [-1,1]). This is against the specification. Again, probably something to be reported upstream.
  • Some browsers will remap some controllers with the "standard" mapping, but will not correctly set mapping = "standard". Once more, this behaviour is discouraged by the spec. And should be reported upstream to see what valid reasons they come up with for not following the recommendation.

Popular browser issue trackers:

@akien-mga akien-mga merged commit 869f5b5 into godotengine:master Jan 18, 2021
@akien-mga
Copy link
Member

Thanks!

@antartica
Copy link

antartica commented Feb 4, 2021

Fixed mappings for Razer Wolverine Ultimate (XBox-style gamepad):

Firefox Linux 78.7.0esr (64-bit):
Linux15320a14,1532-0a14-Generic X-Box pad,a:b0,b:b1,y:b3,x:b2,start:b7,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript

Chromium Linux 87.0.4280.141 (64-bit): (DOESN'T DETECT CLICKING ON "RT")
Linux15320a14,Razer Razer Wolverine Ultimate (Vendor: 1532 Product: 0a14),a:b0,b:b1,y:b3,x:b2,start:b7,back:b6,leftstick:b9,rightstick:b10,leftshoulder:b4,rightshoulder:b5,dpup:-a7,dpleft:-a6,dpdown:+a7,dpright:+a6,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,platform:Javascript

Fixed mappings for iBuffalo BSGP801 classic USB gamepd (SNES-style gamepad):

Firefox Linux 78.7.0esr (64-bit):
Linux05832060,0583-2060-USB,2-axis 8-button gamepad ,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript

Safari MacOS 14.0.2:
MacOSX05832060,583-2060-USB,2-axis 8-button gamepad ,a:b1,b:b0,y:b2,x:b3,start:b7,back:b6,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript

Fixed mappings for HuiJia SNES USB adapter with original SNES gamepad:

Firefox Linux 78.7.0esr (64-bit):
Linux0e8f3013,0e8f-3013-HuiJia USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript

Chrome Windows 80.0.3987.149 (64-bit):
Windows0e8f3013,USB GamePad (Vendor: 0e8f Product: 3013),a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript

Firefox Windows 85.0 (64-bit):
Windows0e8f3013,0e8f-3013-USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a1,dpleft:-a0,dpdown:+a1,dpright:+a0,platform:Javascript

Firefox Mac 85.0:
MacOSX0e8f3013,e8f-3013-USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a4,dpleft:-a3,dpdown:+a4,dpright:+a3,platform:Javascript

Safari MacOS 14.0.2:
MacOSX0e8f3013,e8f-3013-USB GamePad,a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b6,rightshoulder:b7,dpup:-a4,dpleft:-a3,dpdown:+a4,dpright:+a3,platform:Javascript

@madacol
Copy link

madacol commented Mar 21, 2021

Firefox
Linux046dc216,046d-c216-Logitech Logitech Dual Action,a:b1,b:b2,y:b3,x:b0,start:b9,back:b8,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:-a5,dpleft:-a4,dpdown:+a5,dpright:+a4,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Javascript

But on Chrome is recognized as Standard and works just fine

@levhita
Copy link

levhita commented Jun 21, 2021

MaCOSX, Google Chrome NEXT Snes controller

MacOSX00790011,USB Gamepad (Vendor: 0079 Product: 0011),a:b2,b:b1,y:b0,x:b3,start:b9,back:b8,leftshoulder:b4,rightshoulder:b5,dpup:-a1,dpleft:-a1,dpdown:+a1,platform:Javascript

@nyxkn
Copy link

nyxkn commented Oct 3, 2022

This is for a PS3 Dualshock (054c:0268). It works just fine on Linux and Chrome-browsers, but has wrong mappings on Firefox.

This is the correct mapping for Firefox from the Joypads Demo:
Linux054c0268,054c-0268-Sony PLAYSTATION(R)3 Controller,a:b0,b:b1,y:b2,x:b3,start:b9,back:b8,leftstick:b11,rightstick:b12,leftshoulder:b4,rightshoulder:b5,dpup:b13,dpleft:b15,dpdown:b14,dpright:b16,leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2,righttrigger:a5,platform:Javascript

This mapping string also matches the one loaded by default by SDL.

@Faless Faless deleted the js/4.x_gamepads branch October 3, 2022 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Xbox Gamepad Mapping Incorrect in Firefox HTML5 Export
7 participants