-
Notifications
You must be signed in to change notification settings - Fork 9
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
Consider expanding Android gamepad support #106
Comments
…tton. This will help with Android, where native indexes ARE standard indexes, but we have to map them to a consecutive number range to allow Ebitenigne non-standardlayout APIs to work. See divVerent/aaaaxy#106
Starting work on this now. Seems like it requires some minor refactoring, so did that first. |
Minor refactoring: divVerent/ebiten@1b617f4 If you can, @hajimehoshi, please quickly confirm whether the internal gamepad API change for this is OK (regardless whether it compiles yet or not, I'm not that far yet). If so, I will try to add Android and Linux native standard layout support using this. |
There seems a compile error. Do you want to rename some functions by the way? |
Ah now I understand what you want to do. The direction seems correct. |
OK, got a first draft but I started for Linux as it is easier to develop there and the same problems need solving. My android_stdlayout branch now supports my Xbox 360 gamepad mostly even without gamepaddb, but no D-pad or triggers yet. The issue is that to support these, we need to be able to map axes vs hats vs buttons, which SDL does and gamepaddb does, but the current framework to do standard layout remapping in Ebitengine does not. |
So, approach will be:
|
Seems like this IS needed: https://developer.android.com/develop/ui/views/touch-and-input/game-controllers/controller-input E.g. AXIS_HAT_{X,Y} and BUTTON_DPAD_{UP,DOWN,LEFT,RIGHT} should both be mapped to the D-pad. So I think next step is further refactoring so we return a struct indicating whether a standard button/axis is backed by an axis, button or hat. At least for Linux we'd need that anyway. Now one more thing is irritating: |
While at it, dumping here how axis<->button<->hat mapping works in gamepaddb:
|
I'm not sure I fully understand it, but it is OK to refactor the existing functions to achieve your purpose. |
Yeah, me neither. The functionality I want for Android to support generic gamepads is there (but hidden inside gamepaddb code, not native gamepad mapping code like all the others). I gotta figure out why it is failing for my gamepad then (and one of my users reported the same). So, possibly I will solve this by fixing Either way, though, for full Linux support I'll have to refactor standard button/axis support to be able to map to buttons, axes and hats. This will then also enable automatic standard layout on Windows/XInput, however I probably won't be able to be the one to implement that. The big goal here is to deprecate the need for SDL_GameControllerDB for anything but "weird gamepads" - anything Xbox or PlayStation compatible then should work out of the box. (Not sure about Nintendo there, didn't see references to them on SDL source code much) |
Results with my gamepad and Ebitengine 2.5:
I'll edit this reply once I used another app that gives me the button and axis names from Java's POV. |
So the issues are:
Rest is actually correct. This is on my Pixel 6 - on my Moto G7 Play I get no gamepad support at all. |
As for the Guide button, we have this:
However, why NOT already add this? What does this do if SDKVersion is too low? Other than that, this remapping code is very weird and just can't be right in general. E.g. the axis mask is just computed from the number of axes - not which are actually available. The main problem is, whatever I do may conform to Android docs, but break some corner case the SDL code covers. But there are also cases vice versa. So I wonder if this should be introduced as a build flag or as an ebitengine API option one can set at startup. |
But yeah, it seems like Ebitengine 2.5 fixed some of this already - the issues were worse in 2.4. I see some changes have been done there for 2.5, e.g. for 47558d20c505edf2a43eabeebbd39cffe3158579 |
OK... I think I'll get the Linux version of this change in, and then probably will give it a try to implement Google's guidelines in Ebitengine. The current implementation is heavily based on SDL's, and part of it is sure required to keep the axes and buttons indexed consecutively for Ebitengine's non-standardlayout-API use - so I will probably have keep most current code as is even if I use the native gamepad support (that does not go via gamepaddb) I implemented. |
Hm... now that I went through it, the current implementation might be some kind of nonsense for axes (but that's only really a problem for gamepads that lack a right stick but have triggers). For buttons it's sound though. And it at least roughly matches SDL, so I may want to keep it as is for now, modulo bugs. So I improved debugging in AAAAXY to be able to logcat the actual mapping, and will see later what it takes to fix it (possibly locating accidental diffs with SDL). |
(However, doing this mapping inside gamepaddb is probably wrong as well - but not our issue. I may want to refactor this code from gamepaddb.go into gamepad_android.go, but that's indepedent from the fixing here) |
Tried again, this time with better debug code to remove chance of human error. Full list of mistakes:
So, in terms of Linux's mapping, ABS_RX is understood as ABS_RY, ABS_RY as ABS_Z, and ABS_Z as ABS_RX. Axes 0 and 1 are ABS_X and ABS_Y as they should be. Axis 5 is the right trigger, also as it should be. |
So if we made the sorting X, Y, RX, RY, Z, RZ, things would work just fine. But of course, if we go by Android's documentation, it should be X, Y, Z, RZ, RX, RY. Wonder what SDL does... |
By reading source, SDL does the same mistake. But I can't try out without having an SDL based gamepad app and knowing how to compile it... |
If I find nothing better, THIS might actually be a starting point for adding logging of gamepad events: https://github.com/georgik/sdl2-android-example |
Looks like SDL2 comes with its own gamepad test, just is a bit tricky to compile - need the attached patch and then run:
|
With this, all is perfect in SDL. Need to figure out if I'm using a gamecontrollerdb mapping somehow though... |
|
That mapping corresponds to sorting in the order X Y RX RY Z RZ. |
So, next step is adding debug code into SDL to find out where it's making the mapping work. |
HAHA, on SDL we're not even hitting that Java code. The joystick is opened via hidapi. Wonder if I can switch to using that Java code instead... |
When using SDL's Java code, the exact same bug happens:
So on SDL my gamepad (and probably all Xbox ones) only works when using the HIDAPI implementation. To make it actually use the Java implementation, I had to:
I'll file a SDL bug, but as SDL has a solution by an alternate API, I do not expect them to fix it. |
The alternate API that SDL uses is IIRC basically Linux raw device access, which happens to work now but I expect Google to lock that down more and more in future API versions - so I'd rather not want Ebitengine to rely on that. |
Reported as libsdl-org/SDL#7404 and am going to provide a PR to that that will keep existing working SDL_GameControllerDB entries alive. |
Filed libsdl-org/SDL#7405 - and if that gets merged, I'll port the same change into Ebitengine to keep the two in line (so that they interpret SDL_GameControllerDB files the same way). |
Provided alternate fix option in libsdl-org/SDL#7405 (comment) - this one is probably cleaner but may impact existing gamecontrollerdb mappings. Let's have SDL team pick and mirror it in Ebitengine. |
Done - changes are in and my gamepad which is a no-name xbox compatible pad now works out of the box. |
Android needs gamepad support most as touch input isn't so great. Right now only gamepads supported by SDL_GameControllerDB are supported - however Android APIs already provide a standard layout mapping natively.
I filed hajimehoshi/ebiten#2557 for this, but it seems resources are lacking to implement this on Ebitengine side - thus, filing this bug so I'll look into it myself to see what it takes to make this work.
Looking for androidKeyToSDL it seems like we already have a 1:1 mapping from Android buttons to SDL names, which seems close to standard layout. We'd need the same for axes. As part of the SDL ID, we already provide info about axis and button existence, as well. For buttons it seems rather clean which are transmitted 1:1 to Go, for axes not so much as they're remapped in the Java code. Probably should move the remapping into Go and then we also have a trivial standard layout mapping.
The text was updated successfully, but these errors were encountered: