Browse Source

android: switch to NativeActivity instead of rolling our own Java crap;

no known regressions yet.
legacy
Sam Hocevar sam 12 years ago
parent
commit
3af7e62b6a
7 changed files with 271 additions and 304 deletions
  1. +6
    -3
      build/android/AndroidManifest.xml
  2. +14
    -196
      build/android/LolActivity.java
  3. +4
    -4
      build/autotools/common.am
  4. +2
    -2
      build/lol-build
  5. +1
    -1
      configure.ac
  6. +244
    -96
      src/platform/android/androidapp.cpp
  7. +0
    -2
      src/platform/android/androidapp.h

+ 6
- 3
build/android/AndroidManifest.xml View File

@@ -1,19 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.lolengine"
package="net.lolengine.lol_@PROGRAM@"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name"
android:icon="@drawable/icon">
<activity android:name=".LolActivity"
<activity android:name="net.lolengine.LolActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="landscape"
android:label="@string/app_name"
android:launchMode="singleTask">
<meta-data android:name="android.app.lib_name"
android:value="@PROGRAM@" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="8" />
<uses-sdk android:minSdkVersion="9" />
</manifest>

+ 14
- 196
build/android/LolActivity.java View File

@@ -10,65 +10,32 @@

package net.lolengine;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.app.NativeActivity;

import android.content.res.AssetManager; /* getAssets() */
import android.content.res.Resources; /* getResources() */
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.view.Window;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.opengles.GL10;

/* FIXME: this needs to have a different name for each project */
public class LolActivity extends Activity
public class LolActivity extends NativeActivity
{
@Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
requestWindowFeature(Window.FEATURE_NO_TITLE);

nativeInit();

mView = new LolView(getApplication());
setContentView(mView);
}

@Override protected void onPause()
static
{
super.onPause();
mView.onPause();
/* Need to preload libstlport_shared.so somewhere; also need to
* preload lib@PROGRAM@.so otherwise nativeInit() can’t be found. */
System.loadLibrary("stlport_shared");
System.loadLibrary("@PROGRAM@");
}

@Override protected void onResume()
public LolActivity()
{
super.onResume();
mView.onResume();
nativeInit();
}

private LolView mView;
private native void nativeInit();

static
{
System.loadLibrary("stlport_shared");
System.loadLibrary("@PROGRAM@");
}
/*
* Bitmap loading helpers
*/

public Bitmap openImage(String name)
{
@@ -94,154 +61,5 @@ public class LolActivity extends Activity
{
bmp.recycle();
}

private native void nativeInit();
}

class LolView extends GLSurfaceView
{
public LolView(Context context)
{
super(context);
setEGLContextFactory(new ContextFactory());
//setEGLConfigChooser(new ConfigChooser(4, 4, 4, 0, 8, 0));
setEGLConfigChooser(new ConfigChooser(4, 4, 4, 4, 8, 0));
setRenderer(new LolRenderer());
}

private static class ContextFactory implements GLSurfaceView.EGLContextFactory
{
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay dpy, EGLConfig cfg)
{
Log.w("LOL", "creating OpenGL ES 2.0 context");
int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
EGLContext ctx = egl.eglCreateContext(dpy, cfg, EGL10.EGL_NO_CONTEXT, attrib_list);
return ctx;
}

public void destroyContext(EGL10 egl, EGLDisplay dpy, EGLContext ctx)
{
egl.eglDestroyContext(dpy, ctx);
}
}

