Просмотр исходного кода

Moving all the android platform related stuff from gameplay-main to to the PlatformAndroid.

Ramprasad Madhavan 14 лет назад
Родитель
Сommit
3a4fe3be01
2 измененных файлов с 340 добавлено и 371 удалено
  1. 331 184
      gameplay/src/PlatformAndroid.cpp
  2. 9 187
      gameplay/src/gameplay-main-android.cpp

+ 331 - 184
gameplay/src/PlatformAndroid.cpp

@@ -16,22 +16,24 @@
 
 using namespace std;
 
-int __width;
-int __height;
+struct android_app* __state;
+AAssetManager* __assetManager;
+std::string __assetsPath;
+bool __initialized = false;
+bool __destroyed = false;
+
 static EGLDisplay __eglDisplay = EGL_NO_DISPLAY;
 static EGLContext __eglContext = EGL_NO_CONTEXT;
 static EGLSurface __eglSurface = EGL_NO_SURFACE;
 static EGLConfig __eglConfig = 0;
-
+int __width;
+int __height;
 
 struct timespec __timespec;
 static long __timeStart;
 static long __timeAbsolute;
 static bool __vsync = WINDOW_VSYNC;
 
-struct android_app* __state;
-extern std::string __assetsPath;
-
 ASensorManager* __sensorManager;
 ASensorEventQueue* __sensorEventQueue;
 ASensorEvent __sensorEvent;
@@ -39,7 +41,7 @@ const ASensor* __accelerometerSensor;
 
 static int __orientationAngle;
 static bool __multiTouch = false;
-extern bool __displayKeyboard;
+bool __displayKeyboard = false;
 
 static const char* __glExtensions;
 PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray = NULL;
