diff --git a/src/image/codec/android-image.cpp b/src/image/codec/android-image.cpp index 8a182422..379b4f69 100644 --- a/src/image/codec/android-image.cpp +++ b/src/image/codec/android-image.cpp @@ -17,6 +17,10 @@ #include #include +extern "C" { +#include +} + #include "core.h" #include "../../image/image-private.h" @@ -25,8 +29,7 @@ using namespace std; namespace lol { -extern JavaVM *g_vm; -extern jobject g_activity; +extern ANativeActivity *g_activity; /* * Image implementation class @@ -49,13 +52,13 @@ private: bool AndroidImageData::Open(char const *path) { JNIEnv *env; - jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); + jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2); if (res < 0) { #if !LOL_BUILD_RELEASE Log::Error("JVM environment not found, trying to attach thread\n"); #endif - res = g_vm->AttachCurrentThread(&env, nullptr); + res = g_activity->vm->AttachCurrentThread(&env, nullptr); } if (res < 0) { @@ -64,13 +67,13 @@ bool AndroidImageData::Open(char const *path) #endif return false; } - jclass cls = env->GetObjectClass(g_activity); + jclass cls = env->GetObjectClass(g_activity->clazz); jmethodID mid; mid = env->GetMethodID(cls, "openImage", "(Ljava/lang/String;)Landroid/graphics/Bitmap;"); jstring name = env->NewStringUTF(path); - bmp = env->CallObjectMethod(g_activity, mid, name); + bmp = env->CallObjectMethod(g_activity->clazz, mid, name); env->DeleteLocalRef(name); if (!bmp) { @@ -83,15 +86,15 @@ bool AndroidImageData::Open(char const *path) /* Get image dimensions */ mid = env->GetMethodID(cls, "getWidth", "(Landroid/graphics/Bitmap;)I"); - m_size.x = env->CallIntMethod(g_activity, mid, bmp); + m_size.x = env->CallIntMethod(g_activity->clazz, mid, bmp); mid = env->GetMethodID(cls, "getHeight", "(Landroid/graphics/Bitmap;)I"); - m_size.y = env->CallIntMethod(g_activity, mid, bmp); + m_size.y = env->CallIntMethod(g_activity->clazz, mid, bmp); /* Get pixels */ array = env->NewIntArray(m_size.x * m_size.y); env->NewGlobalRef(array); mid = env->GetMethodID(cls, "getPixels", "(Landroid/graphics/Bitmap;[I)V"); - env->CallVoidMethod(g_activity, mid, bmp, array); + env->CallVoidMethod(g_activity->clazz, mid, bmp, array); pixels = env->GetIntArrayElements(array, 0); for (int n = 0; n < m_size.x * m_size.y; n++) @@ -108,7 +111,7 @@ bool AndroidImageData::Open(char const *path) bool AndroidImageData::Close() { JNIEnv *env; - jint res = g_vm->GetEnv((void **)&env, JNI_VERSION_1_2); + jint res = g_activity->vm->GetEnv((void **)&env, JNI_VERSION_1_2); if (res < 0) { #if !LOL_BUILD_RELEASE @@ -116,7 +119,7 @@ bool AndroidImageData::Close() #endif return false; } - jclass cls = env->GetObjectClass(g_activity); + jclass cls = env->GetObjectClass(g_activity->clazz); jmethodID mid; env->ReleaseIntArrayElements(array, pixels, 0); @@ -124,7 +127,7 @@ bool AndroidImageData::Close() /* Free image */ mid = env->GetMethodID(cls, "closeImage", "(Landroid/graphics/Bitmap;)V"); - env->CallVoidMethod(g_activity, mid, bmp); + env->CallVoidMethod(g_activity->clazz, mid, bmp); env->DeleteGlobalRef(bmp); return true; diff --git a/src/platform/android/androidapp.cpp b/src/platform/android/androidapp.cpp index 76006bcb..bd1e603e 100644 --- a/src/platform/android/androidapp.cpp +++ b/src/platform/android/androidapp.cpp @@ -36,7 +36,6 @@ using namespace lol; namespace lol { -JavaVM *g_vm; ANativeActivity *g_activity; AAssetManager *g_assets; }; /* namespace lol */ @@ -91,6 +90,8 @@ public: SavedState m_state; + bool m_video_ready; + private: void HandleCommand(int32_t cmd); int32_t HandleInput(AInputEvent* event); @@ -152,7 +153,7 @@ int lol::AndroidAppData::CreateDisplay() eglQuerySurface(m_display, m_surface, EGL_HEIGHT, &h); /* Launch our renderer */ - Log::Info("Java layer initialising renderer"); + Log::Info("Java layer initialising renderer (%dx%d)", w, h); Video::Setup(ivec2(w, h)); return 0; @@ -199,12 +200,13 @@ int32_t lol::AndroidAppData::HandleInput(AInputEvent* event) switch (AInputEvent_getType(event)) { case AINPUT_EVENT_TYPE_MOTION: - //We need the max if we want coherent mouse speed between axis - float max_screen_size = lol::max(m_wanted_resolution.x, m_wanted_resolution.y); + // We need the max if we want consistent mouse speed between axis + float max_screen_size = lol::max(m_wanted_resolution.x, + m_wanted_resolution.y); /* FIXME: we flip the Y axis here, but is it the right place? */ ivec2 pos(AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0)); - pos = pos * m_wanted_resolution / Video::GetSize(); + pos *= m_wanted_resolution / Video::GetSize(); pos.y = m_wanted_resolution.y - 1 - pos.y; m_mouse->SetCursor(0, vec2(pos) / vec2(m_wanted_resolution), pos); // Note: 100.0f is an arbitrary value that makes it feel about the same than an xbox controller joystick @@ -244,7 +246,8 @@ void lol::AndroidAppData::HandleCommand(int32_t cmd) if (m_native_app->window != nullptr) { CreateDisplay(); - DrawFrame(); + m_video_ready = true; + //DrawFrame(); } break; case APP_CMD_TERM_WINDOW: @@ -265,21 +268,19 @@ AndroidAppData *g_data; void android_main(android_app* native_app) { - Log::Info("Java layer calling main() for app 0x%08lx", (long)native_app); + Log::Info("Java layer calling android_main() for app 0x%08lx", + (long)native_app); /* Register native activity */ g_activity = native_app->activity; - /* Register Java VM */ - g_vm = g_activity->vm; - /* Get JNI environment */ JNIEnv *jni_env; - jint res = g_vm->GetEnv((void **)&jni_env, JNI_VERSION_1_2); + jint res = g_activity->vm->GetEnv((void **)&jni_env, JNI_VERSION_1_2); if (res < 0) { - Log::Error("JVM environment not found, trying to attach thread\n"); - res = g_vm->AttachCurrentThread(&jni_env, nullptr); + Log::Info("JVM environment not found, trying to attach thread\n"); + res = g_activity->vm->AttachCurrentThread(&jni_env, nullptr); } if (res < 0) { @@ -298,6 +299,7 @@ void android_main(android_app* native_app) /* Create our app data */ g_data = new AndroidAppData(); g_data->m_native_app = native_app; + g_data->m_video_ready = false; /* Make sure glue isn't stripped */ app_dummy(); @@ -313,18 +315,22 @@ void android_main(android_app* native_app) } int argc = 1; - char *argv[] = { "", nullptr }; + char *argv[] = { const_cast(""), nullptr }; char *env[] = { nullptr }; - /* FIXME: this is fucking pathetic. */ - while (!g_scene) + /* Wait for GL context */ + while (!g_data->m_video_ready) { - Log::Debug("waiting for g_scene...\n"); - Timer t; - t.Wait(0.1); + int ident, fdesc, events; + struct android_poll_source* source; + + ident = ALooper_pollAll(0, &fdesc, &events, (void**)&source); + + if (ident >= 0 && source) + source->process(native_app, source); } - Log::Info("running main()\n"); + Log::Info("Java layer running real main()\n"); /* Call the user's main() function. One of these will work. */ lol_android_main();