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

[Experimental] Native android export #246

Merged
merged 25 commits into from
Apr 9, 2016
Merged

[Experimental] Native android export #246

merged 25 commits into from
Apr 9, 2016

Conversation

4ian
Copy link
Owner

@4ian 4ian commented Feb 9, 2016

I've made some refactoring and made an experimental exporter to see if SFML powered games could be run on Android.
I've made a really quick explanation about it here: http://4ian.github.io/GD-Documentation/GDCpp%20Documentation/d5/dfa/class_android_exporter.html

The result is that simple games are working, with great performances but I've got some graphical glitches with some objects and weird crash from time to time on a larger game.

I'll probably merge this even if the Android exporter is not working as it's not visible for end users for now and there are some improvements nevertheless.

@victorlevasseur
Copy link
Contributor

Which version of SFML should I use ?

@4ian
Copy link
Owner Author

4ian commented Feb 10, 2016

Use the latest master from https://github.com/SFML/SFML : clone it and follow Retrieving and Building SFML from https://github.com/SFML/SFML/wiki/Tutorial:-Building-SFML-for-Android (build and install armeabi-v7a for devices and/or x86 for simulator like genymotion). Once you've exported a game, do ndk-build, ant debug and adb install as explained in Building and Executing the Android Example.

Note that by default, exported game are built for x86. You can change these lines in jni/Application/mk :

APP_ABI := armeabi-v7a
# APP_ABI := x86

and then re-run ndk-build and the other commands to build an APK for an Android phone. :)

@victorlevasseur
Copy link
Contributor

If I understood correctly the process, there's no need to update the SFML version used by GDevelop itself ?

@4ian
Copy link
Owner Author

4ian commented Feb 10, 2016

Exactly, what the exporter creates is a stand-alone project which can be compiled with a Android SDK/NDK in which there is a version of SFML installed. This version of SFML installed in the Android NDK is totally different.

@victorlevasseur
Copy link
Contributor

I get an error when previewing a native game inside GDevelop (with this exporter enabled) :

cc1plus.exe : No such file or directory

Don't know if it's related to the change of Exporter

EDIT: It's related to the change of exporter as it works in the last GDevelop version.

EDIT: It's seems that it's caused by the compiler version I use (5.1.0)

@4ian
Copy link
Owner Author

4ian commented Feb 10, 2016

Mmm sounds strange to me that the exporter broke the code to launch the compiler.
Did you updated it recently?

@victorlevasseur
Copy link
Contributor

No, I'm trying again with TDM-GCC 4.9.2...

@victorlevasseur
Copy link
Contributor

That's strange. The official GDevelop is working but not the one I built myself (even with MinGW 4.9.2). I still have this error message.

@victorlevasseur
Copy link
Contributor

There's no problem with the master branch. The problem only occurs on this branch (no matter if I enable the AndroidExporter or not).

By the way, the AppVeyor check fails, maybe related.

EDIT: I think the error message is badly parsed by GDevelop. So, the error is not that cc1plus.exe is not found but that the precompiled headers are not found

@victorlevasseur
Copy link
Contributor

I should have looked at the compilation log (instead of the error panel of GDevelop), the full error message is :

cc1plus.exe: fatal error: E:\Developpement\GD\Binaries\Output\Release_Windows/CppPlatform/include/GDCpp/GDCpp/Runtime/EventsPrecompiledHeader.h: No such file or directory

compilation terminated.

@victorlevasseur
Copy link
Contributor

The commit I merged in your branch fix the issue (and also include the Extensions includes).

@victorlevasseur
Copy link
Contributor

I had another problem when doing ndk-build on Windows :

jni/main.cpp:105:57: error: invalid conversion from 'int (*)(RuntimeContext*)' to 'void*' [-fpermissive]
           if (scene->GetName() == "New scene") function = &GDSceneEventsNew_32scene;
                                                         ^
jni/main.cpp:110:68: error: no matching function for call to 'CodeExecutionEngine::LoadFunction(void**)'
             scene->GetCodeExecutionEngine()->LoadFunction(&function);

I'll send a commit that fix it soon.

TiledSpriteObject is displayed correctly on Android devices
@4ian
Copy link
Owner Author

4ian commented Feb 10, 2016

(The platformer game works perfectly on my Nexus 7 2013 tablet)

I'll check again with the updates made to TiledSpriteObject :)
I had a crash during a scene change, could you try a game with more than one scene?

EDIT: Forget the rest, I made some mismatches with my folders :)
Also I can't compile anymore with ndk-build:

Users/florian/Desktop/android-export/jni/Extensions/TextObject/Extension.cpp:26:62: error: expected primary-expression before '>' token
     gd::ObjectMetadata & obj = extension.AddObject<TextObject>(

Any idea why? I merged your changes related to templated object creation before doing the PR but I guess I didn't check the Android compilation was still working for me. That's strange.

@victorlevasseur
Copy link
Contributor

Is TextObject.h included ?

Le mer. 10 févr. 2016 à 18:56, Florian Rival notifications@github.com a
écrit :

(The platformer game works perfectly on my Nexus 7 2013 tablet)

I'll check again with the updates made to TiledSpriteObject :)
I had a crash during a scene change, could you try a game with more than
one scene?

Also I can't compile anymore with ndk-build:

Users/florian/Desktop/android-export/jni/Extensions/TextObject/Extension.cpp:26:62: error: expected primary-expression before '>' token
gd::ObjectMetadata & obj = extension.AddObject(

Any idea why? I merged your changes related to templated object creation
before doing the PR but I guess I didn't check it was still working for me.
That's strange.


Reply to this email directly or view it on GitHub
#246 (comment).

@victorlevasseur
Copy link
Contributor

Are you sure the GDCore/GDCpp file are updated in GDevelop folder and in
the exportation folder (it seems that if the file already exists, it's not
replaced) ? Because it's working perfectly on my side.

Le mer. 10 févr. 2016 à 19:11, Victor Levasseur victorlevasseur52@gmail.com
a écrit :

Is TextObject.h included ?

Le mer. 10 févr. 2016 à 18:56, Florian Rival notifications@github.com a
écrit :

(The platformer game works perfectly on my Nexus 7 2013 tablet)

I'll check again with the updates made to TiledSpriteObject :)
I had a crash during a scene change, could you try a game with more than
one scene?

Also I can't compile anymore with ndk-build:

Users/florian/Desktop/android-export/jni/Extensions/TextObject/Extension.cpp:26:62: error: expected primary-expression before '>' token
gd::ObjectMetadata & obj = extension.AddObject(

Any idea why? I merged your changes related to templated object creation
before doing the PR but I guess I didn't check it was still working for me.
That's strange.


Reply to this email directly or view it on GitHub
#246 (comment).

@4ian
Copy link
Owner Author

4ian commented Feb 10, 2016

No worries my directories were all messed up :)

@victorlevasseur
Copy link
Contributor

I'll try (I manage to make ndk-gdb works)

Le mer. 10 févr. 2016 à 19:35, Florian Rival notifications@github.com a
écrit :

No worries my directories were all messed up :)


Reply to this email directly or view it on GitHub
#246 (comment).

@4ian
Copy link
Owner Author

4ian commented Feb 10, 2016

The game is was testing on my phone is now crashing on startup :/ But working great on the simulator.
I'll check if it's working again by going back to a previous commit. There is still a crash when changing a scene, looks like it's not related to SFML or OpenGL (but in this case, it should work on desktop too).
I'll send you the game if you're interested to see if we can find why it's crashing.

@victorlevasseur
Copy link
Contributor

I've no crashes when changing scenes on my tablet.

You can try to launch the game with ndk-gdb (ndk-gdb-py on Windows) to see where the crash is happening.

@victorlevasseur
Copy link
Contributor

Which game were you trying ? (I'm testing with the platformer project template)

@4ian
Copy link
Owner Author

4ian commented Feb 11, 2016

The crash on startup was related to a compilation mismatch between x86/armv7 ^^' (better use ndk-build clean if you're unsure, to clean every object file).
So TiledSprite are rendered properly now and performance looks good! 👍

For the crash on scene changing, it's in one of my games, I'll dig a bit to see what's going on and/or if I can reproduce it in an example. I tried ndk-gdb but no stack trace (only function named "????"). I took a look at the devices logs and got a stack trace (will put it here later), but it was changing between runs. Often it crashed while deallocating objects related to the platform behavior.

@4ian
Copy link
Owner Author

4ian commented Feb 11, 2016

@victorlevasseur Here is a minimal example: crash-example.zip

Export/compile/launch it, click on the big button in the center on Android and it will crash. It's surely related to the platforms but I'm not sure why.

@victorlevasseur
Copy link
Contributor

I'll try ASAP

@4ian
Copy link
Owner Author

4ian commented Feb 12, 2016

Cool let me know if you can reproduce the crash and if you have any idea on how to debug it efficiently :)

