sm64-port-android-base icon indicating copy to clipboard operation
sm64-port-android-base copied to clipboard

controller won't work shield tv

Open trainfan91 opened this issue 5 years ago • 16 comments

only keyboard works

trainfan91 avatar Sep 18 '20 15:09 trainfan91

Can confirm that this also happens on Android TV 8.0.0 on a Philips 55OLED803 TV.

oscarb avatar Sep 28 '20 19:09 oscarb

Android on the new Chromecast same issue. DS4 controller does not work.

parkerlreed avatar Oct 01 '20 17:10 parkerlreed

Same on the xiaomi mi box 3, xbox one s controller that works fine on the box is not working in this app.

Seems like all android tv devices have the same problem.

Not starting at all on the fire tv stick 4k, just showing the on-screen controls,

Dominiquedb avatar Oct 01 '20 21:10 Dominiquedb

I'm writing to say that I think the issue isn't that the game isn't detecting the controller, but rather it's attaching to another controller first. I've been trying to get a DualShock 4 controller to work, and here's what I've found.

My NVIDIA Shield Remote works to move Mario's head around at the title screen, but I can't do anything else.

The solution, you would think, would be to disconnect the Shield Remote so that the controller you want connected would be next in line. Unfortunately, the Shield itself seems to have 5 additional hidden controllers.

These seem to be:

  • virtual-search
  • shield-ask-remote
  • IPControl_UPnP_RemoteService
  • shield-ask-remote (a second time)
  • Android Accelerometer

Due to these extra controllers, the game seems to automatically link up to either the Shield Remote or possibly one of the other 5 hidden controllers first.

I'm not sure how to tell the game not to connect those other controllers, but I thought I'd share what I've found.

ESurge avatar Dec 20 '20 17:12 ESurge

Got it working.

I added a filter (sorta) to the SDLControllerManager.java file in app/src/main/java/org/libsdl/app folder.

Around line 205 it states:

mJoysticks.add(joystick);
SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, getVendorId(joystickDevice), getProductId(joystickDevice), false, getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0);

I added two if statements. First if statement is used to filter out empty VID/PID devices from being added to the joystick list, and second if statement is used to filter out devices that don't have any axes.

if ((getVendorId(joystickDevice) != 0) && (getProductId(joystickDevice) != 0))
{
	if (joystick.axes.size() != 0)
	{
		mJoysticks.add(joystick);
		SDLControllerManager.nativeAddJoystick(joystick.device_id, joystick.name, joystick.desc, getVendorId(joystickDevice), getProductId(joystickDevice), false, getButtonMask(joystickDevice), joystick.axes.size(), joystick.hats.size()/2, 0);
	}
}

Whether or not this filters out some other devices is beyond me, but it worked to get the Sony PS4 DS4 controller operational on the NVIDIA Shield TV Pro.

Hope this helps.

ESurge avatar Dec 20 '20 18:12 ESurge

@ESurge Nice! Do you perhaps have any idea on how to make this change but with the sm64-port-android repo for compiling it on Android...? I'm having difficulties using this repo and compiling it on my Mac.

oscarb avatar Jan 05 '21 22:01 oscarb

@oscarb Unfortunately at this time, I believe this Android port is incomplete when building on an Android device itself (without some build work on a computer first). This said, I believe it can be done fully on a Mac/Linux/Windows machine. You'll need to sync the sm64-port-android-base, mod the file, and build the apk according to the instructions.

I would suggest looking at the smlinux project. While with smlinux, it can be a bit tricky to add modded files, it does however have a nice pre-build configuration menu/editor, and most build steps are automated.

I ended up creating a mod folder with any modified files in the correct directory structure as the source files. Then I modified the smlinux bash script to have the mod folder/files copied over to the source folder just before the build process is executed.

Hope this helps! Good luck.

ESurge avatar Jan 06 '21 09:01 ESurge

I can't even get this building currently.

sm64ex_nightly branch

Is the ndk too new?

[parker@stealth sm64-port-android-base]$ pacman -Q android-sdk android-ndk 
android-sdk 26.1.1-1.1
android-ndk r22-3
[parker@stealth sm64-port-android-base]$ ls /opt/android-ndk/
build         meta       ndk-gdb   ndk-stack  NOTICE            prebuilt         README.md     simpleperf         sources     wrap.sh
CHANGELOG.md  ndk-build  ndk-lldb  ndk-which  NOTICE.toolchain  python-packages  shader-tools  source.properties  toolchains
[parker@stealth sm64-port-android-base]$ ./gradlew assembleDebug

> Configure project :app
NDK is missing a "platforms" directory.
If you are using NDK, verify the ndk.dir is set to a valid NDK directory.  It is currently set to /opt/android-ndk.
If you are not using NDK, unset the NDK variable from ANDROID_NDK_HOME or local.properties to remove this warning.


