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

udev and SDL Sensor and Touchpad #16188

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open

Conversation

oshaboy
Copy link

@oshaboy oshaboy commented Feb 2, 2024

Description

Implemented Sensor and Touchpad Support for SDL and udev.

Related Issues

#16162

Reviewers

@gouchi @warmenhoven

Known Issues with the pull request

  • No Wiimote support yet.
  • Everything is hardcoded and not adjustable by the user. Which causes problems if an unrelated device such as a mouse takes device 0. Also if you swap the gamepads
    • Only the axes are hardcoded now.
    • SDL Device selection doesn't work.
  • Requires UDEV_TOUCH_SUPPORT to be enabled.
  • Untested with multiple Dualshock 4s/Dualsenses

@oshaboy
Copy link
Author

oshaboy commented Feb 2, 2024

The checks failed due to the UDEV_TOUCH_SUPPORT not being defined.

I'm not really sure what to do should I add a UDEV_SENSOR_SUPPORT macro for the sensor code?

@gouchi
Copy link
Member

gouchi commented Feb 2, 2024

To make some test

git clone https://github.com/libretro/RetroArch.git
cd RetroArch
git fetch origin pull/16188/head:pr16188
git checkout pr16188
./configure && make -j$(nproc)

@LibretroAdmin
Copy link
Contributor

You need to fix the failing CI tasks

@oshaboy
Copy link
Author

oshaboy commented Feb 2, 2024

Will do

@LibretroAdmin
Copy link
Contributor

Linux x86 pipeline still failing.

@gouchi
Copy link
Member

gouchi commented Feb 3, 2024

Linux x86 pipeline still failing.

It seems that sensor API has been introduced in SDL version 2.0.9. And we are using SDL 2.0.4 for the CI as we are building under Xenial.

@oshaboy
Copy link
Author

oshaboy commented Feb 3, 2024

Even if the build succeeds I don't want the pull request merged yet.

It works adequately now for testing but to be usable I need to add a lot of options to adjust sensitivity and mapping. The problem is RN the retropad stack assumes there's only one set of sensors... safe assumption to make on mobile. Not so much with sensor enabled controllers.

An example is that on the dualsense is the way it's set up by default you have to point the shoulder buttons up. Most people play games with the face buttons pointing up so it makes playing extremely unintuitive.

I only made the pull request so people will be aware that I am working on it and maybe get some more testing on it. Please don't merge it until it's complete.

@warmenhoven
Copy link
Contributor

You can tell GitHub to mark the PR as a draft, which will prevent it from being merged until you tell it that it's ready for review.

@oshaboy oshaboy marked this pull request as draft February 3, 2024 15:36
Cleanup
Sensitivity settings and Sensor Retropad selection implemented including menu options
@gouchi
Copy link
Member

gouchi commented Feb 3, 2024

I confirm DS4 is working with udev driver.

  1. Enable Auxiliary Sensor Input in Settings Tab > Input.
    auxiliary-sensor-input

  2. Select correct Sensor in Settings Tab > input > RetroPad Binds > Port 1 Controls > Sensor Index

sensor-index

If needed, you can adjust Sensivity in Settings Tab > Input > Gyroscope Sensitivity

sensivity

@LibretroAdmin
Copy link
Contributor

CI Linux (i686) still fails. Is SDL_Sensor only available on specific SDL versions? Can we have a compile-time ifdefs for this?

@gouchi
Copy link
Member

gouchi commented Feb 4, 2024

It seems there is a macro SDL_VERSION_ATLEAST so we could use SDL_VERSION_ATLEAST(2,0,9).

@oshaboy
Copy link
Author

oshaboy commented Feb 4, 2024

I was going to say that maybe we should drop support for ancient versions of SDL2, but turns out SDL 2.0.9 released in 2018 so it isn't that old.

@gouchi
Copy link
Member

gouchi commented Feb 4, 2024

but turns out SDL 2.0.9 released in 2018 so it isn't that old.

I am confused the release date indicates May 24, 2022 ?

Source

@oshaboy
Copy link
Author

oshaboy commented Feb 5, 2024

Idk the tags tab says 2018. But when you click on it it says 2022.

Maybe they have been pushing commits to it until then.

https://github.com/libsdl-org/SDL/tags?after=release-2.0.18

Edit: I found https://www.phoronix.com/news/SDL-2.0.9-Released confirming it's from 2018.

@oshaboy
Copy link
Author

oshaboy commented Apr 22, 2024

So someone on discord told me I should open the pull request at this state without the menu options. And then either future me or someone who knows their way around the menu code can implement it.

Right now it's functional in both udev and SDL but the axes aren't where the software expects them. So in Kirby: Tilt N Tumble for example requires you to hold the dualshock horizontally when the game boots and tilt backwards to move forwards.

However it does work and there are even menu options to adjust sensitivity and select which sensor device you want to use so I think it's adequate.

@oshaboy oshaboy marked this pull request as ready for review April 22, 2024 21:47
@zoltanvb
Copy link
Contributor

the axes aren't where the software expects them

I am working on extending remote retropad with sensor test display, and have found something similar in the only platform that I can test right now, Android. Will try to check again and see if it matches the udev behavior described above.

Also, since sensor input is part of the input driver (as opposed to the joypad driver), one will not be able to change the input driver to udev/sdl in a Linux desktop environment, since video context driver will force it to be x/wayland. Probably joypad driver stack could be extended to have sensor capabilities, and input driver could have the option to let the joystick driver handle it in cases where it is reasonable.

@oshaboy
Copy link
Author

oshaboy commented Jun 30, 2024

the axes aren't where the software expects them

I am working on extending remote retropad with sensor test display, and have found something similar in the only platform that I can test right now, Android. Will try to check again and see if it matches the udev behavior described above.

I have spoken about the issue at length. I have tried giving the user the ability to change the axis mappings but the menu code is a superfund site.

Also, since sensor input is part of the input driver (as opposed to the joypad driver), one will not be able to change the input driver to udev/sdl in a Linux desktop environment, since video context driver will force it to be x/wayland. Probably joypad driver stack could be extended to have sensor capabilities, and input driver could have the option to let the joystick driver handle it in cases where it is reasonable.

Well it works fine within Mate as long as you set your gamepad permissions right. I would love a way to set a distinct input driver for the joypad and keyboard/mouse because I really don't feel comfortable exposing the udev device of my keyboard to non-root apps because I use this computer for things other than Gaming. But that would require, you guessed it, changing menu code.

@zoltanvb
Copy link
Contributor

I correct myself: x11 context + udev works, other combinations probably not.

That game starts with instruction to hold the device flat, on Android it is consistent with that (i.e. no need to hold the phone upright), but will not adjust if the phone is rotated to landscape, which is an interesting challenge, I can not think of an interface how the core would be aware of that (except via the sensors themselves).

@oshaboy
Copy link
Author

oshaboy commented Jul 5, 2024

I can not think of an interface how the core would be aware of that (except via the sensors themselves).

The same way everything else is mapped. You give the user gamepad mapping files. That's what the RetroPad abstraction is for. I just need help to actually implement it.

@rcampbel3
Copy link

I'm excited to discover this pull request and eager to see it continue to be developed and merged. No longer is the ideal controller an XBOX 360 controller. SDL has great support now for more complex HID devices. Citra is an excellent example of an app that takes full advantage of the new SDL capabilities. Ultimately, what I'd really like to see in retroarch are sane defaults for DS4 and DS5 controllers and Joy-Cons that include gyro controls. Mobile device gyro controls should be supported and configured out of the box too.

Then, I'd love to see a steam input style customization and configurtion tool that can 1) support sane default configs that are auto-detected, 2) support widely desirable community custom configurations per platform that normalize input to an extended Analog+gyro retropad 3) provide ability to use a GUI mapping tool to create and save multiple custom control configurations including gyro and button/input chording 4) provide a way to share community configurations 5) support global system configs, platform configs, and per-game configs

Also, we need a better way to allow a system's game library to have optimal default controls that are configured differently per game in advance. For example, mapping wii controls to a DS4/DS5 and all the different combinations of wiimote / wiimote rotated / wiimote plus / wiimote plus rotated, Wiimote plus nunchuck, wii controller, gamecube controller. It should be possible for a team to define and preconfigure optimal analog+gyro retropad settings per game as defaults given common controllers like xbox, ds4, ds5.