@@ -50,7 +52,149 @@ PFNGLISVERTEXARRAYOESPROC glIsVertexArray = NULL;
 namespace gameplay
 {
 
-extern void displayKeyboard(android_app* state, bool pShow)
+long timespec2millis(struct timespec *a)
+{
+    return a->tv_sec*1000 + a->tv_nsec/1000000;
+}
+
+extern void printError(const char* format, ...)
+{
+    va_list argptr;
+    va_start(argptr, format);
+    LOGI(format, argptr);
+    va_end(argptr);
+}
+
+EGLenum checkErrorEGL(const char* msg)
+{
+    static const char* errmsg[] =
+    {
+        "EGL function succeeded",
+        "EGL is not initialized, or could not be initialized, for the specified display",
+        "EGL cannot access a requested resource",
+        "EGL failed to allocate resources for the requested operation",
+        "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
+        "EGLConfig argument does not name a valid EGLConfig",
+        "EGLContext argument does not name a valid EGLContext",
+        "EGL current surface of the calling thread is no longer valid",
+        "EGLDisplay argument does not name a valid EGLDisplay",
+        "EGL arguments are inconsistent",
+        "EGLNativePixmapType argument does not refer to a valid native pixmap",
+        "EGLNativeWindowType argument does not refer to a valid native window",
+        "EGL one or more argument values are invalid",
+        "EGLSurface argument does not name a valid surface configured for rendering",
+        "EGL power management event has occurred",
+    };
+    EGLenum error = eglGetError();
+    LOGI("%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
+    return error;
+}
+
+// Initialized EGL resources.
+bool initEGL()
+{
+    // Hard-coded to 32-bit/OpenGL ES 2.0.
+    const EGLint eglConfigAttrs[] =
+    {
+        EGL_RED_SIZE,           8,
+        EGL_GREEN_SIZE,         8,
+        EGL_BLUE_SIZE,          8,
+        EGL_ALPHA_SIZE,         8,
+        EGL_DEPTH_SIZE,         24,
+        EGL_STENCIL_SIZE,       8,
+        EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
+        EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
+        EGL_NONE
+    };
+    
+    EGLint eglConfigCount;
+    const EGLint eglContextAttrs[] =
+    {
+        EGL_CONTEXT_CLIENT_VERSION,    2,
+        EGL_NONE
+    };
+
+    const EGLint eglSurfaceAttrs[] =
+    {
+        EGL_RENDER_BUFFER,    EGL_BACK_BUFFER,
+        EGL_NONE
+    };
+
+    // Get the EGL display and initialize.
+    __eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    if (__eglDisplay == EGL_NO_DISPLAY)
+    {
+        checkErrorEGL("eglGetDisplay");
+        goto error;
+    }
+    
+    if (eglInitialize(__eglDisplay, NULL, NULL) != EGL_TRUE)
+    {
+        checkErrorEGL("eglInitialize");
+        goto error;
+    }
+    
+    if (eglChooseConfig(__eglDisplay, eglConfigAttrs, &__eglConfig, 1, &eglConfigCount) != EGL_TRUE || eglConfigCount == 0)
+    {
+        checkErrorEGL("eglChooseConfig");
+        goto error;
+    }
+    
+    __eglContext = eglCreateContext(__eglDisplay, __eglConfig, EGL_NO_CONTEXT, eglContextAttrs);
+    if (__eglContext == EGL_NO_CONTEXT)
+    {
+        checkErrorEGL("eglCreateContext");
+        goto error;
+    }
+    
+    // EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
+    // 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.
+    EGLint format;
+    eglGetConfigAttrib(__eglDisplay, __eglConfig, EGL_NATIVE_VISUAL_ID, &format);
+    ANativeWindow_setBuffersGeometry(__state->window, 0, 0, format);
+    
+    __eglSurface = eglCreateWindowSurface(__eglDisplay, __eglConfig, __state->window, eglSurfaceAttrs);
+    if (__eglSurface == EGL_NO_SURFACE)
+    {
+        checkErrorEGL("eglCreateWindowSurface");
+        goto error;
+    }
+    
+    if (eglMakeCurrent(__eglDisplay, __eglSurface, __eglSurface, __eglContext) != EGL_TRUE)
+    {
+        checkErrorEGL("eglMakeCurrent");
+        goto error;
+    }
+    
+    eglQuerySurface(__eglDisplay, __eglSurface, EGL_WIDTH, &__width);
+    eglQuerySurface(__eglDisplay, __eglSurface, EGL_HEIGHT, &__height);
+    
+    // Set vsync.
+    eglSwapInterval(__eglDisplay, WINDOW_VSYNC ? 1 : 0);
+    
+    // Initialize OpenGL ES extensions.
+    __glExtensions = (const char*)glGetString(GL_EXTENSIONS);
+    
+    if (strstr(__glExtensions, "GL_OES_vertex_array_object") || strstr(__glExtensions, "GL_ARB_vertex_array_object"))
+    {
+        // Disable VAO extension for now.
+        glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
+        glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArrays");
+        glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
+        glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
+    }
+    
+    return true;
+    
+error:
+
+    return false;
+}
+
+// Display the android virtual keyboard.
+void displayKeyboard(android_app* state, bool pShow)
 { 
     
     // The following functions is supposed to show / hide functins from a native activity.. but currently
@@ -116,7 +260,7 @@ extern void displayKeyboard(android_app* state, bool pShow)
 }
 
 // Gets the Keyboard::Key enumeration constant that corresponds to the given Android key code.
-extern Keyboard::Key getKey(int keycode, int metastate)
+Keyboard::Key getKey(int keycode, int metastate)
 {
     bool shiftOn = (metastate == AMETA_SHIFT_ON);
     
@@ -259,38 +403,90 @@ extern Keyboard::Key getKey(int keycode, int metastate)
     }
 }
 
-
-extern void printError(const char* format, ...)
+// Process the next input event.
+static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
 {
-    va_list argptr;
-    va_start(argptr, format);
-    LOGI(format, argptr);
-    va_end(argptr);
+    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
+    {
+        int32_t data = AMotionEvent_getAction(event);
+        int contactIndex = data >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
+        Touch::TouchEvent touchEvent;
+        switch (data & AMOTION_EVENT_ACTION_MASK)
+        {
+            case AMOTION_EVENT_ACTION_DOWN:
+                touchEvent = Touch::TOUCH_PRESS;
+                break;
+            case AMOTION_EVENT_ACTION_UP:
+                touchEvent = Touch::TOUCH_RELEASE;
+                break;
+            case AMOTION_EVENT_ACTION_MOVE:
+                touchEvent = Touch::TOUCH_MOVE;
+                break;
+        }
+    
+        Game::getInstance()->touchEvent(touchEvent, AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0), contactIndex);
+        return 1;
+    } 
+    else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY)
+    {
+        int32_t action = AKeyEvent_getAction(event);
+        int32_t keycode = AKeyEvent_getKeyCode(event);
+        int32_t metastate = AKeyEvent_getMetaState(event); 
+        
+        switch(action)
+        {
+            case AKEY_EVENT_ACTION_DOWN:
+                Game::getInstance()->keyEvent(Keyboard::KEY_PRESS, getKey(keycode, metastate));
+                break;
+                    
+            case AKEY_EVENT_ACTION_UP:
+                Game::getInstance()->keyEvent(Keyboard::KEY_RELEASE, getKey(keycode, metastate));
+                break;
+        }
+    }
+    return 0;
 }
 
-EGLenum checkErrorEGL(const char* msg)
+// Process the next main command.
+static void engine_handle_cmd(struct android_app* app, int32_t cmd) 
 {
-    static const char* errmsg[] =
+    switch (cmd) 
     {
-        "EGL function succeeded",
-        "EGL is not initialized, or could not be initialized, for the specified display",
-        "EGL cannot access a requested resource",
-        "EGL failed to allocate resources for the requested operation",
-        "EGL fail to access an unrecognized attribute or attribute value was passed in an attribute list",
-        "EGLConfig argument does not name a valid EGLConfig",
-        "EGLContext argument does not name a valid EGLContext",
-        "EGL current surface of the calling thread is no longer valid",
-        "EGLDisplay argument does not name a valid EGLDisplay",
-        "EGL arguments are inconsistent",
-        "EGLNativePixmapType argument does not refer to a valid native pixmap",
-        "EGLNativeWindowType argument does not refer to a valid native window",
-        "EGL one or more argument values are invalid",
-        "EGLSurface argument does not name a valid surface configured for rendering",
-        "EGL power management event has occurred",
-    };
-    EGLenum error = eglGetError();
-    LOGI("%s: %s\n", msg, errmsg[error - EGL_SUCCESS]);
-    return error;
+        case APP_CMD_SAVE_STATE:
+            // TODO
+            break;
+        case APP_CMD_INIT_WINDOW:
+            // The window is being shown, get it ready.
+            if (app->window != NULL)
+            {
+                __initialized = true;
+            }
+            break;
+        case APP_CMD_TERM_WINDOW:
+            {
+                __destroyed = true;
+                break;
+            }
+        case APP_CMD_GAINED_FOCUS:
+            // When our app gains focus, we start monitoring the accelerometer.
+            if (__accelerometerSensor != NULL) 
+            {
+                ASensorEventQueue_enableSensor(__sensorEventQueue, __accelerometerSensor);
+                // We'd like to get 60 events per second (in us).
+                ASensorEventQueue_setEventRate(__sensorEventQueue, __accelerometerSensor, (1000L/60)*1000);
+            }
+            Game::getInstance()->resume();
+            break;
+        case APP_CMD_LOST_FOCUS:
+            // When our app loses focus, we stop monitoring the accelerometer.
+            // This is to avoid consuming battery while not being used.
+            if (__accelerometerSensor != NULL) 
+            {
+                ASensorEventQueue_disableSensor(__sensorEventQueue, __accelerometerSensor);
+            }
+            Game::getInstance()->pause();
+            break;
+    }
 }
 
 Platform::Platform(Game* game)
