schellingb / ZillaLib

Sleek multiplatform C++ 2D and 3D game creation!
https://zillalib.github.io/
zlib License
109 stars 8 forks source link

Problems on Android #5

Closed tobybear closed 4 years ago

tobybear commented 5 years ago

So I had the chance to test some of the Android builds of ZillaLib samples and games on some Android phones from the last 5 years (mainly Samsung), with Android versions between 7 and 10, with not so great results.

On Android 8 and 9, you will get a warning message if you run a ZillaLib compiled apk: "This app was built for an older version of Android and may not work properly. Try checking for updates, or contact the developer." On my S9, it won't even run the apk unless I enable developer mode. On other systems, it at least runs the app afterwards. The warning is apparently issued for any apk built for an Android version below Android 6.

The Google Play Store now has a minimum requirement of target API level 26 for an app (meaning minimum Android version 8), everything else is not supported, so you can't submit a ZillaLib apk to the Google Play store.

Here is some more info about these topics: https://www.xda-developers.com/android-q-warn-apps-target-android-lollipop/

Furthermore, another message will be displayed when trying to switch to fullscreen: "This application might not work in full screen mode". For all the ZillaLib apps I tried, it tries to switch to fullscreen mode then, fails, and returns to normal mode with the menu bar, but with a different resolution (see below). This might have something to do with the overhaul of fullscreen options in later Android versions and the various ways to achieve full screen (https://developer.android.com/training/system-ui/immersive).

Another problem I ran into is switching back and forth between apps - the screen size then changes, making the content appear distorted. Here is an example when first running the app: screen1 And when switching back and forth (or just opening the running task window): screen2

Other apps don't work correctly at all concerning screen space: screen3

And another big issue: when an app is sent into the background, most of them are automatically terminated by the system after some time or under some conditions. I haven't look into the details yet, but it is very common on recent Android versions that if you switch from a game to another app, e.g. to quickly check a message or answer a call, then get back to the game, it will continue where you left it, unless a certain amount of time has passed and the game app will be reloaded. For ZillaLib apps, this seems to always be the case however, so when I run for example "Lazer Maze", then quickly switch to my browser, then back to the game, it will start the app from the beginning, as it was apparently unloaded on task switch. I assume this has something to do with using an older SDK.

And finally, almost all of the games on the ZillaLib page I couldn't get in a usable state on Android, since they all require keyboard inputs (cursor keys, space, enter, escape) and no virtual keyboard or a mapping of touch inputs to keys is provided (like in other SDKs/APIs), so there is no way I could control for example the player in Lazer Maze.

I guess there are some similar problems with iOS on iPhones (usually Apple is even more strict and deprecates versions much faster than Android or Windows).

It really sucks to see how fragmented and complicated it has bceome to develop for just the main platforms and I would love to see a simple, lightweight, all-in-one solution now that SDL2, SFML, Cocos2d-x and others have become so bloated and buggy.

schellingb commented 5 years ago

Hey again, thanks for the detailed write-up of the issues at hand.

This seems to be the current rules: https://developer.android.com/distribute/best-practices/develop/target-sdk

Not only do they want API level 28, but also 64-bit native binaries included. I tried to setup Android Studio with the Android Emulator but Google does not provide Arm64 emulator images for anything newer than Android 7.0 (API level 28). I then tried to use the system images built by ci.android.com (i.e. aosp_arm64-eng ) but the emulator refuses to boot it so far. Hopefully I can succeed somehow.

The next step would be to build with targetSdkVersion 29 while still keeping minSdkVersion at 9 for now, both in 32bit and 64bit mode. If that works smooth we could also enable builds for non-arm cpus if it's just an additional switch/flag in the makefile.

If it then somehow runs on Android 10, next would be to try to fix the problems you mentioned (screen resolutions, full screen, returning from standby) one-by-one.

Also you're right, the sample games Lazer Maze, Altar War and StealthMan make no sense to have an APK for download as they don't have mouse/touch support as mentioned. I usually use the build-all tool which just builds for all platforms (except iOS) and put it on the website without thinking. Maybe I can copy the onscreen D-Pad from Puzilla over to them, that would be nicer than removing the APKs.

tobybear commented 5 years ago

Thanks, that sounds like a good approach! At the moment I have important projects in my build environments, so I can't experiment with the Android SDK myself, but I will gladly test any apk on some of my devices and report back.

schellingb commented 5 years ago

Emulator is still stuck in a boot loop but building against SDK 29 worked out of the box. Adding the flag -Xlint:deprecation to the java compilation showed the following 3 issues... only 3? :-)

ZillaActivity.java:74: warning: [deprecation] ACTION_MULTIPLE in KeyEvent has been deprecated
if (keyCode == KeyEvent.KEYCODE_UNKNOWN && action == KeyEvent.ACTION_MULTIPLE)

ZillaActivity.java:75: warning: [deprecation] getCharacters() in KeyEvent has been deprecated
NativeText(event.getCharacters());

ZillaActivity.java:261: warning: [deprecation] vibrate(long) in Vibrator has been deprecated
((android.os.Vibrator)getSystemService(Context.VIBRATOR_SERVICE)).vibrate(durationMs);

I attached the output APK wrapped in ZIP because GitHub doesn't allow .apk files: Hexzilla-SDK29.apk.zip I think I'm going to try to find my google play dev account and try if I can use their APK validator to at least tell me how close we are to being allowed.

tobybear commented 5 years ago

This version now starts without a warning on Android 9! The screen is still messed up and requires some task switching before properly being displayed correctly. Oh, and switching back without the app being reloaded now also seems to work!

schellingb commented 5 years ago

Had a bit of a roller-coaster ride with the newest NDK r20. First I was utterly shocked that it uses up almost 3 GB of disk space while my previous (ARM only) r10 installation is just under 200 MB.

Because Google dropped support for both gcc and stlport it now compiles with the only choice that is clang with libc++. I was worried at first and a small game compiled to a .so with 253 kb. Not the end of the world but with R10 it resulted in only 164 kb. I ended up writing a script that sorts the symbol sizes reported in the linkers map file output and noticed a lot of space is taken up by things with "itanium_demangle" in the name. I couldn't find a way to get rid of it until I stumbled onto this useful blog post and the comment on it: How to make smaller C and C++ binaries

So I achieved these optimizations:

This resulted in a 181 kb .so file. I guess adding 17kb is fine to be let back into the play store.

I then tried overwriting some more internal functions all related to exceptions and ended up with a 169 kb file which still ran perfectly fine on my Android 6 phone. But while overwriting __cxa_demangle did not require a special linker switch, I had to set --allow-multiple-definition for this to work. Which is a bit too much I think.

It kinda sucks that compiling the entire project with exceptions disabled still adds 60 kb of exceptions related overhead because the prebuilt libraries like libc++ that come with the NDK were built with exceptions enabled.

Also the 64bit ARM variation of the same file is 297 kb which is a bit sad as well...

tobybear commented 5 years ago

Great job with the research and optimisations! And funny, that same optimisations link is also in my own bookmarks for some years now, hehe. Yeah, the size of the Android SDK has become enormous and the whole tendency of the software industry in general to no longer really care about small and clean libraries and applications is really sad.

schellingb commented 5 years ago

So I updated the android build process to process, build and sign as many ABI targets as one wants.

I then used the x86_64 build in the emulator to fix some things related to the screen being messed up after coming back from switching out of the game once. It was correct initially so I'm not sure I get what you had.

I also got back into my Google Play developer console and I was able to submit an alpha release for ARM 32 and 64 bit. It shows a big fat warning that my APK is not as optimized as it could be and if I only would give google an unsigned package and let them handle some parts of building and signing it would be so much better. I don't think they can make it that much smaller than 200 kb. I'm now waiting for their so called pre-launch report to tell me everything that is still wrong.

I assume your phone has 64 bit capability so I'd be grateful if you could try the attached APK. Hexzilla-arm64-v8a.apk.zip

tobybear commented 5 years ago

Ok, so I tested the latest version with a Samsung S9+, and it is much improved! It does now work correctly with the resolution, even after switching tasks, and the game state is also retained. Also, no warning messages or security issues! I also noticed that there is no longer the default Android "Switch to Fullscreen" option, and I don't see an option from within the game to trigger/test switching to full screen.

schellingb commented 4 years ago

And suddenly two weeks passed. Most of the issues mentioned in this thread should be fixed by the big 4eb25a44bf1fa9054e8457d07451099bcfd3bbc6 commit.

Because the latest NDK does not build for platforms older than 16 (Android 4.1 aka Jelly Bean) this is now the minimum for ZillaLib built games as well. Until now we were compatible way back to 9 (Android 2.3 aka Gingerbread). Builds also targets the latest SDK 29 (Android 10) and the created APKs are accepted by the Google Play store and pass all their device tests.

The README.md for Android was updated with installation instructions for the latest SDK & NDK and explanation how to build for multiple ABIs (all 4 NDK ABIs arm, arm64, x86, x86_64 are supported). Also the project generator has new options to select the target SDK and ABIs to build for.

Built games now show in immersive mode (hiding the navigation bar) by default, which can be disabled with a flag to get the old behavior back.

And all the sample games on the website come with some sort of touch controls in the Android builds.

Thanks again for reporting and testing!!

tobybear commented 4 years ago

This is incredible! Thank you very much! I will do some testing in the next days and report back should I find any issues.

tobybear commented 4 years ago

Did some quick tests with the new LazerMaze, and things are looking pretty good!

Touch input works, although a bit clunky/hard to control, but this can probably be improved easily for actual games.

I noticed it still showed the system navigation bar while the game was running on my phone (S9). Not sure if the flag is set to that in the code though?