@oshaboy
Copy link
Author

oshaboy commented Jul 18, 2024

I'm excited to discover this pull request and eager to see it continue to be developed and merged.

I mean it's pretty much ready to be merged. But nobody is merging it.

  1. provide ability to use a GUI mapping tool to create and save multiple custom control configurations including gyro and button/input chording

That's the thing I have trouble implementing because of issues with the menu code.

  1. provide a way to share community configurations

The configuration is just a simple text file you can share already.

  1. support global system configs, platform configs, and per-game configs

All of these are up to the cores. And I can't think of a use for per-game configs in Retroarch considering all the games are already designed for the platform's standard input device.

Also, we need a better way to allow a system's game library to have optimal default controls that are configured differently per game in advance. For example, mapping wii controls to a DS4/DS5 and all the different combinations of wiimote / wiimote rotated / wiimote plus / wiimote plus rotated, Wiimote plus nunchuck, wii controller, gamecube controller. It should be possible for a team to define and preconfigure optimal analog+gyro retropad settings per game as defaults given common controllers like xbox, ds4, ds5.

Again that's up to the cores. All Retropad needs to do is act as a standard hook. IMO The Retropad abstraction wasn't very well thought out but it's too late to change it now.

@gouchi
Copy link
Member

gouchi commented Jul 25, 2024

I confirm it is still working with DS4 udev.
ds4-udev.txt.zip

But for SDL2 driver it seems it did not find the sensor. I might have miss something.

