| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*  godot_android.cpp                                                    */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | /*                       This file is part of:                           */ | 
					
						
							|  |  |  | /*                           GODOT ENGINE                                */ | 
					
						
							| 
									
										
										
										
											2017-08-27 14:16:55 +02:00
										 |  |  | /*                      https://godotengine.org                          */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*************************************************************************/ | 
					
						
							| 
									
										
										
										
											2017-01-01 22:01:57 +01:00
										 |  |  | /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */ | 
					
						
							| 
									
										
										
										
											2017-04-08 00:11:42 +02:00
										 |  |  | /* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* Permission is hereby granted, free of charge, to any person obtaining */ | 
					
						
							|  |  |  | /* a copy of this software and associated documentation files (the       */ | 
					
						
							|  |  |  | /* "Software"), to deal in the Software without restriction, including   */ | 
					
						
							|  |  |  | /* without limitation the rights to use, copy, modify, merge, publish,   */ | 
					
						
							|  |  |  | /* distribute, sublicense, and/or sell copies of the Software, and to    */ | 
					
						
							|  |  |  | /* permit persons to whom the Software is furnished to do so, subject to */ | 
					
						
							|  |  |  | /* the following conditions:                                             */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* The above copyright notice and this permission notice shall be        */ | 
					
						
							|  |  |  | /* included in all copies or substantial portions of the Software.       */ | 
					
						
							|  |  |  | /*                                                                       */ | 
					
						
							|  |  |  | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */ | 
					
						
							|  |  |  | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */ | 
					
						
							|  |  |  | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ | 
					
						
							|  |  |  | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */ | 
					
						
							|  |  |  | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */ | 
					
						
							|  |  |  | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */ | 
					
						
							|  |  |  | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */ | 
					
						
							|  |  |  | /*************************************************************************/ | 
					
						
							|  |  |  | #ifdef ANDROID_NATIVE_ACTIVITY
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <errno.h>
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | #include <jni.h>
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <EGL/egl.h>
 | 
					
						
							|  |  |  | #include <GLES2/gl2.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-13 21:46:57 +01:00
										 |  |  | #include "engine.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | #include "file_access_android.h"
 | 
					
						
							|  |  |  | #include "main/main.h"
 | 
					
						
							|  |  |  | #include "os_android.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-22 17:47:04 +07:00
										 |  |  | #include "project_settings.h"
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | #include <android/log.h>
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include <android/sensor.h>
 | 
					
						
							|  |  |  | #include <android/window.h>
 | 
					
						
							|  |  |  | #include <android_native_app_glue.h>
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <unistd.h>
 | 
					
						
							|  |  |  | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "godot", __VA_ARGS__))
 | 
					
						
							|  |  |  | #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "godot", __VA_ARGS__))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | extern "C" { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | JNIEXPORT void JNICALL Java_org_godotengine_godot_Godot_registerSingleton(JNIEnv *env, jobject obj, jstring name, jobject p_object); | 
					
						
							|  |  |  | JNIEXPORT void JNICALL Java_org_godotengine_godot_Godot_registerMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args); | 
					
						
							|  |  |  | JNIEXPORT jstring JNICALL Java_org_godotengine_godot_Godot_getGlobal(JNIEnv *env, jobject obj, jstring path); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class JNISingleton : public Object { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	GDCLASS(JNISingleton, Object); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	struct MethodData { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		jmethodID method; | 
					
						
							|  |  |  | 		Variant::Type ret_type; | 
					
						
							|  |  |  | 		Vector<Variant::Type> argtypes; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	jobject instance; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	Map<StringName, MethodData> method_map; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	JNIEnv *env; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | public: | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	void update_env(JNIEnv *p_env) { env = p_env; } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		print_line("attempt to call " + String(p_method)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		r_error.error = Variant::CallError::CALL_OK; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		Map<StringName, MethodData>::Element *E = method_map.find(p_method); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		if (!E) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			print_line("no exists"); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return Variant(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		int ac = E->get().argtypes.size(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (ac < p_argcount) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			print_line("fewargs"); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; | 
					
						
							|  |  |  | 			r_error.argument = ac; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return Variant(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (ac > p_argcount) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			print_line("manyargs"); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; | 
					
						
							|  |  |  | 			r_error.argument = ac; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return Variant(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < p_argcount; i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; | 
					
						
							|  |  |  | 				r_error.argument = i; | 
					
						
							|  |  |  | 				r_error.expected = E->get().argtypes[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		jvalue *v = NULL; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		if (p_argcount) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			v = (jvalue *)alloca(sizeof(jvalue) * p_argcount); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		for (int i = 0; i < p_argcount; i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			switch (E->get().argtypes[i]) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				case Variant::BOOL: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					v[i].z = *p_args[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case Variant::INT: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					v[i].i = *p_args[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case Variant::REAL: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					v[i].f = *p_args[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case Variant::STRING: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					String s = *p_args[i]; | 
					
						
							|  |  |  | 					jstring jStr = env->NewStringUTF(s.utf8().get_data()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					v[i].l = jStr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case Variant::STRING_ARRAY: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 					PoolVector<String> sarray = *p_args[i]; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					jobjectArray arr = env->NewObjectArray(sarray.size(), env->FindClass("java/lang/String"), env->NewStringUTF("")); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					for (int j = 0; j < sarray.size(); j++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						env->SetObjectArrayElement(arr, j, env->NewStringUTF(sarray[i].utf8().get_data())); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					v[i].l = arr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case Variant::INT_ARRAY: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 					PoolVector<int> array = *p_args[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					jintArray arr = env->NewIntArray(array.size()); | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 					PoolVector<int>::Read r = array.read(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					env->SetIntArrayRegion(arr, 0, array.size(), r.ptr()); | 
					
						
							|  |  |  | 					v[i].l = arr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case Variant::REAL_ARRAY: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 					PoolVector<float> array = *p_args[i]; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					jfloatArray arr = env->NewFloatArray(array.size()); | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 					PoolVector<float>::Read r = array.read(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					env->SetFloatArrayRegion(arr, 0, array.size(), r.ptr()); | 
					
						
							|  |  |  | 					v[i].l = arr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				default: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					ERR_FAIL_V(Variant()); | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		print_line("calling method!!"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		Variant ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		switch (E->get().ret_type) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			case Variant::NIL: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				print_line("call void"); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				env->CallVoidMethodA(instance, E->get().method, v); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case Variant::BOOL: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ret = env->CallBooleanMethodA(instance, E->get().method, v); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				print_line("call bool"); | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			case Variant::INT: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ret = env->CallIntMethodA(instance, E->get().method, v); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				print_line("call int"); | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			case Variant::REAL: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ret = env->CallFloatMethodA(instance, E->get().method, v); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case Variant::STRING: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				jobject o = env->CallObjectMethodA(instance, E->get().method, v); | 
					
						
							|  |  |  | 				String singname = env->GetStringUTFChars((jstring)o, NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case Variant::STRING_ARRAY: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance, E->get().method, v); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				int stringCount = env->GetArrayLength(arr); | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 				PoolVector<String> sarr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				for (int i = 0; i < stringCount; i++) { | 
					
						
							|  |  |  | 					jstring string = (jstring)env->GetObjectArrayElement(arr, i); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					const char *rawString = env->GetStringUTFChars(string, 0); | 
					
						
							|  |  |  | 					sarr.push_back(String(rawString)); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ret = sarr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 			case Variant::INT_ARRAY: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				jintArray arr = (jintArray)env->CallObjectMethodA(instance, E->get().method, v); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				int fCount = env->GetArrayLength(arr); | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 				PoolVector<int> sarr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				sarr.resize(fCount); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 				PoolVector<int>::Write w = sarr.write(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 				w = PoolVector<int>::Write(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ret = sarr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			case Variant::REAL_ARRAY: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				int fCount = env->GetArrayLength(arr); | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 				PoolVector<float> sarr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				sarr.resize(fCount); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 				PoolVector<float>::Write w = sarr.write(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				env->GetFloatArrayRegion(arr, 0, fCount, w.ptr()); | 
					
						
							| 
									
										
										
										
											2017-01-07 18:25:37 -03:00
										 |  |  | 				w = PoolVector<float>::Write(); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				ret = sarr; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} break; | 
					
						
							|  |  |  | 			default: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				print_line("failure.."); | 
					
						
							|  |  |  | 				ERR_FAIL_V(Variant()); | 
					
						
							|  |  |  | 			} break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		print_line("success"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	jobject get_instance() const { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		return instance; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	void set_instance(jobject p_instance) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		instance = p_instance; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	void add_method(const StringName &p_name, jmethodID p_method, const Vector<Variant::Type> &p_args, Variant::Type p_ret_type) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		MethodData md; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		md.method = p_method; | 
					
						
							|  |  |  | 		md.argtypes = p_args; | 
					
						
							|  |  |  | 		md.ret_type = p_ret_type; | 
					
						
							|  |  |  | 		method_map[p_name] = md; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	JNISingleton() {} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //JNIEnv *JNISingleton::env=NULL;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static HashMap<String, JNISingleton *> jni_singletons; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | struct engine { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	struct android_app *app; | 
					
						
							|  |  |  | 	OS_Android *os; | 
					
						
							|  |  |  | 	JNIEnv *jni; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ASensorManager *sensorManager; | 
					
						
							|  |  |  | 	const ASensor *accelerometerSensor; | 
					
						
							|  |  |  | 	const ASensor *magnetometerSensor; | 
					
						
							|  |  |  | 	const ASensor *gyroscopeSensor; | 
					
						
							|  |  |  | 	ASensorEventQueue *sensorEventQueue; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	bool display_active; | 
					
						
							|  |  |  | 	bool requested_quit; | 
					
						
							|  |  |  | 	int animating; | 
					
						
							|  |  |  | 	EGLDisplay display; | 
					
						
							|  |  |  | 	EGLSurface surface; | 
					
						
							|  |  |  | 	EGLContext context; | 
					
						
							|  |  |  | 	int32_t width; | 
					
						
							|  |  |  | 	int32_t height; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Initialize an EGL context for the current display. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static int engine_init_display(struct engine *engine, bool p_gl2) { | 
					
						
							|  |  |  | 	// initialize OpenGL ES and EGL
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	/*
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  |      * Here specify the attributes of the desired configuration. | 
					
						
							|  |  |  |      * Below, we select an EGLConfig with at least 8 bits per color | 
					
						
							|  |  |  |      * component compatible with on-screen windows | 
					
						
							|  |  |  |      */ | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	const EGLint gl2_attribs[] = { | 
					
						
							|  |  |  | 		//  EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
 | 
					
						
							|  |  |  | 		EGL_BLUE_SIZE, 4, | 
					
						
							|  |  |  | 		EGL_GREEN_SIZE, 4, | 
					
						
							|  |  |  | 		EGL_RED_SIZE, 4, | 
					
						
							|  |  |  | 		EGL_ALPHA_SIZE, 0, | 
					
						
							|  |  |  | 		EGL_DEPTH_SIZE, 16, | 
					
						
							|  |  |  | 		EGL_STENCIL_SIZE, EGL_DONT_CARE, | 
					
						
							|  |  |  | 		EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | 
					
						
							|  |  |  | 		EGL_NONE | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const EGLint gl1_attribs[] = { | 
					
						
							|  |  |  | 		//  EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
 | 
					
						
							|  |  |  | 		EGL_BLUE_SIZE, 4, | 
					
						
							|  |  |  | 		EGL_GREEN_SIZE, 4, | 
					
						
							|  |  |  | 		EGL_RED_SIZE, 4, | 
					
						
							|  |  |  | 		EGL_ALPHA_SIZE, 0, | 
					
						
							|  |  |  | 		EGL_DEPTH_SIZE, 16, | 
					
						
							|  |  |  | 		EGL_STENCIL_SIZE, EGL_DONT_CARE, | 
					
						
							|  |  |  | 		EGL_NONE | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const EGLint *attribs = p_gl2 ? gl2_attribs : gl1_attribs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	EGLint w, h, dummy, format; | 
					
						
							|  |  |  | 	EGLint numConfigs; | 
					
						
							|  |  |  | 	EGLConfig config; | 
					
						
							|  |  |  | 	EGLSurface surface; | 
					
						
							|  |  |  | 	EGLContext context; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	eglInitialize(display, 0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* Here, the application chooses the configuration it desires. In this
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  |      * sample, we have a very simplified selection process, where we pick | 
					
						
							|  |  |  |      * the first EGLConfig that matches our criteria */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	eglChooseConfig(display, attribs, &config, 1, &numConfigs); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	LOGI("Num configs: %i\n", numConfigs); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	/* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  |      * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). | 
					
						
							|  |  |  |      * As soon as we picked a EGLConfig, we can safely reconfigure the | 
					
						
							|  |  |  |      * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format); | 
					
						
							|  |  |  | 	//ANativeWindow_setFlags(engine->app->window, 0, 0, format|);
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	surface = eglCreateWindowSurface(display, config, engine->app->window, NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	const EGLint context_attribs[] = { | 
					
						
							|  |  |  | 		EGL_CONTEXT_CLIENT_VERSION, 2, | 
					
						
							|  |  |  | 		EGL_NONE | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 	context = eglCreateContext(display, config, EGL_NO_CONTEXT, p_gl2 ? context_attribs : NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { | 
					
						
							|  |  |  | 		LOGW("Unable to eglMakeCurrent"); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	eglQuerySurface(display, surface, EGL_WIDTH, &w); | 
					
						
							|  |  |  | 	eglQuerySurface(display, surface, EGL_HEIGHT, &h); | 
					
						
							|  |  |  | 	print_line("INIT VIDEO MODE: " + itos(w) + "," + itos(h)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	//engine->os->set_egl_extensions(eglQueryString(display,EGL_EXTENSIONS));
 | 
					
						
							|  |  |  | 	engine->os->init_video_mode(w, h); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	engine->display = display; | 
					
						
							|  |  |  | 	engine->context = context; | 
					
						
							|  |  |  | 	engine->surface = surface; | 
					
						
							|  |  |  | 	engine->width = w; | 
					
						
							|  |  |  | 	engine->height = h; | 
					
						
							|  |  |  | 	engine->display_active = true; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	//engine->state.angle = 0;
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	// Initialize GL state.
 | 
					
						
							|  |  |  | 	//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
 | 
					
						
							|  |  |  | 	glEnable(GL_CULL_FACE); | 
					
						
							|  |  |  | 	//  glShadeModel(GL_SMOOTH);
 | 
					
						
							|  |  |  | 	glDisable(GL_DEPTH_TEST); | 
					
						
							|  |  |  | 	LOGI("GL Version: %s - %s %s\n", glGetString(GL_VERSION), glGetString(GL_VENDOR), glGetString(GL_RENDERER)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static void engine_draw_frame(struct engine *engine) { | 
					
						
							|  |  |  | 	if (engine->display == NULL) { | 
					
						
							|  |  |  | 		// No display.
 | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	// Just fill the screen with a color.
 | 
					
						
							|  |  |  | 	//glClearColor(0,1,0,1);
 | 
					
						
							|  |  |  | 	//glClear(GL_COLOR_BUFFER_BIT);
 | 
					
						
							|  |  |  | 	if (engine->os && engine->os->main_loop_iterate() == true) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		engine->requested_quit = true; | 
					
						
							|  |  |  | 		return; //should exit instead
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	eglSwapBuffers(engine->display, engine->surface); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static void engine_term_display(struct engine *engine) { | 
					
						
							|  |  |  | 	if (engine->display != EGL_NO_DISPLAY) { | 
					
						
							|  |  |  | 		eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); | 
					
						
							|  |  |  | 		if (engine->context != EGL_NO_CONTEXT) { | 
					
						
							|  |  |  | 			eglDestroyContext(engine->display, engine->context); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if (engine->surface != EGL_NO_SURFACE) { | 
					
						
							|  |  |  | 			eglDestroySurface(engine->display, engine->surface); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		eglTerminate(engine->display); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	engine->animating = 0; | 
					
						
							|  |  |  | 	engine->display = EGL_NO_DISPLAY; | 
					
						
							|  |  |  | 	engine->context = EGL_NO_CONTEXT; | 
					
						
							|  |  |  | 	engine->surface = EGL_NO_SURFACE; | 
					
						
							|  |  |  | 	engine->display_active = false; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Process the next input event. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static int32_t engine_handle_input(struct android_app *app, AInputEvent *event) { | 
					
						
							|  |  |  | 	struct engine *engine = (struct engine *)app->userData; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (!engine->os) | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	switch (AInputEvent_getType(event)) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		case AINPUT_EVENT_TYPE_KEY: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			int ac = AKeyEvent_getAction(event); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			switch (ac) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				case AKEY_EVENT_ACTION_DOWN: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 					int32_t code = AKeyEvent_getKeyCode(event); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					if (code == AKEYCODE_BACK) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 						//AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
 | 
					
						
							|  |  |  | 						if (engine->os) | 
					
						
							|  |  |  | 							engine->os->main_loop_request_quit(); | 
					
						
							|  |  |  | 						return 1; | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 				case AKEY_EVENT_ACTION_UP: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				} break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 		case AINPUT_EVENT_TYPE_MOTION: { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			Vector<OS_Android::TouchPos> touchvec; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			int pc = AMotionEvent_getPointerCount(event); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			touchvec.resize(pc); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			for (int i = 0; i < pc; i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				touchvec[i].pos.x = AMotionEvent_getX(event, i); | 
					
						
							|  |  |  | 				touchvec[i].pos.y = AMotionEvent_getY(event, i); | 
					
						
							|  |  |  | 				touchvec[i].id = AMotionEvent_getPointerId(event, i); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			//System.out.printf("gaction: %d\n",event.getAction());
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			int pidx = (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> 8; | 
					
						
							|  |  |  | 			switch (AMotionEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 				case AMOTION_EVENT_ACTION_DOWN: { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					engine->os->process_touch(0, 0, touchvec); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-14 12:26:56 +01:00
										 |  |  | 					//System.out.printf("action down at: %f,%f\n", event.getX(),event.getY());
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case AMOTION_EVENT_ACTION_MOVE: { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					engine->os->process_touch(1, 0, touchvec); | 
					
						
							| 
									
										
										
										
											2017-01-14 12:26:56 +01:00
										 |  |  | 					/*
 | 
					
						
							|  |  |  | 					for(int i=0;i<event.getPointerCount();i++) { | 
					
						
							|  |  |  | 						System.out.printf("%d - moved to: %f,%f\n",i, event.getX(i),event.getY(i)); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					*/ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case AMOTION_EVENT_ACTION_POINTER_UP: { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					engine->os->process_touch(4, pidx, touchvec); | 
					
						
							| 
									
										
										
										
											2017-01-14 12:26:56 +01:00
										 |  |  | 					//System.out.printf("%d - s.up at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case AMOTION_EVENT_ACTION_POINTER_DOWN: { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					engine->os->process_touch(3, pidx, touchvec); | 
					
						
							| 
									
										
										
										
											2017-01-14 12:26:56 +01:00
										 |  |  | 					//System.out.printf("%d - s.down at: %f,%f\n",pointer_idx, event.getX(pointer_idx),event.getY(pointer_idx));
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 				case AMOTION_EVENT_ACTION_CANCEL: | 
					
						
							|  |  |  | 				case AMOTION_EVENT_ACTION_UP: { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					engine->os->process_touch(2, 0, touchvec); | 
					
						
							| 
									
										
										
										
											2017-01-14 12:26:56 +01:00
										 |  |  | 					/*
 | 
					
						
							|  |  |  | 					for(int i=0;i<event.getPointerCount();i++) { | 
					
						
							|  |  |  | 						System.out.printf("%d - up! %f,%f\n",i, event.getX(i),event.getY(i)); | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 					*/ | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				} break; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			return 1; | 
					
						
							|  |  |  | 		} break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**
 | 
					
						
							|  |  |  |  * Process the next main command. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static void _gfx_init(void *ud, bool p_gl2) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	struct engine *engine = (struct engine *)ud; | 
					
						
							|  |  |  | 	engine_init_display(engine, p_gl2); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static void engine_handle_cmd(struct android_app *app, int32_t cmd) { | 
					
						
							|  |  |  | 	struct engine *engine = (struct engine *)app->userData; | 
					
						
							|  |  |  | 	// LOGI("**** CMD %i\n",cmd);
 | 
					
						
							|  |  |  | 	switch (cmd) { | 
					
						
							|  |  |  | 		case APP_CMD_SAVE_STATE: | 
					
						
							|  |  |  | 			// The system has asked us to save our current state.  Do so.
 | 
					
						
							|  |  |  | 			//engine->app->savedState = malloc(sizeof(struct saved_state));
 | 
					
						
							|  |  |  | 			//*((struct saved_state*)engine->app->savedState) = engine->state;
 | 
					
						
							|  |  |  | 			//engine->app->savedStateSize = sizeof(struct saved_state);
 | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case APP_CMD_CONFIG_CHANGED: | 
					
						
							|  |  |  | 		case APP_CMD_WINDOW_RESIZED: { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (engine->display_active) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				EGLint w, h; | 
					
						
							|  |  |  | 				eglQuerySurface(engine->display, engine->surface, EGL_WIDTH, &w); | 
					
						
							|  |  |  | 				eglQuerySurface(engine->display, engine->surface, EGL_HEIGHT, &h); | 
					
						
							|  |  |  | 				//  if (w==engine->os->get_video_mode().width && h==engine->os->get_video_mode().height)
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 				//    break;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				engine_term_display(engine); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			engine->os->reload_gfx(); | 
					
						
							|  |  |  | 			engine_draw_frame(engine); | 
					
						
							|  |  |  | 			engine->animating = 1; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		} break; | 
					
						
							|  |  |  | 		case APP_CMD_INIT_WINDOW: | 
					
						
							|  |  |  | 			//The window is being shown, get it ready.
 | 
					
						
							|  |  |  | 			//LOGI("INIT WINDOW");
 | 
					
						
							|  |  |  | 			if (engine->app->window != NULL) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				if (engine->os == NULL) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					//do initialization here, when there's OpenGL! hackish but the only way
 | 
					
						
							|  |  |  | 					engine->os = new OS_Android(_gfx_init, engine); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					__android_log_print(ANDROID_LOG_INFO, "godot", "pre asdasd setup..."); | 
					
						
							| 
									
										
										
										
											2017-08-27 21:07:15 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					Error err = Main::setup("apk", 0, NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-19 17:00:46 -03:00
										 |  |  | 					String modules = ProjectSettings::get_singleton()->get("android/modules"); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					Vector<String> mods = modules.split(",", false); | 
					
						
							|  |  |  | 					mods.push_back("GodotOS"); | 
					
						
							|  |  |  | 					__android_log_print(ANDROID_LOG_INFO, "godot", "mod count: %i", mods.size()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					if (mods.size()) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						jclass activityClass = engine->jni->FindClass("android/app/NativeActivity"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						jmethodID getClassLoader = engine->jni->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						jobject cls = engine->jni->CallObjectMethod(app->activity->clazz, getClassLoader); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						jclass classLoader = engine->jni->FindClass("java/lang/ClassLoader"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						jmethodID findClass = engine->jni->GetMethodID(classLoader, "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						static JNINativeMethod methods[] = { | 
					
						
							|  |  |  | 							{ "registerSingleton", "(Ljava/lang/String;Ljava/lang/Object;)V", (void *)&Java_org_godotengine_godot_Godot_registerSingleton }, | 
					
						
							|  |  |  | 							{ "registerMethod", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V", (void *)&Java_org_godotengine_godot_Godot_registerMethod }, | 
					
						
							|  |  |  | 							{ "getGlobal", "(Ljava/lang/String;)Ljava/lang/String;", (void *)&Java_org_godotengine_godot_Godot_getGlobal }, | 
					
						
							|  |  |  | 						}; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						jstring gstrClassName = engine->jni->NewStringUTF("org/godotengine/godot/Godot"); | 
					
						
							|  |  |  | 						jclass GodotClass = (jclass)engine->jni->CallObjectMethod(cls, findClass, gstrClassName); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						__android_log_print(ANDROID_LOG_INFO, "godot", "godot ****^*^*?^*^*class data %x", GodotClass); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						engine->jni->RegisterNatives(GodotClass, methods, sizeof(methods) / sizeof(methods[0])); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 						for (int i = 0; i < mods.size(); i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 							String m = mods[i]; | 
					
						
							|  |  |  | 							//jclass singletonClass = engine->jni->FindClass(m.utf8().get_data());
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 							jstring strClassName = engine->jni->NewStringUTF(m.utf8().get_data()); | 
					
						
							|  |  |  | 							jclass singletonClass = (jclass)engine->jni->CallObjectMethod(cls, findClass, strClassName); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 							__android_log_print(ANDROID_LOG_INFO, "godot", "****^*^*?^*^*class data %x", singletonClass); | 
					
						
							|  |  |  | 							jmethodID initialize = engine->jni->GetStaticMethodID(singletonClass, "initialize", "(Landroid/app/Activity;)Lorg/godotengine/godot/Godot$SingletonBase;"); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 							jobject obj = engine->jni->CallStaticObjectMethod(singletonClass, initialize, app->activity->clazz); | 
					
						
							|  |  |  | 							__android_log_print(ANDROID_LOG_INFO, "godot", "****^*^*?^*^*class instance %x", obj); | 
					
						
							|  |  |  | 							jobject gob = engine->jni->NewGlobalRef(obj); | 
					
						
							|  |  |  | 						} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 					} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					if (!Main::start()) | 
					
						
							|  |  |  | 						return; //should exit instead and print the error
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 					engine->os->main_loop_begin(); | 
					
						
							|  |  |  | 				} else { | 
					
						
							|  |  |  | 					//i guess recreate resources?
 | 
					
						
							|  |  |  | 					engine->os->reload_gfx(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				engine->animating = 1; | 
					
						
							|  |  |  | 				engine_draw_frame(engine); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 		case APP_CMD_TERM_WINDOW: | 
					
						
							|  |  |  | 			// The window is being hidden or closed, clean it up.
 | 
					
						
							|  |  |  | 			//LOGI("TERM WINDOW");
 | 
					
						
							|  |  |  | 			engine_term_display(engine); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case APP_CMD_GAINED_FOCUS: | 
					
						
							|  |  |  | 			// When our app gains focus, we start monitoring the accelerometer.
 | 
					
						
							|  |  |  | 			if (engine->accelerometerSensor != NULL) { | 
					
						
							|  |  |  | 				ASensorEventQueue_enableSensor(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->accelerometerSensor); | 
					
						
							|  |  |  | 				// We'd like to get 60 events per second (in us).
 | 
					
						
							|  |  |  | 				ASensorEventQueue_setEventRate(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->accelerometerSensor, (1000L / 60) * 1000); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-11 09:42:23 +11:00
										 |  |  | 			// start monitoring gravity
 | 
					
						
							|  |  |  | 			if (engine->gravitySensor != NULL) { | 
					
						
							|  |  |  | 				ASensorEventQueue_enableSensor(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->gravitySensor); | 
					
						
							|  |  |  | 				// We'd like to get 60 events per second (in us).
 | 
					
						
							|  |  |  | 				ASensorEventQueue_setEventRate(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->gravitySensor, (1000L / 60) * 1000); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			// Also start monitoring the magnetometer.
 | 
					
						
							|  |  |  | 			if (engine->magnetometerSensor != NULL) { | 
					
						
							|  |  |  | 				ASensorEventQueue_enableSensor(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->magnetometerSensor); | 
					
						
							|  |  |  | 				// We'd like to get 60 events per second (in us).
 | 
					
						
							|  |  |  | 				ASensorEventQueue_setEventRate(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->magnetometerSensor, (1000L / 60) * 1000); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// And the gyroscope.
 | 
					
						
							|  |  |  | 			if (engine->gyroscopeSensor != NULL) { | 
					
						
							|  |  |  | 				ASensorEventQueue_enableSensor(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->gyroscopeSensor); | 
					
						
							|  |  |  | 				// We'd like to get 60 events per second (in us).
 | 
					
						
							|  |  |  | 				ASensorEventQueue_setEventRate(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->gyroscopeSensor, (1000L / 60) * 1000); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			engine->animating = 1; | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		case APP_CMD_LOST_FOCUS: | 
					
						
							|  |  |  | 			// When our app loses focus, we stop monitoring the sensors.
 | 
					
						
							|  |  |  | 			// This is to avoid consuming battery while not being used.
 | 
					
						
							|  |  |  | 			if (engine->accelerometerSensor != NULL) { | 
					
						
							|  |  |  | 				ASensorEventQueue_disableSensor(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->accelerometerSensor); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-11-11 09:42:23 +11:00
										 |  |  | 			if (engine->gravitySensor != NULL) { | 
					
						
							|  |  |  | 				ASensorEventQueue_disableSensor(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->gravitySensor); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (engine->magnetometerSensor != NULL) { | 
					
						
							|  |  |  | 				ASensorEventQueue_disableSensor(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->magnetometerSensor); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			if (engine->gyroscopeSensor != NULL) { | 
					
						
							|  |  |  | 				ASensorEventQueue_disableSensor(engine->sensorEventQueue, | 
					
						
							|  |  |  | 						engine->gyroscopeSensor); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			// Also stop animating.
 | 
					
						
							|  |  |  | 			engine->animating = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			engine_draw_frame(engine); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			break; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | void android_main(struct android_app *app) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	struct engine engine; | 
					
						
							|  |  |  | 	// Make sure glue isn't stripped.
 | 
					
						
							|  |  |  | 	app_dummy(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	memset(&engine, 0, sizeof(engine)); | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 	app->userData = &engine; | 
					
						
							|  |  |  | 	app->onAppCmd = engine_handle_cmd; | 
					
						
							|  |  |  | 	app->onInputEvent = engine_handle_input; | 
					
						
							|  |  |  | 	engine.app = app; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	engine.requested_quit = false; | 
					
						
							|  |  |  | 	engine.os = NULL; | 
					
						
							|  |  |  | 	engine.display_active = false; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 	FileAccessAndroid::asset_manager = app->activity->assetManager; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Prepare to monitor sensors
 | 
					
						
							|  |  |  | 	engine.sensorManager = ASensorManager_getInstance(); | 
					
						
							|  |  |  | 	engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, | 
					
						
							|  |  |  | 			ASENSOR_TYPE_ACCELEROMETER); | 
					
						
							| 
									
										
										
										
											2017-11-11 09:42:23 +11:00
										 |  |  | 	engine.gravitySensor = ASensorManager_getDefaultSensor(engine.sensorManager, | 
					
						
							|  |  |  | 			ASENSOR_TYPE_GRAVITY); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	engine.magnetometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, | 
					
						
							|  |  |  | 			ASENSOR_TYPE_MAGNETIC_FIELD); | 
					
						
							|  |  |  | 	engine.gyroscopeSensor = ASensorManager_getDefaultSensor(engine.sensorManager, | 
					
						
							|  |  |  | 			ASENSOR_TYPE_GYROSCOPE); | 
					
						
							|  |  |  | 	engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 			app->looper, LOOPER_ID_USER, NULL, NULL); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 	ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FULLSCREEN | AWINDOW_FLAG_KEEP_SCREEN_ON, 0); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 	app->activity->vm->AttachCurrentThread(&engine.jni, NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	// loop waiting for stuff to do.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	while (1) { | 
					
						
							|  |  |  | 		// Read all pending events.
 | 
					
						
							|  |  |  | 		int ident; | 
					
						
							|  |  |  | 		int events; | 
					
						
							|  |  |  | 		struct android_poll_source *source; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		// If not animating, we will block forever waiting for events.
 | 
					
						
							|  |  |  | 		// If animating, we loop until all events are read, then continue
 | 
					
						
							|  |  |  | 		// to draw the next frame of animation.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		int nullmax = 50; | 
					
						
							|  |  |  | 		while ((ident = ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events, | 
					
						
							|  |  |  | 						(void **)&source)) >= 0) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			// Process this event.
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (source != NULL) { | 
					
						
							|  |  |  | 				// LOGI("process\n");
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 				source->process(app, source); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				nullmax--; | 
					
						
							|  |  |  | 				if (nullmax < 0) | 
					
						
							|  |  |  | 					break; | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			// If a sensor has data, process it now.
 | 
					
						
							|  |  |  | 			// LOGI("events\n");
 | 
					
						
							|  |  |  | 			if (ident == LOOPER_ID_USER) { | 
					
						
							|  |  |  | 				if (engine.accelerometerSensor != NULL || engine.magnetometerSensor != NULL || engine.gyroscopeSensor != NULL) { | 
					
						
							|  |  |  | 					ASensorEvent event; | 
					
						
							|  |  |  | 					while (ASensorEventQueue_getEvents(engine.sensorEventQueue, | 
					
						
							|  |  |  | 								   &event, 1) > 0) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 						if (engine.os) { | 
					
						
							|  |  |  | 							if (event.acceleration != NULL) { | 
					
						
							|  |  |  | 								engine.os->process_accelerometer(Vector3(event.acceleration.x, event.acceleration.y, | 
					
						
							|  |  |  | 										event.acceleration.z)); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							if (event.magnetic != NULL) { | 
					
						
							|  |  |  | 								engine.os->process_magnetometer(Vector3(event.magnetic.x, event.magnetic.y, | 
					
						
							|  |  |  | 										event.magnetic.z)); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 							if (event.vector != NULL) { | 
					
						
							|  |  |  | 								engine.os->process_gyroscope(Vector3(event.vector.x, event.vector.y, | 
					
						
							|  |  |  | 										event.vector.z)); | 
					
						
							|  |  |  | 							} | 
					
						
							|  |  |  | 						} | 
					
						
							|  |  |  | 					} | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			// Check if we are exiting.
 | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 			if (app->destroyRequested != 0) { | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 				if (engine.os) { | 
					
						
							|  |  |  | 					engine.os->main_loop_request_quit(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2017-08-11 15:10:05 -04:00
										 |  |  | 				app->destroyRequested = 0; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			if (engine.requested_quit) { | 
					
						
							|  |  |  | 				engine_term_display(&engine); | 
					
						
							|  |  |  | 				exit(0); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			//     LOGI("end\n");
 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		// LOGI("engine animating? %i\n",engine.animating);
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (engine.animating) { | 
					
						
							|  |  |  | 			//do os render
 | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 			engine_draw_frame(&engine); | 
					
						
							|  |  |  | 			//LOGI("TERM WINDOW");
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | JNIEXPORT void JNICALL Java_org_godotengine_godot_Godot_registerSingleton(JNIEnv *env, jobject obj, jstring name, jobject p_object) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	String singname = env->GetStringUTFChars(name, NULL); | 
					
						
							|  |  |  | 	JNISingleton *s = memnew(JNISingleton); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	s->update_env(env); | 
					
						
							|  |  |  | 	s->set_instance(env->NewGlobalRef(p_object)); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	jni_singletons[singname] = s; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-11-13 21:46:57 +01:00
										 |  |  | 	Engine::get_singleton()->add_singleton(Engine::Singleton(singname, s)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static Variant::Type get_jni_type(const String &p_type) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	static struct { | 
					
						
							|  |  |  | 		const char *name; | 
					
						
							|  |  |  | 		Variant::Type type; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} _type_to_vtype[] = { | 
					
						
							|  |  |  | 		{ "void", Variant::NIL }, | 
					
						
							|  |  |  | 		{ "boolean", Variant::BOOL }, | 
					
						
							|  |  |  | 		{ "int", Variant::INT }, | 
					
						
							|  |  |  | 		{ "float", Variant::REAL }, | 
					
						
							|  |  |  | 		{ "java.lang.String", Variant::STRING }, | 
					
						
							|  |  |  | 		{ "[I", Variant::INT_ARRAY }, | 
					
						
							|  |  |  | 		{ "[F", Variant::REAL_ARRAY }, | 
					
						
							|  |  |  | 		{ "[Ljava.lang.String;", Variant::STRING_ARRAY }, | 
					
						
							|  |  |  | 		{ NULL, Variant::NIL } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int idx = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (_type_to_vtype[idx].name) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (p_type == _type_to_vtype[idx].name) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return _type_to_vtype[idx].type; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		idx++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return Variant::NIL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | static const char *get_jni_sig(const String &p_type) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	static struct { | 
					
						
							|  |  |  | 		const char *name; | 
					
						
							|  |  |  | 		const char *sig; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	} _type_to_vtype[] = { | 
					
						
							|  |  |  | 		{ "void", "V" }, | 
					
						
							|  |  |  | 		{ "boolean", "Z" }, | 
					
						
							|  |  |  | 		{ "int", "I" }, | 
					
						
							|  |  |  | 		{ "float", "F" }, | 
					
						
							|  |  |  | 		{ "java.lang.String", "Ljava/lang/String;" }, | 
					
						
							|  |  |  | 		{ "[I", "[I" }, | 
					
						
							|  |  |  | 		{ "[F", "[F" }, | 
					
						
							|  |  |  | 		{ "[Ljava.lang.String;", "[Ljava/lang/String;" }, | 
					
						
							|  |  |  | 		{ NULL, "V" } | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	int idx = 0; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	while (_type_to_vtype[idx].name) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		if (p_type == _type_to_vtype[idx].name) | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 			return _type_to_vtype[idx].sig; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		idx++; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return ""; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | JNIEXPORT jstring JNICALL Java_org_godotengine_godot_Godot_getGlobal(JNIEnv *env, jobject obj, jstring path) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	String js = env->GetStringUTFChars(path, NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-19 17:00:46 -03:00
										 |  |  | 	return env->NewStringUTF(ProjectSettings::get_singleton()->get(js).operator String().utf8().get_data()); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | JNIEXPORT void JNICALL Java_org_godotengine_godot_Godot_registerMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	String singname = env->GetStringUTFChars(sname, NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ERR_FAIL_COND(!jni_singletons.has(singname)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	JNISingleton *s = jni_singletons.get(singname); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	String mname = env->GetStringUTFChars(name, NULL); | 
					
						
							|  |  |  | 	String retval = env->GetStringUTFChars(ret, NULL); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	Vector<Variant::Type> types; | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	String cs = "("; | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	int stringCount = env->GetArrayLength(args); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	print_line("Singl:  " + singname + " Method: " + mname + " RetVal: " + retval); | 
					
						
							|  |  |  | 	for (int i = 0; i < stringCount; i++) { | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		jstring string = (jstring)env->GetObjectArrayElement(args, i); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 		const char *rawString = env->GetStringUTFChars(string, 0); | 
					
						
							|  |  |  | 		types.push_back(get_jni_type(String(rawString))); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		cs += get_jni_sig(String(rawString)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	cs += ")"; | 
					
						
							|  |  |  | 	cs += get_jni_sig(retval); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	jclass cls = env->GetObjectClass(s->get_instance()); | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	print_line("METHOD: " + mname + " sig: " + cs); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	jmethodID mid = env->GetMethodID(cls, mname.ascii().get_data(), cs.ascii().get_data()); | 
					
						
							|  |  |  | 	if (!mid) { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 		print_line("FAILED GETTING METHOID " + mname); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-03-05 16:44:50 +01:00
										 |  |  | 	s->add_method(mname, mid, types, get_jni_type(retval)); | 
					
						
							| 
									
										
										
										
											2014-02-09 22:10:30 -03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |