|
@@ -47,8 +47,7 @@ void android_main(android_app *app) |
|
|
Thread::setName("Main"); |
|
|
|
|
|
try { |
|
|
app_dummy(); |
|
|
char *argv[] = {strdup(PROJECT_NAME), NULL}; |
|
|
char *argv[] = {strdup(PROJECT_NAME), nullptr}; |
|
|
main(ARRLEN(argv) - 1, argv); |
|
|
free(argv[0]); |
|
|
} catch (std::exception &e) { |
|
@@ -64,85 +63,73 @@ void android_main(android_app *app) |
|
|
exit(retval); |
|
|
} |
|
|
|
|
|
/* handler for finished message box input */ |
|
|
/* Intentionally NOT in namespace porting */ |
|
|
/* TODO this doesn't work as expected, no idea why but there's a workaround */ |
|
|
/* for it right now */ |
|
|
/** |
|
|
* Handler for finished message box input |
|
|
* Intentionally NOT in namespace porting |
|
|
* ToDo: this doesn't work as expected, there's a workaround for it right now |
|
|
*/ |
|
|
extern "C" { |
|
|
JNIEXPORT void JNICALL Java_net_minetest_minetest_GameActivity_putMessageBoxResult( |
|
|
JNIEnv * env, jclass thiz, jstring text) |
|
|
JNIEnv *env, jclass thiz, jstring text) |
|
|
{ |
|
|
errorstream << "Java_net_minetest_minetest_GameActivity_putMessageBoxResult got: " |
|
|
<< std::string((const char*)env->GetStringChars(text,0)) |
|
|
<< std::endl; |
|
|
errorstream << |
|
|
"Java_net_minetest_minetest_GameActivity_putMessageBoxResult got: " << |
|
|
std::string((const char*) env->GetStringChars(text, nullptr)) << std::endl; |
|
|
} |
|
|
} |
|
|
|
|
|
namespace porting { |
|
|
|
|
|
std::string path_storage = DIR_DELIM "sdcard" DIR_DELIM; |
|
|
|
|
|
android_app* app_global; |
|
|
JNIEnv* jnienv; |
|
|
android_app *app_global; |
|
|
JNIEnv *jnienv; |
|
|
jclass nativeActivity; |
|
|
|
|
|
jclass findClass(std::string classname) |
|
|
jclass findClass(const std::string &classname) |
|
|
{ |
|
|
if (jnienv == 0) { |
|
|
return 0; |
|
|
} |
|
|
if (jnienv == nullptr) |
|
|
return nullptr; |
|
|
|
|
|
jclass nativeactivity = jnienv->FindClass("android/app/NativeActivity"); |
|
|
jmethodID getClassLoader = |
|
|
jnienv->GetMethodID(nativeactivity,"getClassLoader", |
|
|
"()Ljava/lang/ClassLoader;"); |
|
|
jobject cls = |
|
|
jnienv->CallObjectMethod(app_global->activity->clazz, getClassLoader); |
|
|
jmethodID getClassLoader = jnienv->GetMethodID( |
|
|
nativeactivity, "getClassLoader", "()Ljava/lang/ClassLoader;"); |
|
|
jobject cls = jnienv->CallObjectMethod( |
|
|
app_global->activity->clazz, getClassLoader); |
|
|
jclass classLoader = jnienv->FindClass("java/lang/ClassLoader"); |
|
|
jmethodID findClass = |
|
|
jnienv->GetMethodID(classLoader, "loadClass", |
|
|
jmethodID findClass = jnienv->GetMethodID(classLoader, "loadClass", |
|
|
"(Ljava/lang/String;)Ljava/lang/Class;"); |
|
|
jstring strClassName = |
|
|
jnienv->NewStringUTF(classname.c_str()); |
|
|
jstring strClassName = jnienv->NewStringUTF(classname.c_str()); |
|
|
return (jclass) jnienv->CallObjectMethod(cls, findClass, strClassName); |
|
|
} |
|
|
|
|
|
void initAndroid() |
|
|
{ |
|
|
porting::jnienv = NULL; |
|
|
porting::jnienv = nullptr; |
|
|
JavaVM *jvm = app_global->activity->vm; |
|
|
JavaVMAttachArgs lJavaVMAttachArgs; |
|
|
lJavaVMAttachArgs.version = JNI_VERSION_1_6; |
|
|
lJavaVMAttachArgs.name = PROJECT_NAME_C "NativeThread"; |
|
|
lJavaVMAttachArgs.group = NULL; |
|
|
#ifdef NDEBUG |
|
|
// This is a ugly hack as arm v7a non debuggable builds crash without this |
|
|
// printf ... if someone finds out why please fix it! |
|
|
infostream << "Attaching native thread. " << std::endl; |
|
|
#endif |
|
|
if ( jvm->AttachCurrentThread(&porting::jnienv, &lJavaVMAttachArgs) == JNI_ERR) { |
|
|
lJavaVMAttachArgs.group = nullptr; |
|
|
|
|
|
if (jvm->AttachCurrentThread(&porting::jnienv, &lJavaVMAttachArgs) == JNI_ERR) { |
|
|
errorstream << "Failed to attach native thread to jvm" << std::endl; |
|
|
exit(-1); |
|
|
} |
|
|
|
|
|
nativeActivity = findClass("net/minetest/minetest/GameActivity"); |
|
|
if (nativeActivity == 0) { |
|
|
if (nativeActivity == nullptr) |
|
|
errorstream << |
|
|
"porting::initAndroid unable to find java native activity class" << |
|
|
std::endl; |
|
|
} |
|
|
|
|
|
#ifdef GPROF |
|
|
/* in the start-up code */ |
|
|
// in the start-up code |
|
|
__android_log_print(ANDROID_LOG_ERROR, PROJECT_NAME_C, |
|
|
"Initializing GPROF profiler"); |
|
|
monstartup("libminetest.so"); |
|
|
monstartup("libMinetest.so"); |
|
|
#endif |
|
|
} |
|
|
|
|
|
void cleanupAndroid() |
|
|
{ |
|
|
|
|
|
#ifdef GPROF |
|
|
errorstream << "Shutting down GPROF profiler" << std::endl; |
|
|
setenv("CPUPROFILE", (path_user + DIR_DELIM + "gmon.out").c_str(), 1); |
|
@@ -157,7 +144,7 @@ static std::string javaStringToUTF8(jstring js) |
|
|
{ |
|
|
std::string str; |
|
|
// Get string as a UTF-8 c-string |
|
|
const char *c_str = jnienv->GetStringUTFChars(js, NULL); |
|
|
const char *c_str = jnienv->GetStringUTFChars(js, nullptr); |
|
|
// Save it |
|
|
str = c_str; |
|
|
// And free the c-string |
|
@@ -166,17 +153,15 @@ static std::string javaStringToUTF8(jstring js) |
|
|
} |
|
|
|
|
|
// Calls static method if obj is NULL |
|
|
static std::string getAndroidPath(jclass cls, jobject obj, jclass cls_File, |
|
|
jmethodID mt_getAbsPath, const char *getter) |
|
|
static std::string getAndroidPath( |
|
|
jclass cls, jobject obj, jmethodID mt_getAbsPath, const char *getter) |
|
|
{ |
|
|
// Get getter method |
|
|
jmethodID mt_getter; |
|
|
if (obj) |
|
|
mt_getter = jnienv->GetMethodID(cls, getter, |
|
|
"()Ljava/io/File;"); |
|
|
mt_getter = jnienv->GetMethodID(cls, getter, "()Ljava/io/File;"); |
|
|
else |
|
|
mt_getter = jnienv->GetStaticMethodID(cls, getter, |
|
|
"()Ljava/io/File;"); |
|
|
mt_getter = jnienv->GetStaticMethodID(cls, getter, "()Ljava/io/File;"); |
|
|
|
|
|
// Call getter |
|
|
jobject ob_file; |
|
@@ -186,8 +171,7 @@ static std::string getAndroidPath(jclass cls, jobject obj, jclass cls_File, |
|
|
ob_file = jnienv->CallStaticObjectMethod(cls, mt_getter); |
|
|
|
|
|
// Call getAbsolutePath |
|
|
jstring js_path = (jstring) jnienv->CallObjectMethod(ob_file, |
|
|
mt_getAbsPath); |
|
|
auto js_path = (jstring) jnienv->CallObjectMethod(ob_file, mt_getAbsPath); |
|
|
|
|
|
return javaStringToUTF8(js_path); |
|
|
} |
|
@@ -201,26 +185,24 @@ void initializePathsAndroid() |
|
|
// Get getAbsolutePath method |
|
|
jmethodID mt_getAbsPath = jnienv->GetMethodID(cls_File, |
|
|
"getAbsolutePath", "()Ljava/lang/String;"); |
|
|
std::string path_storage = getAndroidPath(cls_Env, nullptr, |
|
|
mt_getAbsPath, "getExternalStorageDirectory"); |
|
|
|
|
|
path_cache = getAndroidPath(nativeActivity, app_global->activity->clazz, |
|
|
cls_File, mt_getAbsPath, "getCacheDir"); |
|
|
path_storage = getAndroidPath(cls_Env, NULL, cls_File, mt_getAbsPath, |
|
|
"getExternalStorageDirectory"); |
|
|
path_user = path_storage + DIR_DELIM + PROJECT_NAME_C; |
|
|
path_share = path_storage + DIR_DELIM + PROJECT_NAME_C; |
|
|
|
|
|
path_cache = getAndroidPath(nativeActivity, |
|
|
app_global->activity->clazz, mt_getAbsPath, "getCacheDir"); |
|
|
migrateCachePath(); |
|
|
} |
|
|
|
|
|
void showInputDialog(const std::string& acceptButton, const std::string& hint, |
|
|
const std::string& current, int editType) |
|
|
void showInputDialog(const std::string &acceptButton, const std::string &hint, |
|
|
const std::string ¤t, int editType) |
|
|
{ |
|
|
jmethodID showdialog = jnienv->GetMethodID(nativeActivity,"showDialog", |
|
|
jmethodID showdialog = jnienv->GetMethodID(nativeActivity, "showDialog", |
|
|
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V"); |
|
|
|
|
|
if (showdialog == 0) { |
|
|
assert("porting::showInputDialog unable to find java show dialog method" == 0); |
|
|
} |
|
|
FATAL_ERROR_IF(showdialog == nullptr, |
|
|
"porting::showInputDialog unable to find java show dialog method"); |
|
|
|
|
|
jstring jacceptButton = jnienv->NewStringUTF(acceptButton.c_str()); |
|
|
jstring jhint = jnienv->NewStringUTF(hint.c_str()); |
|
@@ -236,9 +218,8 @@ int getInputDialogState() |
|
|
jmethodID dialogstate = jnienv->GetMethodID(nativeActivity, |
|
|
"getDialogState", "()I"); |
|
|
|
|
|
if (dialogstate == 0) { |
|
|
assert("porting::getInputDialogState unable to find java dialog state method" == 0); |
|
|
} |
|
|
FATAL_ERROR_IF(dialogstate == nullptr, |
|
|
"porting::getInputDialogState unable to find java dialog state method"); |
|
|
|
|
|
return jnienv->CallIntMethod(app_global->activity->clazz, dialogstate); |
|
|
} |
|
@@ -248,14 +229,13 @@ std::string getInputDialogValue() |
|
|
jmethodID dialogvalue = jnienv->GetMethodID(nativeActivity, |
|
|
"getDialogValue", "()Ljava/lang/String;"); |
|
|
|
|
|
if (dialogvalue == 0) { |
|
|
assert("porting::getInputDialogValue unable to find java dialog value method" == 0); |
|
|
} |
|
|
FATAL_ERROR_IF(dialogvalue == nullptr, |
|
|
"porting::getInputDialogValue unable to find java dialog value method"); |
|
|
|
|
|
jobject result = jnienv->CallObjectMethod(app_global->activity->clazz, |
|
|
dialogvalue); |
|
|
|
|
|
const char* javachars = jnienv->GetStringUTFChars((jstring) result,0); |
|
|
const char *javachars = jnienv->GetStringUTFChars((jstring) result, nullptr); |
|
|
std::string text(javachars); |
|
|
jnienv->ReleaseStringUTFChars((jstring) result, javachars); |
|
|
|
|
@@ -269,12 +249,11 @@ float getDisplayDensity() |
|
|
static float value = 0; |
|
|
|
|
|
if (firstrun) { |
|
|
jmethodID getDensity = jnienv->GetMethodID(nativeActivity, "getDensity", |
|
|
"()F"); |
|
|
jmethodID getDensity = jnienv->GetMethodID(nativeActivity, |
|
|
"getDensity", "()F"); |
|
|
|
|
|
if (getDensity == 0) { |
|
|
assert("porting::getDisplayDensity unable to find java getDensity method" == 0); |
|
|
} |
|
|
FATAL_ERROR_IF(getDensity == nullptr, |
|
|
"porting::getDisplayDensity unable to find java getDensity method"); |
|
|
|
|
|
value = jnienv->CallFloatMethod(app_global->activity->clazz, getDensity); |
|
|
firstrun = false; |
|
@@ -291,19 +270,17 @@ v2u32 getDisplaySize() |
|
|
jmethodID getDisplayWidth = jnienv->GetMethodID(nativeActivity, |
|
|
"getDisplayWidth", "()I"); |
|
|
|
|
|
if (getDisplayWidth == 0) { |
|
|
assert("porting::getDisplayWidth unable to find java getDisplayWidth method" == 0); |
|
|
} |
|
|
FATAL_ERROR_IF(getDisplayWidth == nullptr, |
|
|
"porting::getDisplayWidth unable to find java getDisplayWidth method"); |
|
|
|
|
|
retval.X = jnienv->CallIntMethod(app_global->activity->clazz, |
|
|
getDisplayWidth); |
|
|
|
|
|
jmethodID getDisplayHeight = jnienv->GetMethodID(nativeActivity, |
|
|
"getDisplayHeight", "()I"); |
|
|
|
|
|
if (getDisplayHeight == 0) { |
|
|
assert("porting::getDisplayHeight unable to find java getDisplayHeight method" == 0); |
|
|
} |
|
|
FATAL_ERROR_IF(getDisplayHeight == nullptr, |
|
|
"porting::getDisplayHeight unable to find java getDisplayHeight method"); |
|
|
|
|
|
retval.Y = jnienv->CallIntMethod(app_global->activity->clazz, |
|
|
getDisplayHeight); |
|
|