SDL2 log
[INFO] RetroArch 1.18.0 (Git 0da83e8eb4)
[INFO] === Build =======================================
[INFO] CPU Model Name: Intel(R) Core(TM) i7-4771 CPU @ 3.50GHz
[INFO] Capabilities: MMX MMXEXT SSE SSE2 SSE3 SSSE3 SSE4 SSE42 AES AVX AVX2 
[INFO] Version: 1.18.0
[INFO] Git: 0da83e8eb4
[INFO] Built: Jul 25 2024
[INFO] =================================================
[INFO] [Input]: Found input driver: "sdl2".
[INFO] [Environ]: SET_PIXEL_FORMAT: RGB565.
[INFO] [Core]: Version of libretro API: 1, Compiled against API: 1
[INFO] [Core]: Geometry: 320x240, Aspect: 1.333, FPS: 60.00, Sample rate: 48000.00 Hz.
[INFO] [Audio]: Set audio input rate to: 48000.00 Hz.
[INFO] [Video]: Set video size to: fullscreen.
[ERROR] [Wayland]: Failed to connect to Wayland server.
[INFO] [Vulkan]: Vulkan dynamic library loaded.
[INFO] [Vulkan]: Found vulkan context: "vk_x".
[INFO] [Vulkan]: Detecting screen resolution: 1920x1080.
[INFO] [X/Vulkan]: Window manager is i3.
[INFO] [XINERAMA]: Xinerama version: 1.1.
[INFO] [XINERAMA]: Xinerama screens: 1.
[INFO] [X/Vulkan]: Using Xinerama on screen #0.
[INFO] [X/Vulkan]: X = 0, Y = 0, W = 1920, H = 1080.
[INFO] [X/Vulkan]: Using true fullscreen.
[INFO] [Vulkan]: Found GPU at index 0: "NVIDIA GeForce GTX 1060 6GB".
[INFO] [Vulkan]: Using GPU index 0.
[INFO] [Vulkan]: Using fences for WSI acquire.
[INFO] [Vulkan]: Using GPU: "NVIDIA GeForce GTX 1060 6GB".
[INFO] [Vulkan]: Queue family 0 supports 16 sub-queues.
[INFO] [Vulkan]: Got 2 swapchain images.
[INFO] [Vulkan]: Using resolution 958x1059.
[INFO] [Vulkan]: Using RGB565 format.
[INFO] [Vulkan]: Loading stock shader.
[WARN] [SDL]: Couldn't open haptic device of the joypad #0: Haptic: Joystick isn't a haptic device.
[INFO] [SDL]: Falling back to joystick rumble
[INFO] [Joypad]: Found joypad driver: "sdl2".
[INFO] [Autoconf]: PS4 Controller configured in port 1.
[INFO] [X11]: Suspending screensaver (X11, xdg-screensaver).
[INFO] [Video]: Found display server: "x11".
[INFO] [ALSA]: Using ALSA version 1.2.12
[DEBUG] [ALSA]: Requesting device "default" for PLAYBACK stream
[INFO] [ALSA]: Using FLOAT_LE sample format for PLAYBACK device "alsa_playback.retroarch-sensor-sdl2"
[INFO] [ALSA]: Period: 4 periods per buffer (732 frames, 5856 bytes)
[INFO] [ALSA]: Buffer size: 2928 frames (23424 bytes)
[INFO] [ALSA]: Can pause: yes.
[INFO] [ALSA]: Initialized PLAYBACK device "alsa_playback.retroarch-sensor-sdl2"
[INFO] [Audio]: Started synchronous audio driver.
[INFO] [ALSA] Using ALSA version 1.2.12
[INFO] [Microphone]: Initialized microphone driver.
[INFO] [Display]: Found display driver: "vulkan".
[INFO] [Playlist]: Loading history file: "/home/gouchi/.config/retroarch/content_history.lpl".
[INFO] [Playlist]: Loading history file: "/home/gouchi/.config/retroarch/content_music_history.lpl".
[INFO] [Playlist]: Loading history file: "/home/gouchi/.config/retroarch/content_image_history.lpl".
[INFO] [Playlist]: Loading favorites file: "/home/gouchi/.config/retroarch/content_favorites.lpl".
[WARN] [SDL]: Couldn't open haptic device of the joypad #0: Haptic: Joystick isn't a haptic device.
[INFO] [SDL]: Falling back to joystick rumble
[INFO] [X/Vulkan]: Resized fullscreen resolution to 958x1059.
[INFO] [Autoconf]: PS4 Controller configured in port 1.
[INFO] [X/Vulkan]: Resized fullscreen resolution to 1920x1080.
[INFO] [Config]: Saved new config to "/home/gouchi/.config/retroarch/retroarch.cfg".
[INFO] [Core]: Content ran for a total of: 00 hours, 00 minutes, 00 seconds.
[INFO] [Core]: Unloading core..
[INFO] [Core]: Unloading core symbols..
[INFO] [Autoconf]: PS4 Controller disconnected from port 1.
[INFO] [XINERAMA]: Xinerama version: 1.1.
[INFO] [XINERAMA]: Xinerama screens: 1.
[INFO] [XINERAMA]: Saved monitor #0.
[INFO] [Video]: Does not have enough samples for monitor refresh rate estimation. Requires to run for at least 4096 frames.

@zoltanvb
Copy link
Contributor

I still don't think SDL input driver will be effective under X. In any case, here are some logs from KMS+SDL (RPi 4, Ubuntu, SDL 2.26.5):

[INFO] [Video]: Graphics driver did not initialize an input driver. Attempting to pick a suitable driver.
[DEBUG] [sdl]: SDL_GetNumTouchDevices: 0
[DEBUG] [sdl]: SDL_NumSensors: 0
[DEBUG] [sdl]: SDL_NumJoysticks: 1
[DEBUG] [sdl]: Gamepad no 0 (PS4 Controller 0x0x55bb88fd20)
	HasSensor: 0
	IsSensorEnabled: 0
	GetNumTouchpads: 0