@@ -331,172 +527,123 @@ Platform::~Platform()
 
 Platform* Platform::create(Game* game)
 {
-    FileSystem::setResourcePath(__assetsPath.c_str());
-   
     Platform* platform = new Platform(game);
-
-    // Hard-coded to 32-bit/OpenGL ES 2.0.
-    const EGLint eglConfigAttrs[] =
-    {
-        EGL_RED_SIZE,           8,
-        EGL_GREEN_SIZE,         8,
-        EGL_BLUE_SIZE,          8,
-        EGL_ALPHA_SIZE,         8,
-        EGL_DEPTH_SIZE,         24,
-        EGL_STENCIL_SIZE,       8,
-        EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
-        EGL_RENDERABLE_TYPE,    EGL_OPENGL_ES2_BIT,
-        EGL_NONE
-    };
-    
-    EGLint eglConfigCount;
-    const EGLint eglContextAttrs[] =
-    {
-        EGL_CONTEXT_CLIENT_VERSION,    2,
-        EGL_NONE
-    };
-
-    const EGLint eglSurfaceAttrs[] =
-    {
-        EGL_RENDER_BUFFER,    EGL_BACK_BUFFER,
-        EGL_NONE
-    };
-
-    // Get the EGL display and initialize.
-    __eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
-    if (__eglDisplay == EGL_NO_DISPLAY)
-    {
-        checkErrorEGL("eglGetDisplay");
-        goto error;
-    }
-    
-    if (eglInitialize(__eglDisplay, NULL, NULL) != EGL_TRUE)
-    {
-        checkErrorEGL("eglInitialize");
-        goto error;
-    }
-
-    if (eglChooseConfig(__eglDisplay, eglConfigAttrs, &__eglConfig, 1, &eglConfigCount) != EGL_TRUE || eglConfigCount == 0)
-    {
-        checkErrorEGL("eglChooseConfig");
-        goto error;
-    }
-    
-    __eglContext = eglCreateContext(__eglDisplay, __eglConfig, EGL_NO_CONTEXT, eglContextAttrs);
-    if (__eglContext == EGL_NO_CONTEXT)
-    {
-        checkErrorEGL("eglCreateContext");
-        goto error;
-    }
-    
-    // EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
-    // 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.
-    EGLint format;
-    eglGetConfigAttrib(__eglDisplay, __eglConfig, EGL_NATIVE_VISUAL_ID, &format);
-    ANativeWindow_setBuffersGeometry(__state->window, 0, 0, format);
-
-    __eglSurface = eglCreateWindowSurface(__eglDisplay, __eglConfig, __state->window, eglSurfaceAttrs);
-    if (__eglSurface == EGL_NO_SURFACE)
-    {
-        checkErrorEGL("eglCreateWindowSurface");
-        goto error;
-    }
-    
-    if (eglMakeCurrent(__eglDisplay, __eglSurface, __eglSurface, __eglContext) != EGL_TRUE)
-    {
-        checkErrorEGL("eglMakeCurrent");
-        goto error;
-    }
-
-    eglQuerySurface(__eglDisplay, __eglSurface, EGL_WIDTH, &__width);
-    eglQuerySurface(__eglDisplay, __eglSurface, EGL_HEIGHT, &__height);
-    
-    // Set vsync.
-    eglSwapInterval(__eglDisplay, WINDOW_VSYNC ? 1 : 0);
-
-    // Initialize OpenGL ES extensions.
-    __glExtensions = (const char*)glGetString(GL_EXTENSIONS);
-
-    if (strstr(__glExtensions, "GL_OES_vertex_array_object") || strstr(__glExtensions, "GL_ARB_vertex_array_object"))
-    {
-        // Disable VAO extension for now.
-        glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
-        glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArrays");
-        glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
-        glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
-    }
-
     
     // TODO: Determine initial orientation angle.
     //orientation_direction_t direction;
     //orientation_get(&direction, &__orientationAngle);
 
     return platform;
-
-error:
-
-    // TODO: cleanup.
-
-    return NULL;
-}
-
-/**
- * Convert the timespec into milliseconds.
- */
-long timespec2millis(struct timespec *a)
-{
-    return a->tv_sec*1000 + a->tv_nsec/1000000;
 }
 
 int Platform::enterMessagePump()
 {
-    static int state = 0;
+    // Get the android application's activity.
+    ANativeActivity* activity = __state->activity;
+    JNIEnv* env = activity->env;
+
+    // Get the package name for this app from Java.
+    jclass clazz = env->GetObjectClass(activity->clazz);
+    jmethodID methodID = env->GetMethodID(clazz, "getPackageName", "()Ljava/lang/String;");
+    jobject result = env->CallObjectMethod(activity->clazz, methodID);
+    
+    const char* packageName;
+    jboolean isCopy;
+    packageName = env->GetStringUTFChars((jstring)result, &isCopy);
     
-    switch (state)
+    // Set the default path to store the resources.
+    __assetsPath = "/mnt/sdcard/android/data/";
+    __assetsPath += packageName;
+    __assetsPath += "/";
+    FileSystem::setResourcePath(__assetsPath.c_str());    
+        
+    // Get the asset manager to get the resources from the .apk file.
+    __assetManager = __state->activity->assetManager; 
+    
+    // Set the event call back functions.
+    __state->onAppCmd = engine_handle_cmd;
+    __state->onInputEvent = engine_handle_input;
+    
+    // Prepare to monitor accelerometer.
+    __sensorManager = ASensorManager_getInstance();
+    __accelerometerSensor = ASensorManager_getDefaultSensor(__sensorManager, ASENSOR_TYPE_ACCELEROMETER);
+    __sensorEventQueue = ASensorManager_createEventQueue(__sensorManager, __state->looper, LOOPER_ID_USER, NULL, NULL);
+    
+    // Get the initial time.
+    clock_gettime(CLOCK_REALTIME, &__timespec);
+    __timeStart = timespec2millis(&__timespec);
+    __timeAbsolute = 0L;
+    
+    bool initializeGame = true;
+    
+    while (true)
     {
-        case 0:
-            // Get the initial time.
-            clock_gettime(CLOCK_REALTIME, &__timespec);
-            __timeStart = timespec2millis(&__timespec);
-            __timeAbsolute = 0L;
-            _game->run(__width, __height);
+        // Read all pending events.
+        int ident;
+        int events;
+        struct android_poll_source* source;
+        
+        bool _shouldPoll = !(__initialized && Game::getInstance()->getState() == Game::UNINITIALIZED) && (Game::getInstance()->getState() != Game::PAUSED);
+        
+        while ((ident=ALooper_pollAll( _shouldPoll ? 0 : -1, NULL, &events, (void**)&source)) >= 0) 
+        {
+            // Process this event.
+            if (source != NULL) 
+                source->process(__state, source);
             
-            state = 1;
-            break;
-        case 1:
-            // Idle time (no events left to process) is spent rendering.
-            // We skip rendering when the app is paused.
-            if (_game->getState() != Game::PAUSED)
+            // If a sensor has data, process it now.
+            if (ident == LOOPER_ID_USER && __accelerometerSensor != NULL)
+                ASensorEventQueue_getEvents(__sensorEventQueue, &__sensorEvent, 1);
+            
+            if (__state->destroyRequested != 0)
+                break;
+        }
+        
+        if (__initialized && initializeGame)
+        {
+            gameplay::initEGL();
+            WARN_VARG("Platform::enterMessagePump() - width: %d  height: %d assetsPath: %s", __width, __height, __assetsPath.c_str());
+            _game->run(__width, __height);
+            initializeGame = false;
+        }
+        
+        // Idle time (no events left to process) is spent rendering.
+        // We skip rendering when the app is paused.
+        if (__initialized && _game->getState() != Game::PAUSED)
+        {
+            _game->frame();
+
+            // Post the new frame to the display.
+            // Note that there are a couple cases where eglSwapBuffers could fail
+            // with an error code that requires a certain level of re-initialization:
+            //
+            // 1) EGL_BAD_NATIVE_WINDOW - Called when the surface we're currently using
+            //    is invalidated. This would require us to destroy our EGL surface,
+            //    close our OpenKODE window, and start again.
+            //
+            // 2) EGL_CONTEXT_LOST - Power management event that led to our EGL context
+            //    being lost. Requires us to re-create and re-initalize our EGL context
+            //    and all OpenGL ES state.
+            //
+            // For now, if we get these, we'll simply exit.
+            int rc = eglSwapBuffers(__eglDisplay, __eglSurface);
+            if (rc != EGL_TRUE)
             {
-                _game->frame();
-
-                // Post the new frame to the display.
-                // Note that there are a couple cases where eglSwapBuffers could fail
-                // with an error code that requires a certain level of re-initialization:
-                //
-                // 1) EGL_BAD_NATIVE_WINDOW - Called when the surface we're currently using
-                //    is invalidated. This would require us to destroy our EGL surface,
-                //    close our OpenKODE window, and start again.
-                //
-                // 2) EGL_CONTEXT_LOST - Power management event that led to our EGL context
-                //    being lost. Requires us to re-create and re-initalize our EGL context
-                //    and all OpenGL ES state.
-                //
-                // For now, if we get these, we'll simply exit.
-                int rc = eglSwapBuffers(__eglDisplay, __eglSurface);
-                if (rc != EGL_TRUE)
-                {
-                    perror("eglSwapBuffers");
-                    _game->exit();
-                    break;
-                }
+                perror("eglSwapBuffers");
+                _game->exit();
+                break;
             }
+        }
+        
+        // Check if we are exiting.
+        if ((__state->destroyRequested != 0) || (__initialized && Game::getInstance()->getState() == Game::UNINITIALIZED))
+        {
             break;
+        }
+            
+        // Display the keyboard.
+        gameplay::displayKeyboard(__state, __displayKeyboard);
     }
-    
-    return 0;
 }
 
 long Platform::getAbsoluteTime()