Also, the added "showTouchUI" variable seems to be used incorrectly in the code, as it is set initially to true on smartphones (by checking the presence of the SMARTPHONE define), but is then used as a toggle in the update function. Meaning when you press the back key on your phone, it will set the showTouchUI variable to false, so displaying incorrectly the "Press [ESC] again to quit" message, then when touching the screen it will toggle again and the message switches to "Press [BACK] again to quit". This however is just a minor issue, unrelated to the Android SDK integration.

Great work!

schellingb commented 4 years ago

Thanks again for testing!

I started writing this post by saying that I couldn't find a better (simple) way to make LazerMaze play better but then ended up coming up with a fairly good solution. Movement is now not relative to the player position (making it hard to move near the edge of the screen) but relative to where touch started. This seems to control quite nice.

Also thanks for noticing my goof with showTouchUI and the back button. I thought I was clever for allowing touch UI on any platform (mostly so the WebAssembly version can use them on mobile devices as well) but then messed that up. Mapping the BACK key to Escape was always a bit wonky albeit convenient.

Regarding the navigation bar on the S9 I'm a bit stumped. This is how it looks for me on the Android 10 emulator: image For a brief second initially the bar is still visible, then the game resizes over the bar and the navigation buttons slide away to the right. It is the same behavior as on my Nexus 5 with Android 6.

Some interesting discussion regarding immersive mode on S8 is here: https://stackoverflow.com/questions/43694526/samsung-galaxy-s8-full-screen-mode First answer is about manifest changes which I think we've covered with our global android:resizeable="true". The second answer says to use the visibility flags SYSTEM_UI_FLAG_LAYOUT_STABLE|SYSTEM_UI_FLAG_IMMERSIVE_STICKY|SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN|SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION|SYSTEM_UI_FLAG_FULLSCREEN|SYSTEM_UI_FLAG_HIDE_NAVIGATION while currently we only use SYSTEM_UI_FLAG_IMMERSIVE_STICKY|SYSTEM_UI_FLAG_HIDE_NAVIGATION. Then someone mentions that an app needs to be set as full-screen app in the settings under Display → Full Screen Apps. Do you have that option in the settings on the S9?

tobybear commented 4 years ago

Screenshot_20191103-185343 Here is how it looks on my phone

tobybear commented 4 years ago

20191103_185303 And yes, I have the menu settings for fullscreen apps, but it can't be changed for LazerMaze as it is apparently already recognized as a fs app

tobybear commented 4 years ago

Ah, wait, it is working now! Previously I just updated the app, but after deinstalling and reinstalling it, it works correctly now! Probably some old setting was still active in the system for that app.

schellingb commented 4 years ago

Oh! Awesome!! Great to hear.

I just built an APK with SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | SYSTEM_UI_FLAG_FULLSCREEN added to the flags but I guess that's not necessary after all. Reverting that :-)

tobybear commented 4 years ago

Wohoo, cool! I can also confirm touch input is now recognized in the web builds (this was actually going to be one of my next requests), however it seems to have broken something as for example in LazerMaze (web on phone), the screen keeps zooming in and out. I think touch input is recognized here both for the game as well as for the mobile browser.

schellingb commented 4 years ago

Marked the issue as closed. I think we're in a decent state for 2019 :-)

I added multi-touch support for the WebAssembly platform so the sample games on the website with on-screen touch controls like Altar War and Puzilla actually play quite well on the phone, especially with the new fullscreen button.

Not sure if that fixes the mentioned problem where two-fingers on the game screen affect the page-zoom. I can't replicate that neither on my phone nor the emulator.

tobybear commented 4 years ago

Thank you, that did indeed fix the zoom/pinch issue. Control scheme on Altar War is also great! LazerMaze runs unbearably slow on my phone in web, not sure why, Altar War runs way better. The only issue I came across with the WebAssembly build is that they don't switch to landscape mode in full screen, and if you have your phone in portrait-locked mode (probably most users) you won't be able to play the game unless you switch auto-screen-rotation on in the Android settings. Screenshot_20191111-171810_Samsung Internet Screenshot_20191111-172412_Samsung Internet

Screenshot_20191111-172205_Samsung Internet

schellingb commented 4 years ago

Thanks for the quick test and feedback!

Regarding orientation in viewscreen, I saw that and was like "well that's how it should be I guess". But now that you mention it, we know it's web and it is running fullscreen, we could just transform the view ourselves to be landscape. In theory someone could have a monitor on a PC that is taller than wide and it would turn there as well but I guess that is rarer then the mobile device that can be rotated in the users hand.

LazerMaze runs fairly bad on my phone as well, I should look into why that is.

I also tried Safari on a latest iOS device, things aren't looking as good there. Sound and fullscreen does not work. Would be nice if that was improved as well... Oh web, always so fragmented :-)

tobybear commented 4 years ago

Interestingly though, LazerMaze switches automatically to landscape, it seems, just gets some proportions wrong