private static class ConfigChooser implements GLSurfaceView.EGLConfigChooser
{
public ConfigChooser(int r, int g, int b, int a, int depth, int stencil)
{
mRed = r;
mGreen = g;
mBlue = b;
mAlpha = a;
mDepth = depth;
mStencil = stencil;
}

private static int EGL_OPENGL_ES2_BIT = 4;
private static int[] s_configAttribs2 =
{
// EGL10.EGL_BUFFER_SIZE, 16,
EGL10.EGL_DEPTH_SIZE, 8,
EGL10.EGL_RED_SIZE, 4,
EGL10.EGL_GREEN_SIZE, 4,
EGL10.EGL_BLUE_SIZE, 4,
// EGL10.EGL_ALPHA_SIZE, 4,
EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL10.EGL_NONE
};

public EGLConfig chooseConfig(EGL10 egl, EGLDisplay dpy)
{
int[] num_config = new int[1];
egl.eglChooseConfig(dpy, s_configAttribs2, null, 0, num_config);

int n = num_config[0];
if (n <= 0)
throw new IllegalArgumentException("No GLES configs");

EGLConfig[] configs = new EGLConfig[n];
egl.eglChooseConfig(dpy, s_configAttribs2, configs, n, num_config);
return choose(egl, dpy, configs);
}

public EGLConfig choose(EGL10 egl, EGLDisplay dpy, EGLConfig[] configs)
{
for(EGLConfig cfg : configs)
{
/* Do not complain if we get more bits than we asked. */
if (get(egl, dpy, cfg, EGL10.EGL_STENCIL_SIZE, 0) >= mStencil
&& get(egl, dpy, cfg, EGL10.EGL_DEPTH_SIZE, 0) >= mDepth
&& get(egl, dpy, cfg, EGL10.EGL_RED_SIZE, 0) >= mRed
&& get(egl, dpy, cfg, EGL10.EGL_GREEN_SIZE, 0) >= mGreen
&& get(egl, dpy, cfg, EGL10.EGL_BLUE_SIZE, 0) >= mBlue
&& get(egl, dpy, cfg, EGL10.EGL_ALPHA_SIZE, 0) >= mAlpha)
return cfg;
}
return null;
}

private int get(EGL10 egl, EGLDisplay dpy, EGLConfig cfg,
int attr, int defval)
{
int[] value = new int[1];

if (egl.eglGetConfigAttrib(dpy, cfg, attr, value))
return value[0];
return defval;
}

protected int mRed, mGreen, mBlue, mAlpha, mDepth, mStencil;
}

public boolean onTouchEvent(final MotionEvent ev)
{
final int action = ev.getAction();
switch (action)
{
case MotionEvent.ACTION_DOWN:
nativeMove((int)ev.getX(), (int)ev.getY());
nativeDown();
break;
case MotionEvent.ACTION_UP:
nativeMove((int)ev.getX(), (int)ev.getY());
nativeUp();
break;
case MotionEvent.ACTION_MOVE:
nativeMove((int)ev.getX(), (int)ev.getY());
break;
}

return true;
}

private static native void nativePause();
private static native void nativeDown();
private static native void nativeUp();
private static native void nativeMove(int x, int y);
}

class LolRenderer implements GLSurfaceView.Renderer
{
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
nativeInit();
}

public void onSurfaceChanged(GL10 gl, int w, int h)
{
Log.w("LOL", String.format("resizing to %dx%d", w, h));
nativeResize(w, h);
}

public void onDrawFrame(GL10 gl)
{
nativeRender();
}

private static native void nativeInit();
private static native void nativeResize(int w, int h);
private static native void nativeRender();
private static native void nativeDone();
}


+ 4
- 4
build/autotools/common.am View File