[INFO] [udev]: Pad #0 (/dev/input/event4) supports force feedback.
[INFO] [udev]: Pad #0 (/dev/input/event4) supports 16 force feedback effects.
[INFO] [Joypad]: Found joypad driver: "udev".
[INFO] [Video]: Found display server: "kms".
[DEBUG] [PulseAudio]: Sink detected: alsa_output.usb-Sony_Interactive_Entertainment_Wireless_Controller-00.analog-stereo
[DEBUG] [PulseAudio]: Sink detected: alsa_output.platform-bcm2835_audio.stereo-fallback
[DEBUG] [PulseAudio]: Sink detected: alsa_output.platform-fef00700.hdmi.hdmi-stereo
[INFO] [PulseAudio]: Requested 24576 bytes buffer, got 18432.
[INFO] [Audio]: Started synchronous audio driver.
[INFO] [ALSA] Using ALSA version 1.2.8
[INFO] [Microphone]: Initialized microphone driver.
[INFO] [Display]: Found display driver: "glcore".
[INFO] [Playlist]: Loading history file: "/home/pi/.config/retroarch/content_history.lpl".
[INFO] [Playlist]: Loading history file: "/home/pi/.config/retroarch/content_music_history.lpl".
[INFO] [Playlist]: Loading history file: "/home/pi/.config/retroarch/content_video_history.lpl".
[INFO] [Playlist]: Loading history file: "/home/pi/.config/retroarch/content_image_history.lpl".
[INFO] [Playlist]: Loading favorites file: "/home/pi/.config/retroarch/content_favorites.lpl".
[INFO] [Environ]: GET_SENSOR_INTERFACE.
[libretro DEBUG] [Remote RetroPad]: Sensor interface supported, enabling.
[libretro DEBUG] [Remote RetroPad]: Tilt sensor enabled.
[libretro DEBUG] [Remote RetroPad]: Gyro sensor enabled.
[libretro DEBUG] [Remote RetroPad]: Lux sensor enabled.
[ERROR] [sdl]: sdl_input_get_sensor_input recieved a device where none of it's children are sensors
[ERROR] [sdl]: sdl_input_get_sensor_input recieved a device where none of it's children are sensors
[ERROR] [sdl]: sdl_input_get_sensor_input recieved a device where none of it's children are sensors
[ERROR] [sdl]: sdl_input_get_sensor_input recieved a device where none of it's children are sensors
[ERROR] [sdl]: sdl_input_get_sensor_input recieved a device where none of it's children are sensors

The last line is repeated ad infinitum, and remote retropad shows no sign of sensor activity.

With udev, things are working in my tests too, same observation about axes (controller held vertically matches the state of a phone set down on a tabletop) + accelerometer sensitivity had to be cranked up to 5.0 to get similar result as on Android, i.e. a tilt of 90 degrees will move the indicator to the end. As I remember, on Android it was according to the spec:

* Returns the device's acceleration along its local X axis minus the effect of gravity, in m/s^2.

@gouchi
Copy link
Member

gouchi commented Jul 30, 2024

@LibretroAdmin I think it should be good to merge this feature, we confirmed it is working using udev and ds4.

Thank you.

@oshaboy
Copy link
Author

oshaboy commented Jul 30, 2024

@gouchi @zoltanvb I just wrote a minimal test program and it seems to be 100% an issue with SDL itself not with my code.

#include <SDL2/SDL.h>
#include <stdio.h>
int main(void){
	SDL_Init(SDL_INIT_EVERYTHING);
	SDL_GameController* dualsense=SDL_GameControllerOpen(0);
	printf(
		"%s %d %d %d\n",
		SDL_GameControllerName(dualsense),
		SDL_GameControllerHasSensor(dualsense, SDL_SENSOR_ACCEL),
		SDL_GameControllerHasSensor(dualsense, SDL_SENSOR_GYRO),
		SDL_NumSensors()
	);

	return 0;
}

prints "PS5 Controller 0 0 0"

@gouchi
Copy link
Member

gouchi commented Jul 30, 2024

For information, DS4 gives with the SDL2 test program :

PS4 Controller 1 1 0

}
}
if (!gamepad && !sensor){
RARCH_ERR("[sdl]: sdl_input_get_sensor_input recieved a "
Copy link
Member

Choose a reason for hiding this comment

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

There is a typo recieved should be received.

@LibretroAdmin
Copy link
Contributor

Hi there @oshaboy , I'm sorry that this PR has taken so long to be merged.

If you could address the merge conflict we could start fasttracking this.

@oshaboy
Copy link
Author

oshaboy commented Sep 11, 2024

Hi there @oshaboy , I'm sorry that this PR has taken so long to be merged.

If you could address the merge conflict we could start fasttracking this.

No Problem. Better late then never.

@gouchi
Copy link
Member

gouchi commented Sep 17, 2024

@LibretroAdmin I confirm, it is still working with DS4 udev driver using latest commit.

So this feature should be good to be merged.

Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants