Browse Source

Fixed Android linking & startup issues.

Lasse Öörni 13 năm trước cách đây
mục cha
commit
65378ee15b

+ 1 - 1
Android/AndroidManifest.xml

@@ -4,7 +4,7 @@
       android:versionCode="1"
       android:versionName="1.0">
     <application android:label="@string/app_name" android:icon="@drawable/icon">
-        <activity android:name="Urho3D"
+        <activity android:name="SDLActivity"
                   android:label="@string/app_name">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />

+ 4 - 4
Android/jni/Android.mk

@@ -25,6 +25,7 @@ LOCAL_MODULE := Bullet
 
 LOCAL_SRC_FILES := \
     $(subst $(LOCAL_PATH)/,, \
+    $(wildcard $(LOCAL_PATH)/src/BulletCollision/BroadPhaseCollision/*.cpp) \
     $(wildcard $(LOCAL_PATH)/src/BulletCollision/CollisionDispatch/*.cpp) \
     $(wildcard $(LOCAL_PATH)/src/BulletCollision/CollisionShapes/*.cpp) \
     $(wildcard $(LOCAL_PATH)/src/BulletCollision/Gimpact/*.cpp) \
@@ -150,8 +151,6 @@ LOCAL_SRC_FILES := \
     $(wildcard $(LOCAL_PATH)/src/cpuinfo/*.c) \
     $(wildcard $(LOCAL_PATH)/src/events/*.c) \
     $(wildcard $(LOCAL_PATH)/src/file/*.c) \
-    $(wildcard $(LOCAL_PATH)/src/haptic/*.c) \
-    $(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \
     $(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
     $(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
     $(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c) \
@@ -240,7 +239,7 @@ LOCAL_C_INCLUDES := \
     $(LOCAL_PATH)/ThirdParty/SDL/include \
     $(LOCAL_PATH)/ThirdParty/Squish \
     $(LOCAL_PATH)/ThirdParty/StanHull \
-    $(LOCAL_PATH)/ThirdParty/STB \
+    $(LOCAL_PATH)/ThirdParty/STB
 
 LOCAL_SRC_FILES := \
     $(subst $(LOCAL_PATH)/,, \
@@ -259,7 +258,8 @@ LOCAL_SRC_FILES := \
     $(wildcard $(LOCAL_PATH)/Engine/Scene/*.cpp) \
     $(wildcard $(LOCAL_PATH)/Engine/Script/*.cpp) \
     $(wildcard $(LOCAL_PATH)/Engine/UI/*.cpp) \
-    $(wildcard $(LOCAL_PATH)/Urho3D/*.cpp))
+    $(wildcard $(LOCAL_PATH)/Urho3D/*.cpp) \
+    $(wildcard $(LOCAL_PATH)/ThirdParty/SDL/src/main/android/*.cpp))
 
 LOCAL_STATIC_LIBRARIES := AngelScript Bullet FreeType kNet PugiXml SDL Squish StanHull STB
 

+ 1 - 1
Android/res/values/strings.xml

@@ -1,4 +1,4 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <string name="app_name">SDL App</string>
+    <string name="app_name">Urho3D</string>
 </resources>

+ 47 - 30
Android/src/org/libsdl/app/SDLActivity.java

@@ -1,3 +1,5 @@
+// Modified by Lasse Öörni for Urho3D
+
 package org.libsdl.app;
 
 import javax.microedition.khronos.egl.EGL10;
@@ -38,26 +40,24 @@ public class SDLActivity extends Activity {
     private static AudioTrack mAudioTrack;
 
     // EGL private objects
-    private static EGLContext  mEGLContext;
-    private static EGLSurface  mEGLSurface;
-    private static EGLDisplay  mEGLDisplay;
-    private static EGLConfig   mEGLConfig;
-    private static int mGLMajor, mGLMinor;
+    private EGLContext  mEGLContext;
+    private EGLSurface  mEGLSurface;
+    private EGLDisplay  mEGLDisplay;
+    private EGLConfig   mEGLConfig;
+    private int mGLMajor, mGLMinor;
+
+    private boolean mFinished = false;
 
     // Load the .so
     static {
-        System.loadLibrary("SDL2");
-        //System.loadLibrary("SDL2_image");
-        //System.loadLibrary("SDL2_mixer");
-        //System.loadLibrary("SDL2_ttf");
-        System.loadLibrary("main");
+        System.loadLibrary("Urho3D");
     }
 
     // Setup
     protected void onCreate(Bundle savedInstanceState) {
         //Log.v("SDL", "onCreate()");
         super.onCreate(savedInstanceState);
-        
+
         // So we can call stuff from static callbacks
         mSingleton = this;
 
@@ -83,6 +83,9 @@ public class SDLActivity extends Activity {
     protected void onDestroy() {
         super.onDestroy();
         Log.v("SDL", "onDestroy()");
+        
+        mFinished = true;
+
         // Send a quit message to the application
         SDLActivity.nativeQuit();
 
@@ -97,10 +100,13 @@ public class SDLActivity extends Activity {
 
             //Log.v("SDL", "Finished waiting for SDL thread");
         }
+
+        mSingleton = null;
     }
 
     // Messages from the SDLMain thread
     static int COMMAND_CHANGE_TITLE = 1;
+    static int COMMAND_FINISH = 2;
 
     // Handler for the messages
     Handler commandHandler = new Handler() {
@@ -108,6 +114,12 @@ public class SDLActivity extends Activity {
             if (msg.arg1 == COMMAND_CHANGE_TITLE) {
                 setTitle((String)msg.obj);
             }
+            if (msg.arg1 == COMMAND_FINISH) {
+                if (mFinished == false) {
+                    mFinished = true;
+                    finish();
+                }
+            }
         }
     };
 
@@ -148,6 +160,10 @@ public class SDLActivity extends Activity {
         // Called from SDLMain() thread and can't directly affect the view
         mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
     }
+    
+    public static void finishActivity() {
+        mSingleton.sendCommand(COMMAND_FINISH, null);
+    }
 
     public static Context getContext() {
         return mSingleton;
@@ -166,7 +182,7 @@ public class SDLActivity extends Activity {
 
     // EGL functions
     public static boolean initEGL(int majorVersion, int minorVersion) {
-        if (SDLActivity.mEGLDisplay == null) {
+        if (SDLActivity.mSingleton.mEGLDisplay == null) {
             //Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion);
 
             try {
@@ -207,10 +223,10 @@ public class SDLActivity extends Activity {
                     return false;
                 }
                 SDLActivity.mEGLContext = ctx;*/
-                SDLActivity.mEGLDisplay = dpy;
-                SDLActivity.mEGLConfig = config;
-                SDLActivity.mGLMajor = majorVersion;
-                SDLActivity.mGLMinor = minorVersion;
+                SDLActivity.mSingleton.mEGLDisplay = dpy;
+                SDLActivity.mSingleton.mEGLConfig = config;
+                SDLActivity.mSingleton.mGLMajor = majorVersion;
+                SDLActivity.mSingleton.mGLMinor = minorVersion;
 
                 SDLActivity.createEGLSurface();
             } catch(Exception e) {
@@ -228,9 +244,9 @@ public class SDLActivity extends Activity {
     public static boolean createEGLContext() {
         EGL10 egl = (EGL10)EGLContext.getEGL();
         int EGL_CONTEXT_CLIENT_VERSION=0x3098;
-        int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE };
-        SDLActivity.mEGLContext = egl.eglCreateContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs);
-        if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) {
+        int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mSingleton.mGLMajor, EGL10.EGL_NONE };
+        SDLActivity.mSingleton.mEGLContext = egl.eglCreateContext(SDLActivity.mSingleton.mEGLDisplay, SDLActivity.mSingleton.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs);
+        if (SDLActivity.mSingleton.mEGLContext == EGL10.EGL_NO_CONTEXT) {
             Log.e("SDL", "Couldn't create context");
             return false;
         }
@@ -238,26 +254,26 @@ public class SDLActivity extends Activity {
     }
 
     public static boolean createEGLSurface() {
-        if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) {
+        if (SDLActivity.mSingleton.mEGLDisplay != null && SDLActivity.mSingleton.mEGLConfig != null) {
             EGL10 egl = (EGL10)EGLContext.getEGL();
-            if (SDLActivity.mEGLContext == null) createEGLContext();
+            if (SDLActivity.mSingleton.mEGLContext == null) createEGLContext();
 
             Log.v("SDL", "Creating new EGL Surface");
-            EGLSurface surface = egl.eglCreateWindowSurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null);
+            EGLSurface surface = egl.eglCreateWindowSurface(SDLActivity.mSingleton.mEGLDisplay, SDLActivity.mSingleton.mEGLConfig, SDLActivity.mSingleton.mSurface, null);
             if (surface == EGL10.EGL_NO_SURFACE) {
                 Log.e("SDL", "Couldn't create surface");
                 return false;
             }
 
-            if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
+            if (!egl.eglMakeCurrent(SDLActivity.mSingleton.mEGLDisplay, surface, surface, SDLActivity.mSingleton.mEGLContext)) {
                 Log.e("SDL", "Old EGL Context doesnt work, trying with a new one");
                 createEGLContext();
-                if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
+                if (!egl.eglMakeCurrent(SDLActivity.mSingleton.mEGLDisplay, surface, surface, SDLActivity.mSingleton.mEGLContext)) {
                     Log.e("SDL", "Failed making EGL Context current");
                     return false;
                 }
             }
-            SDLActivity.mEGLSurface = surface;
+            SDLActivity.mSingleton.mEGLSurface = surface;
             return true;
         }
         return false;
@@ -274,7 +290,7 @@ public class SDLActivity extends Activity {
 
             egl.eglWaitGL();
 
-            egl.eglSwapBuffers(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface);
+            egl.eglSwapBuffers(SDLActivity.mSingleton.mEGLDisplay, SDLActivity.mSingleton.mEGLSurface);
 
 
         } catch(Exception e) {
@@ -392,26 +408,27 @@ class SDLMain implements Runnable {
         SDLActivity.nativeInit();
 
         //Log.v("SDL", "SDL thread terminated");
+        SDLActivity.finishActivity();
     }
 }
 
 
 /**
     SDLSurface. This is what we draw on, so we need to know when it's created
-    in order to do anything useful. 
+    in order to do anything useful.
 
     Because of this, that's where we set up the SDL thread
 */
-class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, 
+class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
     View.OnKeyListener, View.OnTouchListener, SensorEventListener  {
 
     // Sensors
     private static SensorManager mSensorManager;
 
-    // Startup    
+    // Startup
     public SDLSurface(Context context) {
         super(context);
-        getHolder().addCallback(this); 
+        getHolder().addCallback(this);
     
         setFocusable(true);
         setFocusableInTouchMode(true);

+ 4 - 0
Engine/Graphics/OpenGL/OGLShaderVariation.cpp

@@ -111,6 +111,10 @@ bool ShaderVariation::Create()
     if (!defines_.Empty())
         defines += "\n";
     
+    #ifdef GL_ES_VERSION_2_0
+    defines += "precision medp float;\n";
+    #endif
+    
     shaderCode = version + defines + shaderCode;
     
     const char* shaderCStr = shaderCode.CString();

+ 8 - 5
Engine/IO/FileSystem.cpp

@@ -349,26 +349,29 @@ void FileSystem::ScanDir(Vector<String>& result, const String& pathName, const S
 
 String FileSystem::GetProgramDir()
 {
-    #ifdef WIN32
+    #if defined(WIN32)
     wchar_t exeName[MAX_PATH];
     exeName[0] = 0;
     GetModuleFileNameW(0, exeName, MAX_PATH);
     return GetPath(String(exeName));
-    #endif
-    #ifdef __APPLE__
+    #elif defined(__APPLE__)
     char exeName[MAX_PATH];
     memset(exeName, 0, MAX_PATH);
     unsigned size = MAX_PATH;
     _NSGetExecutablePath(exeName, &size);
     return GetPath(String(exeName));
-    #endif
-    #ifdef __linux__
+    #elif defined(ANDROID)
+    /// \todo Hack, remove
+    return "/sdcard/";
+    #elif defined(__linux__)
     char exeName[MAX_PATH];
     memset(exeName, 0, MAX_PATH);
     pid_t pid = getpid();
     String link = "/proc/" + String(pid) + "/exe";
     readlink(link.CString(), exeName, MAX_PATH);
     return GetPath(String(exeName));
+    #else
+    return String();
     #endif
 }
 

+ 15 - 0
Engine/IO/Log.cpp

@@ -31,6 +31,10 @@
 #include <cstdio>
 #include <ctime>
 
+#ifdef ANDROID
+#include <android/log.h>
+#endif
+
 #include "DebugNew.h"
 
 static const String levelPrefixes[] =
@@ -60,6 +64,7 @@ Log::~Log()
 
 void Log::Open(const String& fileName)
 {
+    #ifndef ANDROID
     if (fileName.Empty())
         return;
     
@@ -71,6 +76,7 @@ void Log::Open(const String& fileName)
         logFile_.Reset();
         Write(LOG_ERROR, "Failed to create log file " + fileName);
     }
+    #endif
 }
 
 void Log::Write(int level, const String& message)
@@ -92,7 +98,12 @@ void Log::Write(int level, const String& message)
     String dateTimeString = String(dateTime).Replaced("\n", "");
     String formattedMessage = "[" + dateTimeString + "] " + levelPrefixes[level] + ": " + message;
     
+    #ifndef ANDROID
     PrintUnicodeLine(formattedMessage);
+    #else
+    /// \todo Use proper log levels
+    __android_log_print(ANDROID_LOG_INFO, "Urho3D", formattedMessage.CString());
+    #endif
     
     if (logFile_)
         logFile_->WriteLine(formattedMessage);
@@ -115,7 +126,11 @@ void Log::WriteRaw(const String& message)
     inWrite_ = true;
     lastMessage_ = message;
     
+    #ifndef ANDROID
     PrintUnicode(message);
+    #else
+    __android_log_print(ANDROID_LOG_INFO, "Urho3D", message.CString());
+    #endif
     
     if (logFile_)
     {

+ 2 - 4
ThirdParty/SDL/include/SDL_main.h

@@ -28,11 +28,11 @@
 
 /**
  *  \file SDL_main.h
- *  
+ *
  *  Redefine main() on some platforms so that it is called by SDL.
  */
 
-#if defined(__WIN32__) || defined(__IPHONEOS__) || defined(__ANDROID__)
+#if defined(__IPHONEOS__) || defined(__ANDROID__)
 #ifndef SDL_MAIN_HANDLED
 #define SDL_MAIN_NEEDED
 #endif
@@ -60,11 +60,9 @@
  */
 
 // Urho3D: commented out
-/*
 #ifdef SDL_MAIN_NEEDED
 #define main	SDL_main
 #endif
-*/
 
 /**
  *  The prototype for the application's main() function

+ 2 - 7
ThirdParty/SDL/src/main/android/SDL_android_main.cpp

@@ -1,3 +1,4 @@
+// Modified by Lasse Öörni for Urho3D
 
 #include "SDL_config.h"
 
@@ -13,13 +14,7 @@
 
 // Called before SDL_main() to initialize JNI bindings in SDL library
 extern "C" void SDL_Android_Init(JNIEnv* env, jclass cls);
-
-// Library init
-extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
-{
-    return JNI_VERSION_1_4;
-}
-
+                            
 // Start up the SDL app
 extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit(JNIEnv* env, jclass cls, jobject obj)
 {

+ 6 - 0
ThirdParty/SDL/src/video/android/SDL_androidwindow.c

@@ -18,6 +18,9 @@
      misrepresented as being the original software.
   3. This notice may not be removed or altered from any source distribution.
 */
+
+// Modified by Lasse Öörni for Urho3D
+
 #include "SDL_config.h"
 
 #if SDL_VIDEO_DRIVER_ANDROID
@@ -30,10 +33,13 @@
 int
 Android_CreateWindow(_THIS, SDL_Window * window)
 {
+    // Urho3D: this is a static variable that may not be cleared between runs of the program. Skip the check
+    /*
     if (Android_Window) {
         SDL_SetError("Android only supports one window");
         return -1;
     }
+    */
     Android_Window = window;
 
     /* Adjust the window data to match the screen */

+ 11 - 0
Urho3D/Urho3D.cpp

@@ -64,7 +64,13 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, PSTR cmdLine, in
     return 0;
 }
 #else
+#ifndef ANDROID
 int main(int argc, char** argv)
+#else
+extern "C" int SDL_main(int argc, char** argv);
+
+int SDL_main(int argc, char** argv)
+#endif
 {
     ParseArguments(argc, argv);
     Run();
@@ -88,6 +94,11 @@ void Run()
             }
         }
         
+        #ifdef ANDROID
+        // Can not pass script name on Android, so choose a hardcoded default
+        scriptFileName = "Scripts/TestScene.as";
+        #endif
+        
         // Show usage if not found
         if (scriptFileName.Empty())
         {