+ 9 - 187
gameplay/src/gameplay-main-android.cpp

@@ -1,206 +1,28 @@
 #ifdef __ANDROID__
 
-#include "gameplay.h"
-#include <android/sensor.h>
 #include <android_native_app_glue.h>
-#include <jni.h>
-
-
-#include <android/log.h>
-#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__))
+#include "gameplay.h"
 
 using namespace gameplay;
 
 extern struct android_app* __state;
-AAssetManager* __assetManager;
-std::string __assetsPath;
-extern ASensorManager* __sensorManager;
-extern const ASensor* __accelerometerSensor;
-extern ASensorEventQueue* __sensorEventQueue;
-extern ASensorEvent __sensorEvent;
-bool __displayKeyboard = false;
-bool __initialized = false;
-
-
-namespace gameplay
-{
-extern Keyboard::Key getKey(int keycode, int metastate);
-extern void displayKeyboard(android_app* mApplication, bool pShow);
-}
-
-/**
- * Process the next input event.
- */
-static int32_t engine_handle_input(struct android_app* app, AInputEvent* event)
-{
-    Platform* platform = static_cast<Platform*>(app->userData);
-    
-    if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION)
-    {
-        
-        int32_t data = AMotionEvent_getAction(event);
-        int contactIndex = data >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
-        Touch::TouchEvent touchEvent;
-        switch (data & AMOTION_EVENT_ACTION_MASK)
-        {
-            case AMOTION_EVENT_ACTION_DOWN:
-                touchEvent = Touch::TOUCH_PRESS;
-                break;
-            case AMOTION_EVENT_ACTION_UP:
-                touchEvent = Touch::TOUCH_RELEASE;
-                break;
-            case AMOTION_EVENT_ACTION_MOVE:
-                touchEvent = Touch::TOUCH_MOVE;
-                break;
-        }
-    
-        Game::getInstance()->touchEvent(touchEvent, AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0), contactIndex);
-        return 1;
-    } 
-    else if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_KEY)
-    {
-        int32_t action = AKeyEvent_getAction(event);
-        int32_t keycode = AKeyEvent_getKeyCode(event);
-        int32_t metastate = AKeyEvent_getMetaState(event); 
-        
-        switch(action)
-        {
-            case AKEY_EVENT_ACTION_DOWN:
-                Game::getInstance()->keyEvent(Keyboard::KEY_PRESS, getKey(keycode, metastate));
-                break;
-                    
-            case AKEY_EVENT_ACTION_UP:
-                Game::getInstance()->keyEvent(Keyboard::KEY_RELEASE, getKey(keycode, metastate));
-                break;
-        }
-    }
-    return 0;
-}
-
-/**
- * Process the next main command.
- */
-static void engine_handle_cmd(struct android_app* app, int32_t cmd) 
-{
-    switch (cmd) 
-    {
-        case APP_CMD_SAVE_STATE:
-            // TODO
-            break;
-        case APP_CMD_INIT_WINDOW:
-            // The window is being shown, get it ready.
-            if (app->window != NULL)
-            {
-                Game* game = Game::getInstance();
-                assert(game != NULL);
-                Platform* platform = Platform::create(game);
-                app->userData = platform;
-                __initialized = true;
-            }
-            break;
-        case APP_CMD_TERM_WINDOW:
-        {
-            Game::getInstance()->exit();
-            Platform* platform = static_cast<Platform*>(app->userData);
-            if (!platform)
-            {
-                return;
-            }
-            delete platform;
-            app->userData = NULL;
-            break;
-        }
-        case APP_CMD_GAINED_FOCUS:
-            // When our app gains focus, we start monitoring the accelerometer.
-            if (__accelerometerSensor != NULL) {
-                ASensorEventQueue_enableSensor(__sensorEventQueue, __accelerometerSensor);
-                // We'd like to get 60 events per second (in us).
-                ASensorEventQueue_setEventRate(__sensorEventQueue, __accelerometerSensor, (1000L/60)*1000);
-            }
-            Game::getInstance()->resume();
-            break;
-        case APP_CMD_LOST_FOCUS:
-            // When our app loses focus, we stop monitoring the accelerometer.
-            // This is to avoid consuming battery while not being used.
-            if (__accelerometerSensor != NULL) {
-                ASensorEventQueue_disableSensor(__sensorEventQueue, __accelerometerSensor);
-            }
-            Game::getInstance()->pause();
-            ((Platform*)static_cast<Platform*>(app->userData))->swapBuffers();
-            break;
-    }
-}
 
 /**
  * Main entry point.
  */
 void android_main(struct android_app* state)
 {
-	// Make sure glue isn't stripped.
+    // Make sure glue isn't stripped.
     app_dummy();
     
-    ANativeActivity* activity = state->activity;
-    JNIEnv* env = activity->env;
-
-    jclass clazz = env->GetObjectClass(activity->clazz);
-    jmethodID methodID = env->GetMethodID(clazz, "getPackageName", "()Ljava/lang/String;");
-    jobject result = env->CallObjectMethod(activity->clazz, methodID);
-    
-    const char* packageName;
-    jboolean isCopy;
-    packageName = env->GetStringUTFChars((jstring)result, &isCopy);
-    
-    __assetsPath = "/mnt/sdcard/android/data/";
-    __assetsPath += packageName;
-    __assetsPath += "/";
-    
-    __assetManager = state->activity->assetManager; 
-    
-    state->onAppCmd = engine_handle_cmd;
-    state->onInputEvent = engine_handle_input;
     __state = state;
-    
-    // Prepare to monitor accelerometer.
-    __sensorManager = ASensorManager_getInstance();
-    __accelerometerSensor = ASensorManager_getDefaultSensor(__sensorManager, ASENSOR_TYPE_ACCELEROMETER);
-    __sensorEventQueue = ASensorManager_createEventQueue(__sensorManager, __state->looper, LOOPER_ID_USER, NULL, NULL);
-    
-    while (true)
-    {
-    
-        // Read all pending events.
-        int ident;
-        int events;
-        struct android_poll_source* source;
-        
-        bool _shouldPoll = !(__initialized && Game::getInstance()->getState() == Game::UNINITIALIZED) && (Game::getInstance()->getState() != Game::PAUSED); 
-        
-        while ((ident=ALooper_pollAll( _shouldPoll ? 0 : -1, NULL, &events, (void**)&source)) >= 0) 
-        {
-            // Process this event.
-            if (source != NULL) 
-                source->process(__state, source);
-            
-            // If a sensor has data, process it now.
-            if (ident == LOOPER_ID_USER && __accelerometerSensor != NULL)
-                ASensorEventQueue_getEvents(__sensorEventQueue, &__sensorEvent, 1);
-            
-            if (__state->destroyRequested != 0)
-                break;
-        }
-        
-        Platform* platform = static_cast<Platform*>(state->userData);
-        if (platform)
-            platform->enterMessagePump();
-            
-        
-        // Check if we are exiting.
-        if ((__state->destroyRequested != 0) || (__initialized && Game::getInstance()->getState() == Game::UNINITIALIZED))
-            break;
-        
-        // Display the keyboard.
-        displayKeyboard(state, __displayKeyboard);
-    }
+    Game* game = Game::getInstance();
+    assert(game != NULL);
+    Platform* platform = Platform::create(game);
+    assert(platform != NULL);
+    platform->enterMessagePump();
+    Game::getInstance()->exit();
+    delete platform;
     
     // We need to exit the process to cleanup global resources.
     exit(0);