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

[macOS/iOS] Controller motion, adaptive triggers and touchpad support. #88590

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bruvzg
Copy link
Member

@bruvzg bruvzg commented Feb 20, 2024

Adds support for DualSense / DualShock 4 touchpad and gyroscope/accelerometer and DualSense adaptive triggers. As well as LED light color control and battery state info.

Modified demo project:
joypads_atrig.zip

@bruvzg
Copy link
Member Author

bruvzg commented Feb 21, 2024

Added support for adaptive triggers as well, updated demo: joypads_atrig.zip

@bruvzg bruvzg changed the title [macOS/iOS] Controller motion and touchpad support. [macOS/iOS] Controller motion, adaptive triggers and touchpad support. Feb 21, 2024
Copy link
Member

@Calinou Calinou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested locally (M1 Mac mini 2020 with macOS Ventura and wired DualSense), it works as expected. I can't test via Bluetooth since I'm having trouble connecting the DualSense on the Mac this way (it used to work).

Great work!

I can confirm 2-finger1 touchpad movement + button, LED color, sensors (accelerometer + gyro) and all adaptive trigger modes work as expected.

One issue I noticed is that if you set the adaptive trigger's "end" point (circled in red) to a value lower than the "begin" point, errors will be spammed in the console and the project freezes:

image

I suggest handling this in a more graceful way, such as clamping the "end" point value to be always at least equal to the "begin" point.

Another issue I noticed is that if you call this in _ready(), the project freezes on startup and a message is spammed in the console:

# Leave this uninitialized.
var joy_num

func _ready():
	Input.set_joy_light(joy_num, Color.CYAN)
2024-02-22 22:34:58.476 godot.macos.editor.arm64[1228:11807] -[JoypadData playerIndex]: unrecognized selector sent to instance 0x60002694c6c0
ERROR: NSException: -[JoypadData playerIndex]: unrecognized selector sent to instance 0x60002694c6c0
   at: run (platform/macos/os_macos.mm:778)

This also occurs if you set the light color after waiting a single frame:

func _ready():
	await get_tree().process_frame
	Input.set_joy_light(0, Color.WHITE)

However, the following works – wait 2 frames and call set_joy_light in each iteration of the loop:

func _ready():
	for i in 2:
		await get_tree().process_frame
		Input.set_joy_light(0, Color.MAGENTA)

It seems pretty sporadic as it'll sometimes occur but not always.

set_joy_light() behaves nicely when called in _process(), which can be used to create animations:

var counter = 0.0

func _process(delta):
	counter += delta * 6
	Input.set_joy_light(joy_num, Color(0.5 + sin(counter) * 0.5, 0.5 + cos(counter) * 0.5, 0))
dualsense_led_animation.mp4

Some questions:

  • Is there a way to query whether the controller supports acceleration, gyro, touchpad, LED colors and adaptive triggers so we can disable relevant UI settings when these aren't supported? While we can query based on whether the lowercased controller name contains dualshock 4 or dualsense, this won't work with third-party controllers that may support these features. We may need something like DisplayServer.has_feature() for controllers.
  • Should we provide calibration methods for accelerometer + gyro that automatically set the current values as an offset for future calculations? Or should this be left to the project developers? @JibbSmart might have an idea about this.

Footnotes

  1. I was today years old when I learned that the DualSense touchpad supports two inputs at once.

@bruvzg
Copy link
Member Author

bruvzg commented Feb 22, 2024

Is there a way to query whether the controller supports acceleration, gyro, touchpad, LED colors and adaptive triggers so we can disable relevant UI settings when these aren't supported?

It's possible (and checked internally), but not exposed, I'll add an extra function to get it.

Should we provide calibration methods for accelerometer + gyro that automatically set the current values as an offset for future calculations? Or should this be left to the project developers?

There's no OS calibration API, but probably can be implemented in Input.

@akien-mga
Copy link
Member

What's the status of the support for these features on other platforms? We should likely aim to have at least feature parity on desktop platforms.

@bruvzg
Copy link
Member Author

bruvzg commented Feb 22, 2024

I have not checked yet, our current Windows implementation is outdated (DInput/Xinput) and definitely won't have any support for this. But there's a new Windows 10+ API I'm planning to check (probably a good idea to implement it anyway). No idea about Linux (touchpad on DualSense control mouse, so there's some support).

@Calinou
Copy link
Member

Calinou commented Feb 23, 2024

No idea about Linux (touchpad on DualSense control mouse, so there's some support).

Full support for gyro and LED control can be implemented (perhaps adaptive triggers as well), but it'll likely require godotengine/godot-proposals#9000. Mouse control by the touchpad is done by the OS driver itself (it works regardless of the current application).

@JibbSmart
Copy link

JibbSmart commented Feb 23, 2024

Should we provide calibration methods for accelerometer + gyro that automatically set the current values as an offset for future calculations? Or should this be left to the project developers? @JibbSmart might have an idea about this.(#user-content-fnref-1-db9bb4b80f65287ee602c3124c645ef7)

Help with calibration would be great for developers who might otherwise shy away from attempting decent motion controls. I wouldn't be able to help directly at the moment, but my header-only library GamepadMotionHelpers can help with automatic calibration, manual calibration, gravity calculation, and world space and player space conversions, and it's all contained in one file so it's easy to include

@bruvzg
Copy link
Member Author

bruvzg commented Feb 23, 2024

Full support for gyro and LED control can be implemented (perhaps adaptive triggers as well), but it'll likely require

We probably only need the HIDAPI (subproject of SDL), not full SDL.

@JibbSmart
Copy link

JibbSmart commented Feb 23, 2024

We probably only need the HIDAPI (subproject of SDL), not full SDL.

It's true that it technically only needs hidapi or something like it, but SDL does some really handy stuff like converting co-ordinate spaces and units from different controllers to a common standard. This is a wheel that's tedious to reinvent, and doing so won't yield any advantages besides not having to have SDL, imo.

Edit: also, using SDL means automatic support for Switch controller motion controls as well

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.

4 participants