@@ -116,17 +116,17 @@ all-local-android: $(foreach p, $(PROGRAMS:%$(EXEEXT)=%), .$(p).androidstamp)
rm -rf "$(d)"
$(MKDIR_P) "$(d)" $(sort $(foreach f, $($(p)_DATA), "$(d)/assets/$(dir $(f))"))
$(foreach f, $($(p)_DATA), $(LN_S) "$(abs_srcdir)/$(f)" "$(d)/assets/$(f)" &&) true
$(SED) -e 's,@PROGRAM@,$(p),' "$(top_srcdir)/build/android/AndroidManifest.xml" > "$(d)/AndroidManifest.xml"
$(SED) -e 's,@PROGRAM@,$(subst -,_,$(p)),' "$(top_srcdir)/build/android/AndroidManifest.xml" > "$(d)/AndroidManifest.xml"
$(MKDIR_P) "$(d)/src/net/lolengine"
$(SED) -e 's,@PROGRAM@,$(p),' "$(top_srcdir)/build/android/LolActivity.java" > "$(d)/src/net/lolengine/LolActivity.java"
$(SED) -e 's,@PROGRAM@,$(subst -,_,$(p)),' "$(top_srcdir)/build/android/LolActivity.java" > "$(d)/src/net/lolengine/LolActivity.java"
$(MKDIR_P) "$(d)/res/values"
$(SED) -e 's,@PROGRAM@,$(p),' "$(top_srcdir)/build/android/strings.xml" > "$(d)/res/values/strings.xml"
$(SED) -e 's,@PROGRAM@,$(subst -,_,$(p)),' "$(top_srcdir)/build/android/strings.xml" > "$(d)/res/values/strings.xml"
$(MKDIR_P) "$(d)/res/drawable"
cp "$(top_srcdir)/build/android/icon.png" "$(d)/res/drawable/"
$(MKDIR_P) "$(d)/libs/armeabi"
$(LN_S) "$(abs_builddir)/$(p)$(EXEEXT)" "$(d)/libs/armeabi/lib$(p).so"
$(LN_S) "$${ANDROID_NDK_ROOT}/sources/cxx-stl/stlport/libs/armeabi/libstlport_shared.so" "$(d)/libs/armeabi"
android update project -t android-8 -p "$(d)"
android update project -t android-9 -n "$(p)" -p "$(d)"
ant debug -f "$(d)/build.xml"
touch $@
else


+ 2
- 2
build/lol-build View File

@@ -183,10 +183,10 @@ configure()
./configure --host=armv7-apple-darwin10 CPPFLAGS="$CPPFLAGS" LDFLAGS="$LDFLAGS" CC="$CC" CXX="$CXX"
;;
android-arm)
CPPFLAGS="$CPPFLAGS -Wno-psabi -I$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/stlport -fpic -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64"
CPPFLAGS="$CPPFLAGS -Wno-psabi -I$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/stlport -I$ANDROID_NDK_ROOT/sources/android/native_app_glue -fpic -fomit-frame-pointer -fno-strict-aliasing -finline-limit=64"
CFLAGS="$CFLAGS -march=armv5te -mtune=xscale -msoft-float -mthumb"
CXXFLAGS="$CXXFLAGS -march=armv5te -mtune=xscale -msoft-float -mthumb -fno-rtti -fno-exceptions"
LOL_LIBS="$LOL_LIBS -L$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/libs/armeabi -lstlport_shared -lm -fpic -XCClinker -shared"
LOL_LIBS="$LOL_LIBS -L$ANDROID_NDK_ROOT/sources/cxx-stl/stlport/libs/armeabi -lstlport_shared -lm -fpic -XCClinker -shared -u ANativeActivity_onCreate"
PKG_CONFIG_PATH="$PKG_CONFIG_PATH" ./configure --host=arm-linux-androideabi ac_cv_exeext=.so CPPFLAGS="$CPPFLAGS" CFLAGS="$CFLAGS" CXXFLAGS="$CXXFLAGS" LDFLAGS="$LDFLAGS" LOL_LIBS="$LOL_LIBS"
# FIXME: is this needed?
# ant debug


+ 1
- 1
configure.ac View File

@@ -312,7 +312,7 @@ dnl Use Android? FIXME: super hacks!
ac_cv_my_have_android="no"
AC_CHECK_LIB(log, __android_log_vprint,
[ac_cv_my_have_android="yes"
LOL_LIBS="${LOL_LIBS} -llog -module"])
LOL_LIBS="${LOL_LIBS} -llog -landroid -module -lEGL -lGLESv2"])
AM_CONDITIONAL(USE_ANDROID, test "${ac_cv_my_have_android}" != "no")