FAILURE: Build failed with an exception.

* What went wrong:
A problem occurred configuring project ':app'.
> java.lang.NullPointerException (no error message)

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 0s

parkerlreed avatar Jan 06 '21 21:01 parkerlreed

Downgrading to 20.1 worked. Just realized I forgot the controller to test. Thanks for the tip! Will test it out when I get home.

parkerlreed avatar Jan 06 '21 21:01 parkerlreed

Well stopped even launching on the new Chromecast. Not sure what's going on.

parkerlreed avatar Jan 07 '21 01:01 parkerlreed

Downgraded to master, disabled touch controls, allowed storage permission (wasn't asking for it). Completely not working anymore.

01-06 20:24:10.954 14099 14158 D AudioTrack: stop(38): called with 0 frames delivered
01-06 20:24:10.956 14099 14158 D         : PlayerBase::stop() from IPlayer
01-06 20:24:10.956 14099 14158 D AudioTrack: stop(38): called with 1024 frames delivered
01-06 20:24:10.957 14099 14158 D         : PlayerBase::stop() from IPlayer
01-06 20:24:10.957 14099 14158 D AudioTrack: stop(38): called with 1024 frames delivered
01-06 20:24:10.982 14099 14131 F libc    : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x8630e761 in tid 14131 (SDLThread), pid 14099 (SDLActivity)
01-06 20:24:10.993 14099 14158 D         : PlayerBase::stop() from IPlayer
01-06 20:24:10.993 14099 14158 D AudioTrack: stop(38): called with 1536 frames delivered
01-06 20:24:11.048 14162 14162 I crash_dump32: obtaining output fd from tombstoned, type: kDebuggerdTombstone
01-06 20:24:11.049  3735  3735 I /system/bin/tombstoned: received crash request for pid 14131
01-06 20:24:11.050 14162 14162 I crash_dump32: performing dump of process 14099 (target tid = 14131)
01-06 20:24:11.067 14099 14158 D         : PlayerBase::stop() from IPlayer
01-06 20:24:11.067 14099 14158 D AudioTrack: stop(38): called with 2560 frames delivered
01-06 20:24:11.068 14099 14158 D         : PlayerBase::stop() from IPlayer
01-06 20:24:11.068 14099 14158 D AudioTrack: stop(38): called with 512 frames delivered

EDIT: Note this is happening regardless of the input patch. Seems the Chromecast just isn't liking the current sm64 compile.

parkerlreed avatar Jan 07 '21 01:01 parkerlreed

This thread isn't really the place to post various issues. I suggest checking out the smlinux project for an easier build process or join the SM64 Port Discord for more assistance.

ESurge avatar Jan 07 '21 01:01 ESurge

Any update on how to get the shield controller to work with the Android port?

Savisthorv avatar Feb 04 '22 22:02 Savisthorv

@ESurge I've made a fork with your controller filter patch added (along with sort of a lot of other stuff) here and your filter works really good for a lot of other controllers and devices too. Unfortunately, though, I've received a report that it does filter out a valid controller in this configuration, which begins working when your patch is reverted:

  • Galaxy Tab S7 FE SM-T733
  • Android 13
  • Joytron EX Force controller via Bluetooth

I tried to collect data from that setup by inserting this right before your first if statement:

Log.d("SDL", "vendor: " + getVendorId(joystickDevice));
Log.d("SDL", "device: " + getProductId(joystickDevice));
Log.d("SDL", "axis count: " + joystick.axes.size());

However, it seems like it takes repeated tries to reach that code path, because on my devices I can only see that information print in adb logcat after disconnecting and reconnecting my controller many times, and unfortunately the person who has the Joytron EX Force does not have time to repeatedly test code frequently.

What I'm curious about is, does your Shield Controller still work if you remove your getVendorId() and getProductId() conditions and only use the joystick.axes.size() condition, or are all three conditions required for your device? I'm trying to come up with a version that might work for as many controllers as possible at once (in this case except for controllers without analog sticks, though hopefully most don't want to use those in this situation), then gradually get as many users with problematic controllers as possible to test it so I can find out if it works, repeat.

Also relevant for this thread, I've also tested and added directions for building a Super Mario 64 android app fully from source, including the code you modified, solely on Android without a desktop PC, in the README of my fork, as well as rewritten build directions for every other platform for building the .apk (Android partial, Windows full, GNU/Linux full, Docker full) which could help people here who've had difficulty building with this controller filter patch enabled.

robertkirkman avatar Feb 10 '23 05:02 robertkirkman

Hi @robertkirkman

To understand what was going on with the NVIDIA Shield Pro 2019 and my controller, I used some SDL apps I found via another site. These apps included a gamepad demo based on Godot Engine, and also a SDL controller remapping tool. Information gathered by using these apps were what made my decision to create the filter if statement "patch".

However, since upgrading my Shield to 9.1.1, and revisiting this sm64 code, the aforementioned apps don't work quite the same. Therefore, I added some code to the SDLControllerManager.java file. The code outputs all the detected joysticks + details to a text file. Since I didn't want to get too involved in the code (aka nothing fancy), I just output the text file to two locations. Depending on permissions granted by the user, the result is a file in one of those two locations.

For the information below, I've been using your forked code for sm64ex coop.

Here's the code that generates the joystick detail output: In SDLControllerManager.java: At Line 7, I added the import for IO for the file writing import java.io.*;

At around line 208, before the if statement "patch", I added the following:

String data = "Joystick ID: " + joystick.device_id + "\nJoystick Name: " + joystick.name + "\nJoystick Axes: " + joystick.axes + "\nJoystick Hats: " + joystick.hats + "\nJoystick Vender ID: " + getVendorId(joystickDevice) + "\nJoystick Product ID: " + getProductId(joystickDevice) + "\n\n";

String filename = "/storage/emulated/0/com.owokitty.sm64excoop/user/sm64-coop.txt";

try(FileWriter fileWriter = new FileWriter(filename, true); PrintWriter printWriter = new PrintWriter(fileWriter);)
{
    printWriter.println(data);
}
catch (IOException e)
{
    e.printStackTrace();
}

filename = "/storage/emulated/0/Android/data/com.owokitty.sm64excoop/files/user/sm64-coop.txt";

try(FileWriter fileWriter = new FileWriter(filename, true); PrintWriter printWriter = new PrintWriter(fileWriter);)
{
    printWriter.println(data);
}
catch (IOException e)
{
    e.printStackTrace();
}

After testing with the NVIDIA Shield Pro 2019 running software version 9.1.1 (Android 11), and having a PS4 DualShock controller connected via Bluetooth, I found the following controllers were present:

Joystick ID: 5
Joystick Name: IPControl_UPnP_RemoteService
Joystick Axes: []
Joystick Hats: []
Joystick Vender ID: 6353
Joystick Product ID: 256


Joystick ID: 6
Joystick Name: shield-ask-remote
Joystick Axes: []
Joystick Hats: []
Joystick Vender ID: 6353
Joystick Product ID: 256


Joystick ID: 8
Joystick Name: virtual-search
Joystick Axes: []
Joystick Hats: []
Joystick Vender ID: 6353
Joystick Product ID: 256


Joystick ID: 15
Joystick Name: NVIDIA SHIELD Remote
Joystick Axes: []
Joystick Hats: []
Joystick Vender ID: 2389
Joystick Product ID: 29207


Joystick ID: 21
Joystick Name: Wireless Controller
Joystick Axes: [android.view.InputDevice$MotionRange@2865bee, android.view.InputDevice$MotionRange@b4bd88f, android.view.InputDevice$MotionRange@8e0f71c, android.view.InputDevice$MotionRange@ebbef25, android.view.InputDevice$MotionRange@48048fa, android.view.InputDevice$MotionRange@c376eab, android.view.InputDevice$MotionRange@a946908, android.view.InputDevice$MotionRange@d6158a1]
Joystick Hats: [android.view.InputDevice$MotionRange@8f9fac6, android.view.InputDevice$MotionRange@7fc4a87]
Joystick Vender ID: 1356
Joystick Product ID: 1476

I also did some testing on a OnePlus 8 Pro mobile phone running Android 12, and also tested on a Samsung Galaxy A53 mobile phone running Android 13. I found that no text file is generated when no controller is present. This means no hidden controllers were present.

Since I don't have a Joytron Ex Force controller to test, my thoughts on the "patch" impeding the controller connection in game seems to mean that the joystick variable isn't reporting any Axes. Therefore, a modification to the "patch" would be as follows: if (getVendorId(joystickDevice) != 0 && getProductId(joystickDevice) != 0 && (joystick.axes.size() != 0 && joystick.hats.size() != 0))

I think it would be safe to remove the check for Vendor/Product IDs since it seems unlikely to be doing any filtering at all based on my new findings with the NVIDIA Shield Pro 2019.

I looked for the Joytron Ex Force controller in the SDL2 GameController DB but I couldn't find it. It's likely being reported as a generic controller, similar to my PS4 DualShock controller being reported as a "Wireless Controller".

Anyways, I hope this helps!

PS: The sm64ex coop project is pretty slick. I haven't kept up with the sm64 modding scene, so it's nice to see so much progress in the last year or so.

ESurge avatar Feb 22 '23 01:02 ESurge

Thank you! I've gone with joystick.axes.size() != 0 || joystick.hats.size() != 0 so that if there is at least one of either a hat or an axis, the gamepad will be considered usable. I hope to eventually get back in contact with the person who has Joytron EX Force to check whether this is usable for him.

robertkirkman avatar May 01 '23 07:05 robertkirkman