@victorlevasseur
Copy link
Contributor

It also crashes on my tablet. Investigating...

@victorlevasseur
Copy link
Contributor

It get a stack trace from ndk-gdb :

#0  0xaee21e44 in __tree_is_left_child<std::__1::__tree_node_base<void*>*> (
    __x=0xaec5d174)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/__tree:68
#1  std::__1::__tree_next<std::__1::__tree_node_base<void*>*> (__x=0xaec5d174)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/__tree:159
#2  0xaef60824 in operator++ (this=<optimized out>)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/__tree:747
#3  ScenePlatformObjectsManager::~ScenePlatformObjectsManager (
    this=0xaec5d16c, __in_chrg=<optimized out>)
    at jni/Extensions/PlatformBehavior/ScenePlatformObjectsManager.cpp:8
#4  0xaef5b040 in std::__1::pair<RuntimeScene* const, ScenePlatformObjectsManager>::~pair (this=0xaec5d168, __in_chrg=<optimized out>)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/utility:248
#5  0xaef5a4b0 in ~__value_type (this=0xaec5d168, __in_chrg=<optimized out>)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/map:617
#6  __destroy<std::__1::__value_type<RuntimeScene*, ScenePlatformObjectsManager> > (__p=0xaec5d168)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/memory:1589
#7  destroy<std::__1::__value_type<RuntimeScene*, ScenePlatformObjectsManager> > (__p=0xaec5d168, __a=...)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/memory:1487
#8  std::__1::__tree<std::__1::__value_type<RuntimeScene*, ScenePlatformObjectsManager>, std::__1::__map_value_compare<RuntimeScene*, std::__1::__value_type<RuntimeScene*, ScenePlatformObjectsManager>, std::__1::less<RuntimeScene*>, true>, std::__1::allocator<std::__1::__value_type<RuntimeScene*, ScenePlatformObjectsManager> > >::erase (
    this=0xaf09f358 <ScenePlatformObjectsManager::managers>, __p=...)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/__tree:1985
#9  0xaef59f20 in std::__1::__tree<std::__1::__value_type<RuntimeScene*, ScenePlatformObjectsManager>, std::__1::__map_value_compare<RuntimeScene*, std::__1::__value_type<RuntimeScene*, ScenePlatformObjectsManager>, std::__1::less<RuntimeScene*>, true>, std::__1::allocator<std::__1::__value_type<RuntimeScene*, ScenePlatformObjectsManager> > >::__erase_unique<RuntimeScene*> (
    this=0xaf09f358 <ScenePlatformObjectsManager::managers>, __k=
    @0xab4e8254: 0xa27ff810)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/__tree:2007
#10 0xaef589e4 in erase (__k=<optimized out>, this=<optimized out>)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/map:1077
#11 PlatformBehaviorCppExtension::SceneUnloaded (this=0xa2693500, scene=...)
    at jni/Extensions/PlatformBehavior/Extension.cpp:462
#12 0xaee70304 in RuntimeScene::~RuntimeScene (this=0xa27ff810,
    __in_chrg=<optimized out>) at jni/GDCpp/GDCpp/Runtime/RuntimeScene.cpp:69
#13 0xaee9b204 in std::__1::__shared_ptr_emplace<RuntimeScene, std::__1::allocator<RuntimeScene> >::__on_zero_shared (this=0xa27ff800)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/memory:3738
#14 0xb3a7e22c in __release_shared (this=0xa27ff800)
    at /tmp/ndk-user/tmp/build-libc++/ndk/sources/cxx-stl/llvm-libc++/libcxx/src/memory.cpp:61
