moonlight-stream / moonlight-android

GameStream client for Android
GNU General Public License v3.0
3.23k stars 512 forks source link

Gamepad mapping (Bluetooth) #559

Closed MarrowB83 closed 6 years ago

MarrowB83 commented 6 years ago

Hello,

I have downloaded this app on my android device & i am superly happy with that except of one thing.

I can not make working one button on my gamepad, which is right down bumper. I have tested it in defferent apps in android, also gamepad tester app, and it works perfectly. The only app where it is not working is Moonlight. It is just not sending R2 button information while streaming. I dunno why.

Is there any way to check key mapping in Moonlight android?

Thank you in advance!

Shadsterwolf commented 6 years ago

I'm surprised there's not a manual input setup, since I do have this similar problem. Looking through \app\src\main\java\com\limelight\binding\input , It appears to be asking the generic input device what it could be. As I see a lot of flags for common controllers.

Shouldn't be too difficult to add this functionality, I'll keep reading through the code and see if possibly I can provide assistance.

cgutman commented 6 years ago

What gamepad model is it?

The Moonlight code works with any gamepad that adheres to the standard gamepad specification for Android along with certain popular non-compliant gamepads (PS3, PS4, Xbox 360, Xbox One)

https://docs.nvidia.com/gameworks/content/technologies/mobile/game_controller_quickdoc_amalgamated_gamepad.htm

MarrowB83 commented 6 years ago

Yes. Afterall I gave up, because of what @cgutman said above.

My gamepade type is not listed in supported devices, so I think thats it. Pitty is, that it is working overall, cept that one button. :-)

It is this kind of gamepad: https://img.staticbg.com/thumb/view/oaupload/banggood/images/C2/20/afbad64a-29d4-4d87-b6c9-dca39ec63167.jpg

@Shadsterwolf I have been trying to check the source too, but I was not sucessfull at all. I would appreaciate your help, if you are gonna be a bit more lucky than me :-)

cgutman commented 6 years ago

What button/axis code do you get when you push the right trigger in the gamepad tester app? Is the trigger analog or digital?

Shadsterwolf commented 6 years ago

@MarrowB83 Same, my gamepad type doesn't identify properly with android's inputs. I'll have to learn how game emulator apps properly capture these inputs.

@cgutman I believe in our case, our gamepads do not abide to the standard. For example, I am actually using JoyCons, which is connected by an adapter to my S9 called "Magic-NS" https://www.amazon.com/Mayflash-MAGIC-NS-Wireless-Controller-Nintendo-Switch/dp/B074JZPS39 I found while testing that not all buttons identify as a generic input, however is still detectable. Various game emulator apps I use are able to prompt and map these inputs

Shadsterwolf commented 6 years ago

Writing my findings here, and how I got my joycons working.

Working only within the file: \app\src\main\java\com\limelight\binding\input\ControllerHandler.java

Firstly @ class InputDeviceContext Add a public boolean of your device reference

public boolean isMagicNs; //Joycon adapter