+ 244
- 96
src/platform/android/androidapp.cpp View File

@@ -1,7 +1,7 @@
//
// Lol Engine
//
// Copyright: (c) 2010-2011 Sam Hocevar <sam@hocevar.net>
// Copyright: (c) 2010-2013 Sam Hocevar <sam@hocevar.net>
// This program is free software; you can redistribute it and/or
// modify it under the terms of the Do What The Fuck You Want To
// Public License, Version 2, as published by Sam Hocevar. See
@@ -15,166 +15,314 @@
#if defined __ANDROID__

#include <jni.h>
#include <android/log.h>

#include <EGL/egl.h>
#include <GLES/gl.h>

extern "C" {
#include <android_native_app_glue.h>
#include <android_native_app_glue.c>
}

#include "core.h"
#include "loldebug.h"
#include "androidapp.h"

using namespace lol;

/* One of these wrappers will be overridden by the user's version */
void lol_android_main(void) __attribute__((weak));
void lol_android_main(int argc, char **argv) __attribute__((weak));
void lol_android_main(int argc, char **argv, char **envp) __attribute__((weak));

namespace lol
{
JavaVM *g_vm;
jobject g_activity;
Queue<int> g_main_queue;
Thread *g_main_thread;
float g_fps;
}; /* namespace lol */

AndroidApp::AndroidApp(char const *title, ivec2 res, float fps)
: m_data(0)
extern "C" jint
JNI_OnLoad(JavaVM* vm, void* reserved)
{
g_fps = fps;
Log::Info("Java layer loading library, vm=0x%08lx", (long)(intptr_t)vm);
g_vm = vm;
return JNI_VERSION_1_4;
}

void AndroidApp::ShowPointer(bool show)
extern "C" void
Java_net_lolengine_LolActivity_nativeInit(JNIEnv* env, jobject thiz)
{
Log::Info("Java layer initialising activity 0x%08lx", (long)thiz);
env->NewGlobalRef(thiz); /* FIXME: never released! */
g_activity = thiz;
}

/* This is a fake Tick() method. We just wait until we're called and
* signal nativeInit() that all the user's initialisation code was
* called. Then we sit here forever, the Java layer is in charge of
* calling TickDraw(). */
void AndroidApp::Tick()
/* One of these wrappers will be overridden by the user's version */
void lol_android_main(void) __attribute__((weak));
void lol_android_main(int argc, char **argv) __attribute__((weak));
void lol_android_main(int argc, char **argv, char **envp) __attribute__((weak));

/**
* Our saved state data.
*/
struct SavedState
{
ivec2 position;
};

/**
* Shared state for our app.
*/
class lol::AndroidAppData
{
public:
android_app* m_native_app;

EGLDisplay display;
EGLSurface surface;
EGLContext context;

SavedState m_state;
};

/**
* Initialize an EGL context for the current display.
*/
static int engine_init_display(struct AndroidAppData* engine)
{
static int init = 0;
if (!init)
/*
* 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
*/
const EGLint attribs[] =
{
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_BUFFER_SIZE, 16,
EGL_DEPTH_SIZE, 16,
EGL_RED_SIZE, 4,
EGL_GREEN_SIZE, 4,
EGL_BLUE_SIZE, 4,
EGL_ALPHA_SIZE, 4,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
EGLint w, h, dummy, format;
EGLint numConfigs;
EGLConfig config;
EGLSurface surface;
EGLContext context;

EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

eglInitialize(display, 0, 0);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);

ANativeWindow_setBuffersGeometry(engine->m_native_app->window,
0, 0, format);
surface = eglCreateWindowSurface(display, config,
engine->m_native_app->window, nullptr);

EGLint ctxattr[] =
{
init = 1;
g_main_queue.Push(1);
g_main_queue.Push(1);
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
context = eglCreateContext(display, config, EGL_NO_CONTEXT, ctxattr);

if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
{
Log::Error("unable to eglMakeCurrent");
return -1;
}

/* Do nothing while the real render thread does the job. The
* real stuff happens in nativeRender() */
Timer t;
t.Wait(0.5f);
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);

engine->display = display;
engine->context = context;
engine->surface = surface;

/* Launch our ticker */
Log::Info("Java layer initialising renderer at %g fps", 60.0f);
Ticker::Setup(60.0f);
Video::Setup(ivec2(w, h));

return 0;
}