#15 std::__1::__shared_weak_count::__release_shared (this=0xa27ff800)
    at /tmp/ndk-user/tmp/build-libc++/ndk/sources/cxx-stl/llvm-libc++/libcxx/src/memory.cpp:86
#16 0xaee99950 in std::__1::shared_ptr<RuntimeScene>::~shared_ptr (
    this=0xab4e831c, __in_chrg=<optimized out>)
    at E:/Developpement/Outils/android-ndk-r10e/sources/cxx-stl/llvm-libc++/libcxx/include/memory:4448
#17 0xaee98c5c in SceneStack::Step (this=0xab4e86b0)
    at jni/GDCpp/GDCpp/Runtime/SceneStack.cpp:36
#18 0xaef4e37c in main (argc=0, argv=0x0) at jni/main.cpp:120
#19 0xaee1f73a in sf::priv::main(sf::priv::ActivityStates*) ()
   from E:\Developpement\GDevelop-android-export\obj\local\armeabi-v7a\libsfml-example.so
#20 0xb3b53e72 in sf::priv::ThreadImpl::entryPoint(void*) ()
   from E:\Developpement\GDevelop-android-export\obj\local\armeabi-v7a\libsfml-system.so
#21 0xb6d41460 in __pthread_start(void*) ()
   from E:\Developpement\GDevelop-android-export\obj\local\armeabi-v7a\libc.so
#22 0xb6d1bb44 in __start_thread ()
   from E:\Developpement\GDevelop-android-export\obj\local\armeabi-v7a\libc.so
#23 0x00000000 in ?? ()

@4ian
Copy link
Owner Author

4ian commented Feb 17, 2016

Nice stacktrace (much more complete than the ones I had), seems related to ScenePlatformObjectsManager and scene unloading!

@blurymind
Copy link
Contributor

This is awesome progress guys. Gaining native android support will attract a lot of new users

@4ian
Copy link
Owner Author

4ian commented Mar 1, 2016

I'm also experimenting with another alternative: using Cocos2d game engine, which would bring cross platform/JS compatibility with native rendering on Android/iOS/Mac/Windows/Linux and HTML5 for web games. :)

@4ian
Copy link
Owner Author

4ian commented Mar 1, 2016

See this issue for discussions about this alternative: #238 😃

@blurymind
Copy link
Contributor

I've heard a lot of good things about cocos2d in the past. It is a very solid and battle tested as a mobile game development engine- both games and apps. If you manage to integrate it with gd you will also have to maintain only one engine rather than two. The other advantage of course would be the updates that it gets. It seems like a better choice than further implementing sfml, but also a lot more work. I think it would be worth it in the long run as it is more advantageous

@victorlevasseur
Copy link
Contributor

Did you manage to catch the Platformer bug ?
I may have an idea (I'll test it as soon as I can get my tablet) :

for (std::set<PlatformBehavior*>::iterator it = allPlatforms.begin();
         it != allPlatforms.end();
         ++it)
{
    (*it)->Activate(false);
}

Here Activate(false) deactivates the platform behavior but also removes the platform from the ScenePlatformObjectsManager (by calling OnDeActivate() of the behavior :

void PlatformBehavior::OnDeActivate()
{
    if ( sceneManager )
        sceneManager->RemovePlatform(this);

    registeredInManager = false;
}

By removing the platform while iterating on it, it may invalidate the it iterator and cause a crash in the next instruction using it : ++it of the for loop.

It seems like a better choice than further implementing sfml

Personally, I still think SFML is the best choice as it does request less things to be installed (except when you want to build your game for Android) compared to Cocos2d.

@victorlevasseur
Copy link
Contributor

The platformer behavior should be fixed now. :D

@4ian
Copy link
Owner Author

4ian commented Mar 6, 2016

Awesome, thanks for the debugging! Will try it soon :)

@4ian 4ian merged commit d33042c into master Apr 9, 2016
@4ian 4ian deleted the feature/native-android branch April 14, 2016 17:55
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.

3 participants