Secondly @ private InputDeviceContext createInputDeviceContextForDevice(InputDevice dev) In the if (devName != null) { Add your device name (captured by a gamepad test)

else if (devName.equals("MAGIC-NS")) { context.isMagicNs = true; }

Lastly @ private int handleRemapping(InputDeviceContext context, KeyEvent event) Add your remappings to your scancode

else if (context.isMagicNs) { switch (event.getScanCode()) { case 306: return KeyEvent.KEYCODE_BUTTON_A; case 304: return KeyEvent.KEYCODE_BUTTON_Y; case 308: return KeyEvent.KEYCODE_BUTTON_L1; case 309: return KeyEvent.KEYCODE_BUTTON_R1; case 310: return KeyEvent.KEYCODE_BUTTON_L2; case 311: return KeyEvent.KEYCODE_BUTTON_R2; case 312: return KeyEvent.KEYCODE_BUTTON_SELECT; case 313: return KeyEvent.KEYCODE_BUTTON_START; case 314: return KeyEvent.KEYCODE_BUTTON_THUMBL; case 315: return KeyEvent.KEYCODE_BUTTON_THUMBR; default: // Other buttons are mapped correctly } }

Built my debug APK and it works like a charm. Hope this helps others out for now.

Here's the Gamepad tester app I used from GooglePlay that helped me get my scancodes and compare what button I needed to be remapped to. screenshot_20180415-192141_gamepad_tester

MarrowB83 commented 6 years ago

Hey @Shadsterwolf !

This is great news! Thank you for the information from your investigation! I will definetly check that out too.

I will try your solution during the weekend, I'm kind of curious :-)

Thank you again! Mark

MarrowB83 commented 6 years ago

Hey @Shadsterwolf !

I did everything you said here, but unfortunately it is still not working. I think I am doing something wrong with my scancodes.

I have issue only with one button, and thats R2. Here is the document and what I have done:

Iam using BTGamepad (BT Gamepad).

ControllerHandler.java https://drive.google.com/file/d/1xOiX5DhMcl4TBjLw8q2qHPxqTfTaFdGx/view?usp=sharing

Scancodes from APP on Android screenshot_20180421-160240

What I thought is that I have to put there the scancode from the testing app, which is 313 for me. However, it is 313 also for you, and for some reason you used scancode 311, can you explain to me why? :-)

Ty a lot!

MarrowB83 commented 6 years ago

I did a little test... I tried to remap R2 button to X button (where X button is working properly). 313 scancode is being used for R2, 307 for X.

From: case 313: return KeyEvent.KEYCODE_BUTTON_R2;

To: case 307: return KeyEvent.KEYCODE_BUTTON_R2;

When I tried this, X button stopped working. It seems like that application does not recognize KeyEvent.KEYCODE_BUTTON_R2 for some unknown reason...

Shadsterwolf commented 6 years ago

@MarrowB83 For my controller, my keycodes are different than yours, as many have their own.

The switch statement case is returning the keycode detected from the controller. Remember this is to remap your buttons. In your case it appears there's a button that identifies as R2, which you need to remap to the correct button. As for your X button, ensure that it's not remapped to something else and that gamepad tester detects it (If it doesn't it may be bluetooth/hardware issue)

For example, My + button on my joycon identifies as keycode 313 and button as BUTTON_R2 I have to say case 313: return KeyEvent.KEYCODE_BUTTON_START; In addition, My R2 button on my joycon identifies as keycode 311 and button as BUTTON_R1 I have to say case 311: return KeyEvent.KEYCODE_BUTTON_R2;

cgutman commented 6 years ago

@Shadsterwolf can you submit a PR with your changes? I'd gladly take them upstream.

MarrowB83 commented 6 years ago

@Shadsterwolf Thank you for you fast response!

If I get you properly, your joycon have been sending to your android device different keycodes & buttons, which is the case you remapped.

I am afraid that it is afterall not my issue, to be sure, I have recorded my test gamepad app, whilst pressing R2 button check the video, if you can, please.

IMHO there should not be any reason for remapping in my case, am I correct?

cgutman commented 6 years ago

@MarrowB83 can you try to identify what axes are present on your gamepad and what buttons correspond to them? Moonlight will suppress the digital trigger buttons if it thinks your triggers have analog axes too.

MarrowB83 commented 6 years ago

@cgutman you are probably talking about this: supress

Tried indetifying them here.

Left stick is button "AXIS X" & "AXIS Y". Right stick is button "AXIS Z" & "AXIS RZ".

... I am not sure if I answered your question, hehe :-)

cgutman commented 6 years ago

@MarrowB83 Does pressing left trigger change AXIS BRAKE?

MarrowB83 commented 6 years ago

@cgutman WoW, nice observation, it does! What does it mean? ^.^ EDIT: And the value of AXIS BRAKE is everytime completely different, whilst pressing left trigger.

cgutman commented 6 years ago

@MarrowB83 That explains it then. Your gamepad exposes the left trigger as KEYCODE_BUTTON_L2 and AXIS_BRAKE. It also apparently claims to have an AXIS_THROTTLE/AXIS_GAS, but doesn't send any right trigger values through it. As a result, Moonlight suppresses the KEYCODE_BUTTON_R2, but nothing ever comes via the analog axes either.

Does this build fix it? https://drive.google.com/open?id=1DwIEsbhFKZi7isM2y3YK_IWojtHzJjSB

MarrowB83 commented 6 years ago

@cgutman I see what you mean now. Unfortunately, it still does not work, even with your build you have provided.

cgutman commented 6 years ago

@MarrowB83 oops, sorry. I forgot to update both places. Try this: https://drive.google.com/open?id=1xeaDFgj-HZYO2GnGw80Ef_DA-yR3zo4m

MarrowB83 commented 6 years ago

My goosh, you made it workiiing! Haha, I am super happy now :-)

May I ask you how does the code looks like now, please?

Also, is this just fix for my gamepad or is it going to be in official relase?

Thank you in advance, I owe you a beer.

cgutman commented 6 years ago

Glad to hear that it works. It will be in the next official release.

The fix is here: https://github.com/moonlight-stream/moonlight-android/commit/381509b3a63e89d50a6516afae5bbc57879e1596

smiller171 commented 5 years ago

Does this fix only work with the magic-ns adapter? I'm having no luck with my joycons over Bluetooth

Shadsterwolf commented 5 years ago

Does this fix only work with the magic-ns adapter? I'm having no luck with my joycons over Bluetooth

I'm not sure how much the master's branch of code changed since I posted my little tutorial how to support his setup here: https://github.com/moonlight-stream/moonlight-android/issues/559#issuecomment-382634333

I've only used the Magic-NS adapter, and even then the firmware for that device has updated too.

Now, I have no experience how Joycons work with bluetooth to an android device directly, but seen only one joycon (not both) being able to be used. Even then, I'm not sure if anyone has invented a supporting code for this purpose without using an adapter.

smiller171 commented 5 years ago

They show up as two separate controllers (L and R), so in software you have to accept input from both and map each to half a controller.

There's an app in the Play Store that can handle this and emulate a single controller, but it requires root to work in other apps.

https://play.google.com/store/apps/details?id=com.catalyst06.joyconenabler

MrFancyPantsVT commented 5 years ago

@Shadsterwolf Would you mind walking me through building a debug APK or pointing me to some resources? I'm running into sync/build issues.

Shadsterwolf commented 5 years ago

I remember having a bit of trouble too. I've stepped away from Android development and rusty again how to handle it myself.

From what I remember, I had to re-read carefully his build instructions: https://github.com/moonlight-stream/moonlight-android/blob/master/README.md#building

The Android NDK stuff was the most difficult. You have to call from inside where the source code folder resides, then add the path of where the NDK's source was in the file mentioned. (I know it's not very clear nor in a piecemeal fashion, but it's all I can remember.)

mistertest commented 2 years ago

Hello, I'm the dev of Xcloud shield, an unofficial app for the shield tv, about playing Xcloud directly from the shield and having a better experience than the sideloaded smartphone app. My project is here : https://github.com/mistertest/xcloud-shield

I need some help for including in my code a remapping of the select button acting like an back button on android tv. So in game I want that when you push on select button the Key code 109 and scancode 114 will be sending to the webview. The app is a optimised custom webview with java.

Can someone help me to obtaining this feature ? You can contact me if you can help, you are welcome.