From 5ccdeccb6ed6b8480a86b0db36f192526cba1274 Mon Sep 17 00:00:00 2001 From: Ruslan Mustakov Date: Fri, 18 Aug 2017 21:17:35 +0700 Subject: [PATCH] Make GDNative work on Android The changes include work done to ensure that GDNative apps and Nim integration specifically can run on Android. The changes have been tested on our WIP game, which uses godot-nim and depends on several third-party .so libs, and Platformer demo to ensure nothing got broken. - .so libraries are exported to lib/ folder in .apk, instead of assets/, because that's where Android expects them to be and it resolves the library name into "lib//", where is the ABI matching the current device. So we establish the convention that Android .so files in the project must be located in the folder corresponding to the ABI they were compiled for. - Godot callbacks (event handlers) are now called from the same thread from which Main::iteration is called. It is also what Godot now considers to be the main thread, because Main::setup is also called from there. This makes threading on Android more consistent with other platforms, making the code that depends on Thread::get_main_id more portable (GDNative has such code). - Sizes of GDNative API types have been fixed to work on 32-bit platforms. --- main/main.cpp | 14 +- modules/gdnative/gdnative.cpp | 36 ++- modules/gdnative/gdnative.h | 17 +- modules/gdnative/godot/array.h | 2 +- modules/gdnative/godot/dictionary.h | 2 +- modules/gdnative/godot/gdnative.h | 2 +- modules/gdnative/godot/node_path.h | 2 +- modules/gdnative/godot/pool_arrays.h | 14 +- modules/gdnative/godot/rid.h | 2 +- modules/gdnative/godot/string.h | 2 +- modules/gdnative/godot/variant.h | 2 +- modules/nativescript/godot_nativescript.h | 2 +- modules/nativescript/nativescript.cpp | 2 + platform/android/detect.py | 2 +- platform/android/export/export.cpp | 35 ++- .../java/src/org/godotengine/godot/Godot.java | 251 +++++++++++------- .../src/org/godotengine/godot/GodotLib.java | 5 +- .../org/godotengine/godot/GodotPaymentV3.java | 2 +- .../src/org/godotengine/godot/GodotView.java | 94 +++++-- .../godot/input/GodotTextInputWrapper.java | 43 ++- platform/android/java_glue.cpp | 234 +++++++--------- platform/android/java_glue.h | 3 +- 22 files changed, 447 insertions(+), 321 deletions(-) diff --git a/main/main.cpp b/main/main.cpp index 532b5277b56..2e34012b6f7 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1098,10 +1098,20 @@ bool Main::start() { test = args[i + 1]; } else if (args[i] == "--export") { editor = true; //needs editor - _export_preset = args[i + 1]; + if (i + 1 < args.size()) { + _export_preset = args[i + 1]; + } else { + ERR_PRINT("Export preset name not specified"); + return false; + } } else if (args[i] == "--export-debug") { editor = true; //needs editor - _export_preset = args[i + 1]; + if (i + 1 < args.size()) { + _export_preset = args[i + 1]; + } else { + ERR_PRINT("Export preset name not specified"); + return false; + } export_debug = true; } else { // The parameter does not match anything known, don't skip the next argument diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index 7faf21c5a1d..ded987557c3 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -40,7 +40,7 @@ const String init_symbol = "godot_gdnative_init"; const String terminate_symbol = "godot_gdnative_terminate"; -String GDNativeLibrary::platform_names[NUM_PLATFORMS] = { +String GDNativeLibrary::platform_names[NUM_PLATFORMS + 1] = { "X11_32bit", "X11_64bit", "Windows_32bit", @@ -48,11 +48,15 @@ String GDNativeLibrary::platform_names[NUM_PLATFORMS] = { "OSX", "Android", - "iOS", - "WebAssembly" + "iOS_32bit", + "iOS_64bit", + + "WebAssembly", + + "" }; -String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = { +String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS + 1] = { "so", "so", "dll", @@ -60,21 +64,30 @@ String GDNativeLibrary::platform_lib_ext[NUM_PLATFORMS] = { "dylib", "so", + + "dylib", "dylib", - "wasm" + "wasm", + + "" }; -// TODO(karroffel): make this actually do the right thing. GDNativeLibrary::Platform GDNativeLibrary::current_platform = #if defined(X11_ENABLED) - X11_64BIT; + (sizeof(void *) == 8 ? X11_64BIT : X11_32BIT); #elif defined(WINDOWS_ENABLED) - WINDOWS_64BIT; + (sizeof(void *) == 8 ? WINDOWS_64BIT : WINDOWS_32BIT); #elif defined(OSX_ENABLED) OSX; +#elif defined(IPHONE_ENABLED) + (sizeof(void *) == 8 ? IOS_64BIT : IOS_32BIT); +#elif defined(ANDROID_ENABLED) + ANDROID; +#elif defined(JAVASCRIPT_ENABLED) + WASM; #else - X11_64BIT; // need a sensible default.. + NUM_PLATFORMS; #endif GDNativeLibrary::GDNativeLibrary() @@ -151,7 +164,10 @@ String GDNativeLibrary::get_library_path(StringName p_platform) const { } String GDNativeLibrary::get_active_library_path() const { - return library_paths[GDNativeLibrary::current_platform]; + if (GDNativeLibrary::current_platform != NUM_PLATFORMS) { + return library_paths[GDNativeLibrary::current_platform]; + } + return ""; } GDNative::GDNative() { diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index bec746a4419..dc1c3507ec4 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -48,11 +48,17 @@ class GDNativeLibrary : public Resource { // NOTE(karroffel): I heard OSX 32 bit is dead, so 64 only OSX, - // TODO(karroffel): all different android versions and archs + // Android .so files must be located in directories corresponding to Android ABI names: + // https://developer.android.com/ndk/guides/abis.html + // Android runtime will select the matching library depending on the device. + // The value here must simply point to the .so name, for example: + // "res://libmy_gdnative.so" or "libmy_gdnative.so", + // while in the project the actual paths can be "lib/android/armeabi-v7a/libmy_gdnative.so", + // "lib/android/arm64-v8a/libmy_gdnative.so". ANDROID, - // TODO(karroffe): all different iOS versions and archs - IOS, + IOS_32BIT, + IOS_64BIT, // TODO(karroffel): figure out how to deal with web stuff at all... WASM, @@ -64,10 +70,9 @@ class GDNativeLibrary : public Resource { }; - static String platform_names[NUM_PLATFORMS]; - static String platform_lib_ext[NUM_PLATFORMS]; + static String platform_names[NUM_PLATFORMS + 1]; + static String platform_lib_ext[NUM_PLATFORMS + 1]; - // TODO(karroffel): make this actually do something lol. static Platform current_platform; String library_paths[NUM_PLATFORMS]; diff --git a/modules/gdnative/godot/array.h b/modules/gdnative/godot/array.h index 434ce958c9f..08f73c87853 100644 --- a/modules/gdnative/godot/array.h +++ b/modules/gdnative/godot/array.h @@ -37,7 +37,7 @@ extern "C" { #include -#define GODOT_ARRAY_SIZE 8 +#define GODOT_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_ARRAY_TYPE_DEFINED diff --git a/modules/gdnative/godot/dictionary.h b/modules/gdnative/godot/dictionary.h index bbe40f23c3f..10d580af086 100644 --- a/modules/gdnative/godot/dictionary.h +++ b/modules/gdnative/godot/dictionary.h @@ -36,7 +36,7 @@ extern "C" { #include -#define GODOT_DICTIONARY_SIZE 8 +#define GODOT_DICTIONARY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED diff --git a/modules/gdnative/godot/gdnative.h b/modules/gdnative/godot/gdnative.h index 8b289da1f52..c71a7ae1ef1 100644 --- a/modules/gdnative/godot/gdnative.h +++ b/modules/gdnative/godot/gdnative.h @@ -56,7 +56,7 @@ extern "C" { #define GDAPI GDCALLINGCONV #endif #else -#define GDCALLINGCONV __attribute__((sysv_abi)) +#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default"))) #define GDAPI GDCALLINGCONV #endif diff --git a/modules/gdnative/godot/node_path.h b/modules/gdnative/godot/node_path.h index 3e2a99e4618..2f71ddd59dc 100644 --- a/modules/gdnative/godot/node_path.h +++ b/modules/gdnative/godot/node_path.h @@ -36,7 +36,7 @@ extern "C" { #include -#define GODOT_NODE_PATH_SIZE 8 +#define GODOT_NODE_PATH_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED #define GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED diff --git a/modules/gdnative/godot/pool_arrays.h b/modules/gdnative/godot/pool_arrays.h index ecd85ddfe80..1b51dca38c5 100644 --- a/modules/gdnative/godot/pool_arrays.h +++ b/modules/gdnative/godot/pool_arrays.h @@ -38,7 +38,7 @@ extern "C" { /////// PoolByteArray -#define GODOT_POOL_BYTE_ARRAY_SIZE 8 +#define GODOT_POOL_BYTE_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_BYTE_ARRAY_TYPE_DEFINED @@ -49,7 +49,7 @@ typedef struct { /////// PoolIntArray -#define GODOT_POOL_INT_ARRAY_SIZE 8 +#define GODOT_POOL_INT_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_INT_ARRAY_TYPE_DEFINED @@ -60,7 +60,7 @@ typedef struct { /////// PoolRealArray -#define GODOT_POOL_REAL_ARRAY_SIZE 8 +#define GODOT_POOL_REAL_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_REAL_ARRAY_TYPE_DEFINED @@ -71,7 +71,7 @@ typedef struct { /////// PoolStringArray -#define GODOT_POOL_STRING_ARRAY_SIZE 8 +#define GODOT_POOL_STRING_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_STRING_ARRAY_TYPE_DEFINED @@ -82,7 +82,7 @@ typedef struct { /////// PoolVector2Array -#define GODOT_POOL_VECTOR2_ARRAY_SIZE 8 +#define GODOT_POOL_VECTOR2_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_VECTOR2_ARRAY_TYPE_DEFINED @@ -93,7 +93,7 @@ typedef struct { /////// PoolVector3Array -#define GODOT_POOL_VECTOR3_ARRAY_SIZE 8 +#define GODOT_POOL_VECTOR3_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_VECTOR3_ARRAY_TYPE_DEFINED @@ -104,7 +104,7 @@ typedef struct { /////// PoolColorArray -#define GODOT_POOL_COLOR_ARRAY_SIZE 8 +#define GODOT_POOL_COLOR_ARRAY_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED #define GODOT_CORE_API_GODOT_POOL_COLOR_ARRAY_TYPE_DEFINED diff --git a/modules/gdnative/godot/rid.h b/modules/gdnative/godot/rid.h index b685157cec0..c56ff387351 100644 --- a/modules/gdnative/godot/rid.h +++ b/modules/gdnative/godot/rid.h @@ -36,7 +36,7 @@ extern "C" { #include -#define GODOT_RID_SIZE 8 +#define GODOT_RID_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_RID_TYPE_DEFINED #define GODOT_CORE_API_GODOT_RID_TYPE_DEFINED diff --git a/modules/gdnative/godot/string.h b/modules/gdnative/godot/string.h index f41626faa1a..d691744453d 100644 --- a/modules/gdnative/godot/string.h +++ b/modules/gdnative/godot/string.h @@ -37,7 +37,7 @@ extern "C" { #include #include -#define GODOT_STRING_SIZE 8 +#define GODOT_STRING_SIZE sizeof(void *) #ifndef GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED #define GODOT_CORE_API_GODOT_STRING_TYPE_DEFINED diff --git a/modules/gdnative/godot/variant.h b/modules/gdnative/godot/variant.h index fda24db8d46..849ba8bda6f 100644 --- a/modules/gdnative/godot/variant.h +++ b/modules/gdnative/godot/variant.h @@ -36,7 +36,7 @@ extern "C" { #include -#define GODOT_VARIANT_SIZE 24 +#define GODOT_VARIANT_SIZE (16 + sizeof(void *)) #ifndef GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED #define GODOT_CORE_API_GODOT_VARIANT_TYPE_DEFINED diff --git a/modules/nativescript/godot_nativescript.h b/modules/nativescript/godot_nativescript.h index 1eaf459570d..d263c614641 100644 --- a/modules/nativescript/godot_nativescript.h +++ b/modules/nativescript/godot_nativescript.h @@ -58,7 +58,7 @@ extern "C" { #define GDAPI GDCALLINGCONV #endif #else -#define GDCALLINGCONV __attribute__((sysv_abi)) +#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default"))) #define GDAPI GDCALLINGCONV #endif diff --git a/modules/nativescript/nativescript.cpp b/modules/nativescript/nativescript.cpp index 3799ce31f84..e1410806873 100644 --- a/modules/nativescript/nativescript.cpp +++ b/modules/nativescript/nativescript.cpp @@ -994,6 +994,8 @@ void NativeScriptLanguage::init_library(const Ref &lib) { #endif // See if this library was "registered" already. const String &lib_path = lib->get_active_library_path(); + ERR_EXPLAIN(lib->get_name() + " does not have a library for the current platform"); + ERR_FAIL_COND(lib_path.length() == 0); Map >::Element *E = library_gdnatives.find(lib_path); if (!E) { diff --git a/platform/android/detect.py b/platform/android/detect.py index 65442bf6f8f..c1ac54c5876 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -240,7 +240,7 @@ def configure(env): env.Append(CPPPATH=['#platform/android']) env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL', '-DMPC_FIXED_POINT']) - env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'android', 'log', 'z']) + env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'android', 'log', 'z', 'dl']) # TODO: Move that to opus module's config if("module_opus_enabled" in env and env["module_opus_enabled"] != "no"): diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 8b3a64bbe67..da1b2617eff 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -468,11 +468,36 @@ class EditorExportAndroid : public EditorExportPlatform { return zipfi; } - static Error save_apk_file(void *p_userdata, const String &p_path, const Vector &p_data, int p_file, int p_total) { + static Set get_abis() { + Set abis; + abis.insert("armeabi"); + abis.insert("armeabi-v7a"); + abis.insert("arm64-v8a"); + abis.insert("x86"); + abis.insert("x86_64"); + abis.insert("mips"); + abis.insert("mips64"); + return abis; + } + static Error save_apk_file(void *p_userdata, const String &p_path, const Vector &p_data, int p_file, int p_total) { APKExportData *ed = (APKExportData *)p_userdata; String dst_path = p_path; - dst_path = dst_path.replace_first("res://", "assets/"); + static Set android_abis = get_abis(); + + if (dst_path.ends_with(".so")) { + String abi = dst_path.get_base_dir().get_file().strip_edges(); // parent dir name + if (android_abis.has(abi)) { + dst_path = "lib/" + abi + "/" + dst_path.get_file(); + } else { + String err = "Dynamic libraries must be located in the folder named after Android ABI they were compiled for. " + + p_path + " does not follow this convention."; + ERR_PRINT(err.utf8().get_data()); + return ERR_FILE_BAD_PATH; + } + } else { + dst_path = dst_path.replace_first("res://", "assets/"); + } zip_fileinfo zipfi = get_zip_fileinfo(); @@ -1375,15 +1400,15 @@ public: } } - if (file == "lib/x86/libgodot_android.so" && !export_x86) { + if (file == "lib/x86/*.so" && !export_x86) { skip = true; } - if (file.match("lib/armeabi*/libgodot_android.so") && !export_arm) { + if (file.match("lib/armeabi*/*.so") && !export_arm) { skip = true; } - if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) { + if (file.match("lib/arm64*/*.so") && !export_arm64) { skip = true; } diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index eab0387f329..53a90e4cfec 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -92,7 +92,7 @@ import android.os.SystemClock; public class Godot extends Activity implements SensorEventListener, IDownloaderClient -{ +{ static final int MAX_SINGLETONS = 64; private IStub mDownloaderClientStub; @@ -139,9 +139,9 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC com.godot.game.R.string.text_button_pause; mPauseButton.setText(stringResourceID); } - + static public class SingletonBase { - + protected void registerClass(String p_name, String[] p_methods) { GodotLib.singleton(p_name,this); @@ -210,6 +210,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC */ private String[] command_line; + private boolean use_apk_expansion; public GodotView mView; private boolean godot_initialized=false; @@ -264,27 +265,40 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC layout = new FrameLayout(this); layout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); setContentView(layout); - + // GodotEditText layout - GodotEditText edittext = new GodotEditText(this); + GodotEditText edittext = new GodotEditText(this); edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT)); // ...add to FrameLayout layout.addView(edittext); - + mView = new GodotView(getApplication(),io,use_gl2,use_32_bits, this); layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); - setKeepScreenOn(GodotLib.getGlobal("display/driver/keep_screen_on").equals("True")); - - edittext.setView(mView); - io.setEdit(edittext); - + edittext.setView(mView); + io.setEdit(edittext); + // Ad layout adLayout = new RelativeLayout(this); adLayout.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT)); layout.addView(adLayout); - + + final String[] current_command_line = command_line; + final GodotView view = mView; + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.setup(current_command_line); + runOnUiThread(new Runnable() { + @Override + public void run() { + view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/driver/keep_screen_on"))); + } + }); + } + }); + } - + public void setKeepScreenOn(final boolean p_enabled) { keep_screen_on = p_enabled; if (mView != null){ @@ -315,13 +329,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } }); } - + private static Godot _self; - + public static Godot getInstance(){ return Godot._self; } - + private String[] getCommandLine() { InputStream is; @@ -402,7 +416,6 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC Log.d("GODOT"," " + command_line[w]); } }*/ - GodotLib.initialize(this,io.needsReloadHooks(),command_line,getAssets()); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); @@ -411,9 +424,12 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); + GodotLib.initialize(this, io.needsReloadHooks(), getAssets(), use_apk_expansion); + result_callback = null; mPaymentsManager = PaymentsManager.createManager(this).initService(); + godot_initialized=true; } @@ -426,7 +442,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC - @Override + @Override protected void onCreate(Bundle icicle) { Log.d("GODOT", "** GODOT ACTIVITY CREATED HERE ***\n"); @@ -437,12 +453,10 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC //window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); - //check for apk expansion API if (true) { boolean md5mismatch = false; command_line = getCommandLine(); - boolean use_apk_expansion=false; String main_pack_md5=null; String main_pack_key=null; @@ -528,23 +542,23 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC if (!pack_valid) { Log.d("GODOT", "Pack Invalid, try re-downloading."); - + Intent notifierIntent = new Intent(this, this.getClass()); notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP); - + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); - + int startResult; try { Log.d("GODOT", "INITIALIZING DOWNLOAD"); startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( - getApplicationContext(), - pendingIntent, + getApplicationContext(), + pendingIntent, GodotDownloaderService.class); Log.d("GODOT", "DOWNLOAD SERVICE FINISHED:" + startResult); - + if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { Log.d("GODOT", "DOWNLOAD REQUIRED"); // This is where you do set up to display the download @@ -563,7 +577,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC mCellMessage = findViewById(com.godot.game.R.id.approveCellular); mPauseButton = (Button) findViewById(com.godot.game.R.id.pauseButton); mWiFiSettingsButton = (Button) findViewById(com.godot.game.R.id.wifiSettingsButton); - + return; } else{ Log.d("GODOT", "NO DOWNLOAD REQUIRED"); @@ -582,7 +596,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC initializeGodot(); - + //instanceSingleton( new GodotFacebook(this) ); @@ -590,14 +604,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override protected void onDestroy(){ - + if(mPaymentsManager != null ) mPaymentsManager.destroy(); for(int i=0;i= 19.0){ // check if the application runs on an android 4.4+ Window window = getWindow(); window.getDecorView().setSystemUiVisibility( @@ -644,8 +669,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC singletons[i].onMainResume(); } - - + + } @@ -670,32 +695,39 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override public void onSensorChanged(SensorEvent event) { Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); int displayRotation = display.getRotation(); - + float[] adjustedValues = new float[3]; final int axisSwap[][] = { - { 1, -1, 0, 1 }, // ROTATION_0 - {-1, -1, 1, 0 }, // ROTATION_90 - {-1, 1, 0, 1 }, // ROTATION_180 - { 1, 1, 1, 0 } }; // ROTATION_270 + { 1, -1, 0, 1 }, // ROTATION_0 + {-1, -1, 1, 0 }, // ROTATION_90 + {-1, 1, 0, 1 }, // ROTATION_180 + { 1, 1, 1, 0 } }; // ROTATION_270 - final int[] as = axisSwap[displayRotation]; - adjustedValues[0] = (float)as[0] * event.values[ as[2] ]; - adjustedValues[1] = (float)as[1] * event.values[ as[3] ]; + final int[] as = axisSwap[displayRotation]; + adjustedValues[0] = (float)as[0] * event.values[ as[2] ]; + adjustedValues[1] = (float)as[1] * event.values[ as[3] ]; adjustedValues[2] = event.values[2]; - - float x = adjustedValues[0]; - float y = adjustedValues[1]; - float z = adjustedValues[2]; - int typeOfSensor = event.sensor.getType(); - if (typeOfSensor == event.sensor.TYPE_ACCELEROMETER) { - GodotLib.accelerometer(x,y,z); - } - if (typeOfSensor == event.sensor.TYPE_MAGNETIC_FIELD) { - GodotLib.magnetometer(x,y,z); - } - if (typeOfSensor == event.sensor.TYPE_GYROSCOPE) { - GodotLib.gyroscope(x,y,z); + final float x = adjustedValues[0]; + final float y = adjustedValues[1]; + final float z = adjustedValues[2]; + + final int typeOfSensor = event.sensor.getType(); + if (mView != null) { + mView.queueEvent(new Runnable() { + @Override + public void run() { + if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) { + GodotLib.accelerometer(x,y,z); + } + if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) { + GodotLib.magnetometer(x,y,z); + } + if (typeOfSensor == Sensor.TYPE_GYROSCOPE) { + GodotLib.gyroscope(x,y,z); + } + } + }); } } @@ -722,7 +754,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override public void onBackPressed() { System.out.printf("** BACK REQUEST!\n"); - //GodotLib.back(); + if (mView != null) { + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.back(); + } + }); + } } public void forceQuit() { @@ -733,7 +772,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC private boolean obbIsCorrupted(String f, String main_pack_md5){ - + try { InputStream fis = new FileInputStream(f); @@ -780,58 +819,64 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC } //@Override public boolean dispatchTouchEvent (MotionEvent event) { - public boolean gotTouchEvent(MotionEvent event) { + public boolean gotTouchEvent(final MotionEvent event) { super.onTouchEvent(event); - int evcount=event.getPointerCount(); + final int evcount=event.getPointerCount(); if (evcount==0) return true; - int[] arr = new int[event.getPointerCount()*3]; + if (mView != null) { + final int[] arr = new int[event.getPointerCount()*3]; - for(int i=0;i(); joy.hats = new ArrayList(); @@ -224,19 +225,29 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { } } joy_devices.add(joy); - GodotLib.joyconnectionchanged(id, true, joy.name); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(id, true, name); + } + }); } @Override public void onInputDeviceRemoved(int deviceId) { - int id = find_joy_device(deviceId); + final int id = find_joy_device(deviceId); joy_devices.remove(id); - GodotLib.joyconnectionchanged(id, false, ""); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyconnectionchanged(id, false, ""); + } + }); } @Override public void onInputDeviceChanged(int deviceId) { } - @Override public boolean onKeyUp(int keyCode, KeyEvent event) { + @Override public boolean onKeyUp(final int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { return true; @@ -249,22 +260,38 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { int source = event.getSource(); if ((source & InputDevice.SOURCE_JOYSTICK) != 0 || (source & InputDevice.SOURCE_DPAD) != 0 || (source & InputDevice.SOURCE_GAMEPAD) != 0) { - int button = get_godot_button(keyCode); - int device = find_joy_device(event.getDeviceId()); + final int button = get_godot_button(keyCode); + final int device = find_joy_device(event.getDeviceId()); - GodotLib.joybutton(device, button, false); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joybutton(device, button, false); + } + }); return true; } else { - - GodotLib.key(keyCode, event.getUnicodeChar(0), false); + final int chr = event.getUnicodeChar(0); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(keyCode, chr, false); + } + }); }; return super.onKeyUp(keyCode, event); }; - @Override public boolean onKeyDown(int keyCode, KeyEvent event) { + @Override public boolean onKeyDown(final int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { - GodotLib.back(); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.back(); + } + }); + // press 'back' button should not terminate program //normal handle 'back' event in game logic return true; @@ -281,16 +308,26 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { if (event.getRepeatCount() > 0) // ignore key echo return true; - int button = get_godot_button(keyCode); - int device = find_joy_device(event.getDeviceId()); + final int button = get_godot_button(keyCode); + final int device = find_joy_device(event.getDeviceId()); //Log.e(TAG, String.format("joy button down! button %x, %d, device %d", keyCode, button, device)); - - GodotLib.joybutton(device, button, true); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joybutton(device, button, true); + } + }); return true; } else { - GodotLib.key(keyCode, event.getUnicodeChar(0), true); + final int chr = event.getUnicodeChar(0); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(keyCode, chr, true); + } + }); }; return super.onKeyDown(keyCode, event); } @@ -299,21 +336,32 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { - int device_id = find_joy_device(event.getDeviceId()); + final int device_id = find_joy_device(event.getDeviceId()); joystick joy = joy_devices.get(device_id); for (int i = 0; i < joy.axes.size(); i++) { InputDevice.MotionRange range = joy.axes.get(i); - float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f; + final float value = (event.getAxisValue(range.getAxis()) - range.getMin() ) / range.getRange() * 2.0f - 1.0f; //Log.e(TAG, String.format("axis event: %d, value %f", i, value)); - GodotLib.joyaxis(device_id, i, value); + final int idx = i; + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyaxis(device_id, idx, value); + } + }); } for (int i = 0; i < joy.hats.size(); i+=2) { - int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis())); - int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis())); + final int hatX = Math.round(event.getAxisValue(joy.hats.get(i).getAxis())); + final int hatY = Math.round(event.getAxisValue(joy.hats.get(i+1).getAxis())); //Log.e(TAG, String.format("HAT EVENT %d, %d", hatX, hatY)); - GodotLib.joyhat(device_id, hatX, hatY); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.joyhat(device_id, hatX, hatY); + } + }); } return true; }; diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java index c2d03e4eccf..04669a3b0c2 100644 --- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -89,8 +89,13 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene //Log.d(TAG, "beforeTextChanged(" + pCharSequence + ")start: " + start + ",count: " + count + ",after: " + after); for (int i=0;i 0; i--) { - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); - GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, true); + GodotLib.key(KeyEvent.KEYCODE_DEL, 0, false); + } + }); + /* if (BuildConfig.DEBUG) { Log.d(TAG, "deleteBackward"); @@ -131,9 +147,14 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene } for(int i = 0; i < text.length(); i++) { - int ch = text.codePointAt(i); - GodotLib.key(0, ch, true); - GodotLib.key(0, ch, false); + final int ch = text.codePointAt(i); + mView.queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.key(0, ch, true); + GodotLib.key(0, ch, false); + } + }); } /* if (BuildConfig.DEBUG) { @@ -141,7 +162,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene } */ } - + if (pActionID == EditorInfo.IME_ACTION_DONE) { this.mView.requestFocus(); } diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 06abe9d751c..509d1bf1236 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -613,8 +613,6 @@ static List pointer_events; static List > key_events; static List joy_events; static bool initialized = false; -static Mutex *input_mutex = NULL; -static Mutex *suspend_mutex = NULL; static int step = 0; static bool resized = false; static bool resized_reload = false; @@ -756,7 +754,7 @@ static void _alert(const String &p_message, const String &p_title) { env->CallVoidMethod(_godot_instance, _alertDialog, jStrMessage, jStrTitle); } -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobjectArray p_cmdline, jobject p_asset_manager) { +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobject p_asset_manager, jboolean p_use_apk_expansion) { __android_log_print(ANDROID_LOG_INFO, "godot", "**INIT EVENT! - %p\n", env); @@ -826,36 +824,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en AudioDriverAndroid::setup(gob); } - const char **cmdline = NULL; - int cmdlen = 0; - bool use_apk_expansion = false; - if (p_cmdline) { - cmdlen = env->GetArrayLength(p_cmdline); - if (cmdlen) { - cmdline = (const char **)malloc((env->GetArrayLength(p_cmdline) + 1) * sizeof(const char *)); - cmdline[cmdlen] = NULL; - - for (int i = 0; i < cmdlen; i++) { - - jstring string = (jstring)env->GetObjectArrayElement(p_cmdline, i); - const char *rawString = env->GetStringUTFChars(string, 0); - if (!rawString) { - __android_log_print(ANDROID_LOG_INFO, "godot", "cmdline arg %i is null\n", i); - } else { - //__android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is: %s\n",i,rawString); - - if (strcmp(rawString, "--main_pack") == 0) - use_apk_expansion = true; - } - - cmdline[i] = rawString; - } - } - } - - __android_log_print(ANDROID_LOG_INFO, "godot", "CMDLINE LEN %i - APK EXPANSION %I\n", cmdlen, int(use_apk_expansion)); - - os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, use_apk_expansion); + os_android = new OS_Android(_gfx_init_func, env, _open_uri, _get_data_dir, _get_locale, _get_model, _get_screen_dpi, _show_vk, _hide_vk, _set_screen_orient, _get_unique_id, _get_system_dir, _play_video, _is_video_playing, _pause_video, _stop_video, _set_keep_screen_on, _alert, p_use_apk_expansion); os_android->set_need_reload_hooks(p_need_reload_hook); char wd[500]; @@ -864,62 +833,10 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en __android_log_print(ANDROID_LOG_INFO, "godot", "test construction %i\n", tst.a); __android_log_print(ANDROID_LOG_INFO, "godot", "running from dir %s\n", wd); - __android_log_print(ANDROID_LOG_INFO, "godot", "**SETUP"); - - Error err = Main::setup("apk", cmdlen, (char **)cmdline, false); - - if (err != OK) { - __android_log_print(ANDROID_LOG_INFO, "godot", "*****UNABLE TO SETUP"); - - return; //should exit instead and print the error - } - - __android_log_print(ANDROID_LOG_INFO, "godot", "*****SETUP OK"); - //video driver is determined here, because once initialized, it can't be changed - String vd = ProjectSettings::get_singleton()->get("display/driver"); + // String vd = ProjectSettings::get_singleton()->get("display/driver"); env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean) true); - - __android_log_print(ANDROID_LOG_INFO, "godot", "**START"); - - input_mutex = Mutex::create(); - suspend_mutex = Mutex::create(); -} - -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload) { - - __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ resize %lld, %i, %i\n", Thread::get_caller_id(), width, height); - if (os_android) - os_android->set_display_size(Size2(width, height)); - - /*input_mutex->lock(); - resized=true; - if (reload) - resized_reload=true; - new_size=Size2(width,height); - input_mutex->unlock();*/ -} - -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits) { - - __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ newcontext %lld\n", Thread::get_caller_id()); - - if (os_android) { - os_android->set_context_is_16_bits(!p_32_bits); - } - - if (os_android && step > 0) { - - os_android->reload_gfx(); - } -} - -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) { - - input_mutex->lock(); - go_back_request = true; - input_mutex->unlock(); } static void _initialize_java_modules() { @@ -985,36 +902,106 @@ static void _initialize_java_modules() { } } -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj) { - +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline) { ThreadAndroid::setup_thread(); - //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_id()); + __android_log_print(ANDROID_LOG_INFO, "godot", "**SETUP"); - suspend_mutex->lock(); - input_mutex->lock(); - //first time step happens, initialize + const char **cmdline = NULL; + int cmdlen = 0; + bool use_apk_expansion = false; + if (p_cmdline) { + cmdlen = env->GetArrayLength(p_cmdline); + if (cmdlen) { + cmdline = (const char **)malloc((env->GetArrayLength(p_cmdline) + 1) * sizeof(const char *)); + cmdline[cmdlen] = NULL; + + for (int i = 0; i < cmdlen; i++) { + + jstring string = (jstring)env->GetObjectArrayElement(p_cmdline, i); + const char *rawString = env->GetStringUTFChars(string, 0); + if (!rawString) { + __android_log_print(ANDROID_LOG_INFO, "godot", "cmdline arg %i is null\n", i); + } else { + //__android_log_print(ANDROID_LOG_INFO,"godot","cmdline arg %i is: %s\n",i,rawString); + + if (strcmp(rawString, "-main_pack") == 0) + use_apk_expansion = true; + } + + cmdline[i] = rawString; + } + } + } + __android_log_print(ANDROID_LOG_INFO, "godot", "CMDLINE LEN %i - APK EXPANSION %i\n", cmdlen, int(use_apk_expansion)); + +#if 0 + char *args[]={"-test","render",NULL}; + __android_log_print(ANDROID_LOG_INFO,"godot","pre asdasd setup..."); + Error err = Main::setup("apk",2,args,false); +#else + Error err = Main::setup("apk", cmdlen, (char **)cmdline, false); +#endif + if (cmdline) { + free(cmdline); + } + + if (err != OK) { + __android_log_print(ANDROID_LOG_INFO, "godot", "*****UNABLE TO SETUP"); + return; //should exit instead and print the error + } + __android_log_print(ANDROID_LOG_INFO, "godot", "*****SETUP OK"); + + java_class_wrapper = memnew(JavaClassWrapper(_godot_instance)); + ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaClassWrapper", java_class_wrapper)); + _initialize_java_modules(); +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload) { + + __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ resize %lld, %i, %i\n", Thread::get_caller_id(), width, height); + if (os_android) + os_android->set_display_size(Size2(width, height)); + + /*input_mutex->lock(); + resized=true; + if (reload) + resized_reload=true; + new_size=Size2(width,height); + input_mutex->unlock();*/ +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits) { + + __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ newcontext %lld\n", Thread::get_caller_id()); + + if (os_android) { + os_android->set_context_is_16_bits(!p_32_bits); + } + + if (os_android && step > 0) { + + os_android->reload_gfx(); + } +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj) { + go_back_request = true; +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj) { if (step == 0) { - // ugly hack to initialize the rest of the engine - // because of the way android forces you to do everything with threads - - java_class_wrapper = memnew(JavaClassWrapper(_godot_instance)); - ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaClassWrapper", java_class_wrapper)); - _initialize_java_modules(); + __android_log_print(ANDROID_LOG_INFO, "godot", "**FIRST_STEP"); // Since Godot is initialized on the UI thread, _main_thread_id was set to that thread's id, // but for Godot purposes, the main thread is the one running the game loop Main::setup2(Thread::get_caller_id()); ++step; - suspend_mutex->unlock(); - input_mutex->unlock(); return; - }; + } + if (step == 1) { if (!Main::start()) { - - input_mutex->unlock(); - suspend_mutex->lock(); return; //should exit instead and print the error } @@ -1022,6 +1009,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job ++step; } + //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_id()); + while (pointer_events.size()) { JAndroidPointerEvent jpe = pointer_events.front()->get(); @@ -1052,8 +1041,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job go_back_request = false; } - input_mutex->unlock(); - os_android->process_accelerometer(accelerometer); os_android->process_magnetometer(magnetometer); @@ -1067,8 +1054,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job env->CallVoidMethod(_godot_instance, _finish); __android_log_print(ANDROID_LOG_INFO, "godot", "**FINISH REQUEST!!! - %p-%i\n", env, Thread::get_caller_id()); } - - suspend_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions) { @@ -1091,11 +1076,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jo jpe.points = points; jpe.what = ev; - input_mutex->lock(); - pointer_events.push_back(jpe); - - input_mutex->unlock(); /* if (os_android) os_android->process_touch(ev,pointer,points); @@ -1365,9 +1346,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env jevent.index = p_button; jevent.pressed = p_pressed; - input_mutex->lock(); joy_events.push_back(jevent); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value) { @@ -1378,9 +1357,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jevent.index = p_axis; jevent.value = p_value; - input_mutex->lock(); joy_events.push_back(jevent); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, jobject obj, jint p_device, jint p_hat_x, jint p_hat_y) { @@ -1401,9 +1378,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyhat(JNIEnv *env, j hat |= InputDefault::HAT_MASK_DOWN; } jevent.hat = hat; - input_mutex->lock(); joy_events.push_back(jevent); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(JNIEnv *env, jobject obj, jint p_device, jboolean p_connected, jstring p_name) { @@ -1437,54 +1412,31 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobj go_back_request = true; } - input_mutex->lock(); key_events.push_back(ievent); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_accelerometer(JNIEnv *env, jobject obj, jfloat x, jfloat y, jfloat z) { - - input_mutex->lock(); accelerometer = Vector3(x, y, z); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_magnetometer(JNIEnv *env, jobject obj, jfloat x, jfloat y, jfloat z) { - - input_mutex->lock(); magnetometer = Vector3(x, y, z); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_gyroscope(JNIEnv *env, jobject obj, jfloat x, jfloat y, jfloat z) { - - input_mutex->lock(); gyroscope = Vector3(x, y, z); - input_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusin(JNIEnv *env, jobject obj) { - if (!suspend_mutex) - return; - suspend_mutex->lock(); - if (os_android && step > 0) os_android->main_loop_focusin(); - - suspend_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env, jobject obj) { - if (!suspend_mutex) - return; - suspend_mutex->lock(); - if (os_android && step > 0) os_android->main_loop_focusout(); - - suspend_mutex->unlock(); } JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_audio(JNIEnv *env, jobject obj) { diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h index 64970040f8a..ec8ae9a0a69 100644 --- a/platform/android/java_glue.h +++ b/platform/android/java_glue.h @@ -36,7 +36,8 @@ #include extern "C" { -JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobjectArray p_cmdline, jobject p_asset_manager); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jobject obj, jobject activity, jboolean p_need_reload_hook, jobject p_asset_manager, jboolean p_use_apk_expansion); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jobject obj, jobjectArray p_cmdline); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, jobject obj);