void *AndroidApp::MainRun(void *data)
static void engine_draw_frame(AndroidAppData* engine)
{
int argc = 1;
char *argv[] = { "", nullptr };
char *env[] = { nullptr };
if (!engine->display)
return;

/* Call the user's main() function. One of these will work. */
lol_android_main();
lol_android_main(argc, argv);
lol_android_main(argc, argv, env);
Ticker::TickDraw();

return nullptr;
eglSwapBuffers(engine->display, engine->surface);
}

AndroidApp::~AndroidApp()
/**
* Tear down the EGL context currently associated with the display.
*/
static void engine_term_display(AndroidAppData* 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);
}
engine->display = EGL_NO_DISPLAY;
engine->context = EGL_NO_CONTEXT;
engine->surface = EGL_NO_SURFACE;
}

};

extern "C" jint
JNI_OnLoad(JavaVM* vm, void* reserved)
/**
* Process the next input event.
*/
static int32_t engine_handle_input(android_app* native_app, AInputEvent* event)
{
Log::Info("Java layer loading library, vm=0x%08lx", (long)(intptr_t)vm);
g_vm = vm;
return JNI_VERSION_1_4;
AndroidAppData* engine = (AndroidAppData*)native_app->userData;
switch (AInputEvent_getType(event))
{
case AINPUT_EVENT_TYPE_MOTION:
Input::SetMousePos(ivec2(AMotionEvent_getX(event, 0),
AMotionEvent_getY(event, 0)));
switch (AKeyEvent_getAction(event) & AMOTION_EVENT_ACTION_MASK)
{
case AMOTION_EVENT_ACTION_DOWN:
Input::SetMouseButton(0);
break;
case AMOTION_EVENT_ACTION_UP:
Input::UnsetMouseButton(0);
break;
}
return 1;
}
return 0;
}

extern "C" void
Java_net_lolengine_LolActivity_nativeInit(JNIEnv* env, jobject thiz)
/**
* Process the next main command.
*/
static void engine_handle_cmd(android_app* native_app, int32_t cmd)
{
Log::Info("Java layer initialising activity 0x%08lx", (long)thiz);
env->NewGlobalRef(thiz); /* FIXME: never released! */
g_activity = thiz;
AndroidAppData* engine = (AndroidAppData*)native_app->userData;
switch (cmd)
{
case APP_CMD_SAVE_STATE:
/* The system has asked us to save our current state. Do so. */
engine->m_native_app->savedState = malloc(sizeof(SavedState));
*((SavedState*)engine->m_native_app->savedState) = engine->m_state;
engine->m_native_app->savedStateSize = sizeof(SavedState);
break;
case APP_CMD_INIT_WINDOW:
/* The window is being shown, get it ready. */
if (engine->m_native_app->window != nullptr)
{
engine_init_display(engine);
engine_draw_frame(engine);
}
break;
case APP_CMD_TERM_WINDOW:
/* The window is being hidden or closed, clean it up. */
engine_term_display(engine);
break;
case APP_CMD_GAINED_FOCUS:
break;
case APP_CMD_LOST_FOCUS:
/* FIXME: stop animating */
engine_draw_frame(engine);
break;
}
}

extern "C" void
Java_net_lolengine_LolRenderer_nativeInit(JNIEnv* env)
/* FIXME: find a better way to pass this to the AndroidApp ctor. */
AndroidAppData *g_data;

void android_main(android_app* native_app)
{
/* Initialise app thread and wait for it to be ready, ie. set
* the FPS value at least. */
g_main_thread = new Thread(lol::AndroidApp::MainRun, nullptr);
g_main_queue.Pop();
g_data = new AndroidAppData();

/* Launch our ticker */
Log::Info("Java layer initialising renderer at %g fps", g_fps);
Ticker::Setup(g_fps);
Video::Setup(ivec2(320, 200));
/* Make sure glue isn't stripped */
app_dummy();

/* Wake up app thread */
g_main_queue.Pop();
}
native_app->userData = g_data;
native_app->onAppCmd = engine_handle_cmd;
native_app->onInputEvent = engine_handle_input;
g_data->m_native_app = native_app;

extern "C" void
Java_net_lolengine_LolRenderer_nativeResize(JNIEnv* env, jobject thiz,
jint w, jint h)
{
Log::Info("Java layer resizing to %i x %i", w, h);
Video::Setup(ivec2(w, h));
}
if (native_app->savedState != nullptr)
{
/* We are starting with a previous saved state; restore from it */
g_data->m_state = *(SavedState*)native_app->savedState;
}

extern "C" void
Java_net_lolengine_LolRenderer_nativeDone(JNIEnv* env)
{
/* FIXME: clean up */
delete g_main_thread;
}
int argc = 1;
char *argv[] = { "", nullptr };
char *env[] = { nullptr };

extern "C" void
Java_net_lolengine_LolView_nativePause(JNIEnv* env)
{
/* TODO: unimplemented */
/* Call the user's main() function. One of these will work. */
lol_android_main();
lol_android_main(argc, argv);
lol_android_main(argc, argv, env);
}

extern "C" void
Java_net_lolengine_LolView_nativeDown(JNIEnv* env)
lol::AndroidApp::AndroidApp(char const *title, ivec2 res, float fps)
: m_data(g_data)
{
Input::SetMouseButton(0);
;
}

extern "C" void
Java_net_lolengine_LolView_nativeUp(JNIEnv* env)
void lol::AndroidApp::ShowPointer(bool show)
{
Input::UnsetMouseButton(0);
}

extern "C" void
Java_net_lolengine_LolView_nativeMove(JNIEnv* env, jobject thiz,
jint x, jint y)
lol::AndroidApp::~AndroidApp()
{
Input::SetMousePos(ivec2(x, y));
engine_term_display(m_data);
delete m_data;
}

/* Call to render the next GL frame */
extern "C" void
Java_net_lolengine_LolRenderer_nativeRender(JNIEnv* env)
void lol::AndroidApp::Tick()
{
Ticker::TickDraw();
/* Read all pending events. */
int ident;
int events;
struct android_poll_source* source;

/* Loop until all events are read, then continue to draw the next
* frame of animation. */
while ((ident = ALooper_pollAll(0, nullptr, &events,
(void**)&source)) >= 0)
{
/* Process this event */
if (source)
source->process(m_data->m_native_app, source);

/* Check if we are exiting */
if (m_data->m_native_app->destroyRequested != 0)
Ticker::Shutdown();
}

engine_draw_frame(m_data);
}

/*
* Fake main() wrappers that let us call the user’s main() from within
* a separate thread.
*/
void lol_android_main(void) {}
void lol_android_main(void)
{
}

void lol_android_main(int argc, char **argv)
{
UNUSED(argc, argv);
}

void lol_android_main(int argc, char **argv, char **envp)
{
UNUSED(argc, argv, envp);


+ 0
- 2
src/platform/android/androidapp.h View File

@@ -32,8 +32,6 @@ public:
void ShowPointer(bool show);
void Tick();

static void *MainRun(void *data);

private:
AndroidAppData *m_data;
};


Loading…
Cancel
Save