Build the SDL library as a shared object on Android, so it will work correctly with SDL_image and SDL_ttf.
authorSam Lantinga <slouken@libsdl.org>
Thu, 06 Jan 2011 16:11:21 -0800
changeset 4964 6c645018741e
parent 4963 604077962776
child 4965 91d0085b7560
Build the SDL library as a shared object on Android, so it will work correctly with SDL_image and SDL_ttf.
Android.mk
Makefile.android
README.android
android/config.cfg.example
android/project/AndroidManifest.xml
android/project/build.properties
android/project/build.xml
android/project/default.properties
android/project/jni/Android.mk
android/project/jni/android-support.cpp
android/project/jni/lesson05.c
android/project/local.properties
android/project/res/drawable-hdpi/icon.png
android/project/res/drawable-ldpi/icon.png
android/project/res/drawable-mdpi/icon.png
android/project/res/layout/main.xml
android/project/res/values/strings.xml
android/project/src/org/libsdl/app/SDLActivity.java
include/SDL_config_android.h
src/SDL_android.cpp
src/main/android/SDL_android_main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Android.mk	Thu Jan 06 16:11:21 2011 -0800
@@ -0,0 +1,41 @@
+LOCAL_PATH := $(call my-dir)
+
+###########################
+#
+# SDL shared library
+#
+###########################
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := SDL
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+
+LOCAL_SRC_FILES := src/SDL_android.cpp \
+	$(subst $(LOCAL_PATH)/,, \
+	$(wildcard $(LOCAL_PATH)/src/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/audio/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/cpuinfo/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/events/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/file/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/joystick/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/haptic/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/stdlib/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/thread/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/timer/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/video/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/power/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/audio/android/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/audio/dummy/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/video/android/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/joystick/android/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/haptic/dummy/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/atomic/dummy/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/thread/pthread/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/timer/unix/*.c) \
+	$(wildcard $(LOCAL_PATH)/src/loadso/dlopen/*.c))
+
+LOCAL_LDLIBS := -ldl -lGLESv1_CM -llog
+
+include $(BUILD_SHARED_LIBRARY)
--- a/Makefile.android	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-# Makefile to build the SDL library
-
-include ./android/config.cfg #get ANDROID_NDK, ANDROID_NDK_HOST
-
-# For NDK R4
-TOOLS_PATH=$(ANDROID_NDK)/build/prebuilt/$(ANDROID_NDK_HOST)/arm-eabi-4.2.1/bin
-ANDROID_INCLUDES = -I$(ANDROID_NDK)/build/platforms/android-4/arch-arm/usr/include 
-
-# For NDK R5
-#TOOLS_PATH=$(ANDROID_NDK)/toolchains/arm-eabi-4.4.0/prebuilt/$(ANDROID_NDK_HOST)/bin
-#ANDROID_INCLUDES = -I$(ANDROID_NDK)/platforms/android-4/arch-arm/usr/include 
-
-INCLUDE = -I./include
-CFLAGS  = -g -O2 -fno-short-enums $(INCLUDE) $(ANDROID_INCLUDES) -DANDROID -DANDROID_NDK -static
-
-AR	= $(TOOLS_PATH)/arm-eabi-ar
-RANLIB	= $(TOOLS_PATH)/arm-eabi-ranlib
-CC = $(TOOLS_PATH)/arm-eabi-gcc
-
-
-CONFIG_H = include/SDL_config.h
-TARGET  = libSDL.a
-SOURCES = \
-	src/*.c \
-	src/audio/*.c \
-	src/cpuinfo/*.c \
-	src/events/*.c \
-	src/file/*.c \
-	src/joystick/*.c \
-	src/haptic/*.c \
-	src/stdlib/*.c \
-	src/thread/*.c \
-	src/timer/*.c \
-	src/video/*.c \
-	src/power/*.c \
-	src/audio/android/*.c \
-	src/audio/dummy/*.c \
-	src/video/android/*.c \
-	src/joystick/android/*.c \
-	src/haptic/dummy/*.c \
-	src/atomic/dummy/*.c \
-	src/thread/pthread/*.c \
-	src/timer/unix/*.c \
-	src/loadso/dummy/*.c \
-
-OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g')
-
-all: $(TARGET)
-
-$(TARGET): $(CONFIG_H) $(OBJECTS)
-	$(AR) crv $@ $^
-	$(RANLIB) $@
-
-$(CONFIG_H):
-	cp $(CONFIG_H).default $(CONFIG_H)
-
-clean:
-	rm -f $(TARGET) $(OBJECTS)
--- a/README.android	Wed Jan 05 00:09:19 2011 -0800
+++ b/README.android	Thu Jan 06 16:11:21 2011 -0800
@@ -2,7 +2,8 @@
 Simple DirectMedia Layer for Android
 ================================================================================
 
-Requirements: Android NDK r4 or later
+Requirements: Android SDK and Android NDK r4 or later
+http://developer.android.com/
 
 ================================================================================
  How the port works
@@ -16,26 +17,44 @@
 - This eventually produces a standard Android .apk package
 
 
-
-
-
-
 ================================================================================
  Building an app
 ================================================================================
 
 Instructions:
-1. Edit android/config.cfg to point to the location of the NDK
-2. Run 'make -f Makefile.android'. If all goes well, libsdl.a should be created
-3. Place your application source files in android/project/jni
-4. Edit the Android.mk to include your source files
+1. Copy the android-project directory wherever you want your Android project to go
+2. Move this SDL directory into the <project>/jni directory
+3. Place your application source files in the <project>/jni/src directory
+4. Edit <project>/jni/src/Android.mk to include your source files
 5. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
-6. Edit project/local.properties to point to the SDK directory
-6. Run 'ant debug' in android/project. This compiles the .java and eventually 
-creates a .apk with the C source embedded
-7. 'ant install' will push the apk to the device or emulator (if connected)
+
+If you want to use the Eclipse IDE, skip to the Eclipse section below.
+
+6. Edit <project>/local.properties to point to the Android SDK directory
+7. Run 'ant debug' in android/project. This compiles the .java and eventually 
+creates a .apk with the native code embedded
+8. 'ant install' will push the apk to the device or emulator (if connected)
 
 
+================================================================================
+ Using Eclipse
+================================================================================
+
+NEED CONTENT
+
+
+================================================================================
+ Loading files
+================================================================================
+
+NEED CONTENT
+
+
+================================================================================
+ Troubleshooting
+================================================================================
+
+NEED CONTENT
 
 
 ================================================================================
--- a/android/config.cfg.example	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-# This file sets up paths needed to find the NDK build tools.
-# Edit it appropriately for your configuration and save it as "config.cfg".
-
-# This should be the full path to the Android NDK
-ANDROID_NDK := /Users/hercules/eclipse/android-ndk-r5
-
-# This should be "linux-x86" for linux, "darwin-x86" for mac
-ANDROID_NDK_HOST := darwin-x86
--- a/android/project/AndroidManifest.xml	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="org.libsdl.app"
-      android:versionCode="1"
-      android:versionName="1.0">
-    <application android:label="@string/app_name" android:icon="@drawable/icon">
-        <activity android:name="SDLActivity"
-                  android:label="@string/app_name">
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    </application>
-</manifest> 
--- a/android/project/build.properties	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-# This file is used to override default values used by the Ant build system.
-# 
-# This file must be checked in Version Control Systems, as it is
-# integral to the build system of your project.
-
-# This file is only used by the Ant script.
-
-# You can use this to override default values such as
-#  'source.dir' for the location of your java source folder and
-#  'out.dir' for the location of your output folder.
-
-# You can also use it define how the release builds are signed by declaring
-# the following properties:
-#  'key.store' for the location of your keystore and
-#  'key.alias' for the name of the key to use.
-# The password will be asked during the build when you use the 'release' target.
-
--- a/android/project/build.xml	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project name="SDLApp" default="help">
-
-    <!-- The local.properties file is created and updated by the 'android' tool.
-         It contains the path to the SDK. It should *NOT* be checked in in Version
-         Control Systems. -->
-    <property file="local.properties" />
-
-    <!-- The build.properties file can be created by you and is never touched
-         by the 'android' tool. This is the place to change some of the default property values
-         used by the Ant rules.
-         Here are some properties you may want to change/update:
-
-         application.package
-             the name of your application package as defined in the manifest. Used by the
-             'uninstall' rule.
-         source.dir
-             the name of the source directory. Default is 'src'.
-         out.dir
-             the name of the output directory. Default is 'bin'.
-
-         Properties related to the SDK location or the project target should be updated
-          using the 'android' tool with the 'update' action.
-
-         This file is an integral part of the build system for your application and
-         should be checked in in Version Control Systems.
-
-         -->
-    <property file="build.properties" />
-
-    <!-- The default.properties file is created and updated by the 'android' tool, as well
-         as ADT.
-         This file is an integral part of the build system for your application and
-         should be checked in in Version Control Systems. -->
-    <property file="default.properties" />
-
-    <!-- Custom Android task to deal with the project target, and import the proper rules.
-         This requires ant 1.6.0 or above. -->
-    <path id="android.antlibs">
-        <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
-        <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
-        <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
-        <pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
-        <pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
-    </path>
-
-    <taskdef name="setup"
-        classname="com.android.ant.SetupTask"
-        classpathref="android.antlibs" />
-
-    <!-- Execute the Android Setup task that will setup some properties specific to the target,
-         and import the build rules files.
-
-         The rules file is imported from
-            <SDK>/platforms/<target_platform>/templates/android_rules.xml
-
-         To customize some build steps for your project:
-         - copy the content of the main node <project> from android_rules.xml
-         - paste it in this build.xml below the <setup /> task.
-         - disable the import by changing the setup task below to <setup import="false" />
-
-         This will ensure that the properties are setup correctly but that your customized
-         build steps are used.
-    -->
-    <setup />
-
-</project>
--- a/android/project/default.properties	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,11 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-# 
-# This file must be checked in Version Control Systems.
-# 
-# To customize properties used by the Ant build system use,
-# "build.properties", and override values to adapt the script to your
-# project structure.
-
-# Project target.
-target=android-4
--- a/android/project/jni/Android.mk	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := sdlapp
-SDL := ../../../
-
-LOCAL_CFLAGS := -DANDROID_NDK \
-                -DDISABLE_IMPORTGL \
-                -I$(SDL)/include
-
-LOCAL_SRC_FILES := \
-    android-support.cpp \
-    lesson05.c \
-
-LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog -lSDL -lgcc -L$(SDL)
-
-include $(BUILD_SHARED_LIBRARY)
--- a/android/project/jni/android-support.cpp	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-/*******************************************************************************
- This file links the Java side of Android with libsdl
-*******************************************************************************/
-#include <jni.h>
-#include <sys/time.h>
-#include <time.h>
-#include <android/log.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <pthread.h>
-
-#define DEBUG
-
-
-/*******************************************************************************
-                               Globals
-*******************************************************************************/
-static long _getTime(void){
-	struct timeval  now;
-	gettimeofday(&now, NULL);
-	return (long)(now.tv_sec*1000 + now.tv_usec/1000);
-}
-
-JNIEnv* mEnv = NULL;
-JNIEnv* mAudioThreadEnv = NULL; //See the note below for why this is necessary
-JavaVM* mVM = NULL;
-
-//Main activity
-jclass mActivityInstance;
-
-//method signatures
-jmethodID midCreateGLContext;
-jmethodID midFlipBuffers;
-jmethodID midEnableFeature;
-jmethodID midUpdateAudio;
-
-extern "C" int SDL_main(int argc, char *argv[]);
-extern "C" int Android_OnKeyDown(int keycode);
-extern "C" int Android_OnKeyUp(int keycode);
-extern "C" void Android_SetScreenResolution(int width, int height);
-extern "C" void Android_OnResize(int width, int height, int format);
-extern "C" int SDL_SendQuit();
-extern "C" void Android_EnableFeature(int featureid, bool enabled);
-
-//If we're not the active app, don't try to render
-bool bRenderingEnabled = false;
-
-//Feature IDs
-static const int FEATURE_AUDIO = 1;
-static const int FEATURE_ACCEL = 2;
-
-//Accelerometer data storage
-float fLastAccelerometer[3];
-
-
-/*******************************************************************************
-                 Functions called by JNI
-*******************************************************************************/	
-
-//Library init
-extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved){
-
-    JNIEnv* env = NULL;
-    jint result = -1;
-
-    if (vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
-        return result;
-    }
-
-    mEnv = env;
-
-    __android_log_print(ANDROID_LOG_INFO, "SDL", "JNI: OnLoad");
-
-    jclass cls = mEnv->FindClass ("org/libsdl/app/SDLActivity"); 
-    mActivityInstance = cls;
-    midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V");
-    midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V");
-    midEnableFeature = mEnv->GetStaticMethodID(cls,"enableFeature","(II)V");
-    midUpdateAudio = mEnv->GetStaticMethodID(cls,"updateAudio","([B)V");
-
-    if(!midCreateGLContext || !midFlipBuffers || !midEnableFeature ||
-        !midUpdateAudio){
-        __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Bad mids\n");
-    }else{
-#ifdef DEBUG
-        __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Good mids\n");
-#endif
-    }
-    
-    return JNI_VERSION_1_4;
-}
-
-//Start up the SDL app
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit( JNIEnv* env, 
-                                                                jobject obj ){ 
-                                                                   
-	__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Native Init");
-
-	mEnv = env;
-	bRenderingEnabled = true;
-
-	Android_EnableFeature(FEATURE_ACCEL, true);
-
-    char *argv[2];
-    argv[0] = strdup("SDL_app");
-    argv[1] = NULL;
-    SDL_main(1, argv);
-}
-
-//Keydown
-extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(JNIEnv* env, 
-               jobject obj, jint keycode){
-    
-    int r = Android_OnKeyDown(keycode);
-#ifdef DEBUG
-    __android_log_print(ANDROID_LOG_INFO, "SDL", 
-                        "SDL: native key down %d, %d\n", keycode, r);
-#endif
-                        
-}
-
-//Keyup
-extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(JNIEnv* env, 
-               jobject obj, jint keycode){
-    
-    int r = Android_OnKeyUp(keycode);
-#ifdef DEBUG
-    __android_log_print(ANDROID_LOG_INFO, "SDL", 
-                        "SDL: native key up %d, %d\n", keycode, r);
-#endif
-                        
-}
-
-//Touch
-extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env, 
-               jobject obj, jint action, jfloat x, jfloat y, jfloat p){
-
-#ifdef DEBUG
-    __android_log_print(ANDROID_LOG_INFO, "SDL", 
-                        "SDL: native touch event %d @ %f/%f, pressure %f\n", 
-                        action, x, y, p);
-#endif
-
-    //TODO: Pass this off to the SDL multitouch stuff
-                        
-}
-
-//Quit
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit( JNIEnv*  env, 
-                                                                jobject obj ){    
-
-    //Stop rendering as we're no longer in the foreground
-	bRenderingEnabled = false;
-
-    //Inject a SDL_QUIT event
-    int r = SDL_SendQuit();
-
-    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Native quit %d", r);        
-}
-
-//Screen size
-extern "C" void Java_org_libsdl_app_SDLActivity_nativeSetScreenSize(
-                JNIEnv*  env, jobject obj, jint width, jint height){
-
-    __android_log_print(ANDROID_LOG_INFO, "SDL", 
-                        "SDL: Set screen size on init: %d/%d\n", width, height);
-    Android_SetScreenResolution(width, height);
-                        
-}
-
-//Resize
-extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize(
-                                        JNIEnv*  env, jobject obj, jint width, 
-                                        jint height, jint format){
-    Android_OnResize(width, height, format);
-}
-
-extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel(
-                                        JNIEnv*  env, jobject obj,
-                                        jfloat x, jfloat y, jfloat z){
-    fLastAccelerometer[0] = x;
-    fLastAccelerometer[1] = y;
-    fLastAccelerometer[2] = z;   
-}
-
-
-
-/*******************************************************************************
-             Functions called by SDL into Java
-*******************************************************************************/
-extern "C" void Android_CreateContext(){
-	__android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: sdl_create_context()\n");
-
-	bRenderingEnabled = true;
-
-    mEnv->CallStaticVoidMethod(mActivityInstance, midCreateGLContext ); 
-}
-
-extern "C" void Android_Render(){
-
-    if(!bRenderingEnabled){
-        return;
-    }
-
-    //When we get here, we've accumulated a full frame    
-    mEnv->CallStaticVoidMethod(mActivityInstance, midFlipBuffers ); 
-}
-
-extern "C" void Android_EnableFeature(int featureid, bool enabled){
-
-    mEnv->CallStaticVoidMethod(mActivityInstance, midEnableFeature, 
-                                featureid, (int)enabled); 
-}
-
-extern "C" void Android_UpdateAudioBuffer(unsigned char *buf, int len){
-
-    //Annoyingly we can't just call into Java from any thread. Because the audio
-    //callback is dispatched from the SDL audio thread (that wasn't made from
-    //java, we have to do some magic here to let the JVM know about the thread.
-    //Because everything it touches on the Java side is static anyway, it's 
-    //not a big deal, just annoying.
-    if(!mAudioThreadEnv){
-        __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Need to set up audio thread env\n");
-
-        mVM->AttachCurrentThread(&mAudioThreadEnv, NULL);
-
-        __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: ok\n");
-    }
-    
-    jbyteArray arr = mAudioThreadEnv->NewByteArray(len);
-
-    //blah. We probably should rework this so we avoid the copy. 
-    mAudioThreadEnv->SetByteArrayRegion(arr, 0, len, (jbyte *)buf);
-    
-    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: copied\n");
-
-    mAudioThreadEnv->CallStaticVoidMethod(  mActivityInstance, 
-                                            midUpdateAudio, arr );
-
-    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: invoked\n");
-    
-}
-
--- a/android/project/jni/lesson05.c	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,574 +0,0 @@
-/*
- * This code was created by Jeff Molofee '99 
- * (ported to Linux/SDL by Ti Leggett '01)
- *
- * If you've found this code useful, please let me know.
- *
- * Visit Jeff at http://nehe.gamedev.net/
- * 
- * or for port-specific comments, questions, bugreports etc. 
- * email to leggett@eecs.tulane.edu
- */
- 
-#include <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-
-#include <signal.h>
-
-#include <android/log.h>
-
-
-#ifdef ANDROID
-#include <GLES/gl.h>
-#else
-#include <GL/gl.h>
-#include <GL/glu.h>
-#endif
-#include "SDL.h"
-
-/* screen width, height, and bit depth */
-#define SCREEN_WIDTH  320
-#define SCREEN_HEIGHT 430
-#define SCREEN_BPP     16
-
-/* Define our booleans */
-#define TRUE  1
-#define FALSE 0
-
-/* This is our SDL surface */
-SDL_Surface *surface;
-
-int rotation = 0;
-
-
-/**************************************
-	gluperspective implementation
-**************************************/
-void gluPerspective(double fovy, double aspect, double zNear, double zFar){
-	glMatrixMode(GL_PROJECTION);
-	glLoadIdentity();
-	double xmin, xmax, ymin, ymax;
-	ymax = zNear * tan(fovy * M_PI / 360.0);
-	ymin = -ymax;
-	xmin = ymin * aspect;
-	xmax = ymax * aspect;
-	glFrustumf(xmin, xmax, ymin, ymax, zNear, zFar);
-}
-
-
-/**************************************
-	  glulookat implementation
-**************************************/
-void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,
-          GLfloat centerx, GLfloat centery, GLfloat centerz,
-          GLfloat upx, GLfloat upy, GLfloat upz)
-{
-    GLfloat m[16];
-    GLfloat x[3], y[3], z[3];
-    GLfloat mag;
-    
-    /* Make rotation matrix */
-    
-    /* Z vector */
-    z[0] = eyex - centerx;
-    z[1] = eyey - centery;
-    z[2] = eyez - centerz;
-    mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
-    if (mag) {          /* mpichler, 19950515 */
-        z[0] /= mag;
-        z[1] /= mag;
-        z[2] /= mag;
-    }
-    
-    /* Y vector */
-    y[0] = upx;
-    y[1] = upy;
-    y[2] = upz;
-    
-    /* X vector = Y cross Z */
-    x[0] = y[1] * z[2] - y[2] * z[1];
-    x[1] = -y[0] * z[2] + y[2] * z[0];
-    x[2] = y[0] * z[1] - y[1] * z[0];
-    
-    /* Recompute Y = Z cross X */
-    y[0] = z[1] * x[2] - z[2] * x[1];
-    y[1] = -z[0] * x[2] + z[2] * x[0];
-    y[2] = z[0] * x[1] - z[1] * x[0];
-    
-    /* mpichler, 19950515 */
-    /* cross product gives area of parallelogram, which is < 1.0 for
-     * non-perpendicular unit-length vectors; so normalize x, y here
-     */
-    
-    mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
-    if (mag) {
-        x[0] /= mag;
-        x[1] /= mag;
-        x[2] /= mag;
-    }
-    
-    mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
-    if (mag) {
-        y[0] /= mag;
-        y[1] /= mag;
-        y[2] /= mag;
-    }
-    
-#define M(row,col)  m[col*4+row]
-    M(0, 0) = x[0];
-    M(0, 1) = x[1];
-    M(0, 2) = x[2];
-    M(0, 3) = 0.0;
-    M(1, 0) = y[0];
-    M(1, 1) = y[1];
-    M(1, 2) = y[2];
-    M(1, 3) = 0.0;
-    M(2, 0) = z[0];
-    M(2, 1) = z[1];
-    M(2, 2) = z[2];
-    M(2, 3) = 0.0;
-    M(3, 0) = 0.0;
-    M(3, 1) = 0.0;
-    M(3, 2) = 0.0;
-    M(3, 3) = 1.0;
-#undef M
-    glMultMatrixf(m);
-    
-    /* Translate Eye to Origin */
-    glTranslatef(-eyex, -eyey, -eyez);
-    
-}
-
-
-
-
-
-/* function to release/destroy our resources and restoring the old desktop */
-void Quit( int returnCode )
-{
-    /* clean up the window */
-    SDL_Quit( );
-
-    /* and exit appropriately */
-    exit( returnCode );
-}
-
-/* function to reset our viewport after a window resize */
-int resizeWindow( int width, int height )
-{
-    /* Height / width ration */
-    GLfloat ratio;
- 
-    /* Protect against a divide by zero */
-   if ( height == 0 )
-	height = 1;
-
-    ratio = ( GLfloat )width / ( GLfloat )height;
-
-    /* Setup our viewport. */
-    glViewport( 0, 0, ( GLsizei )width, ( GLsizei )height );
-
-    /* change to the projection matrix and set our viewing volume. */
-    glMatrixMode( GL_PROJECTION );
-    glLoadIdentity( );
-
-    /* Set our perspective */
-    gluPerspective( 45.0f, ratio, 0.1f, 100.0f );
-
-    /* Make sure we're chaning the model view and not the projection */
-    glMatrixMode( GL_MODELVIEW );
-
-    /* Reset The View */
-    glLoadIdentity( );
-
-    return( TRUE );
-}
-
-/* function to handle key press events */
-void handleKeyPress( SDL_keysym *keysym )
-{
-    switch ( keysym->sym )
-	{
-	case SDLK_ESCAPE:
-	    /* ESC key was pressed */
-	    Quit( 0 );
-	    break;
-	case SDLK_F1:
-	    /* F1 key was pressed
-	     * this toggles fullscreen mode
-	     */
-	    SDL_WM_ToggleFullScreen( surface );
-	    break;
-    case SDLK_LEFT:
-        rotation -= 30;
-        break;
-
-    case SDLK_RIGHT:
-        rotation += 30;
-        break;
-        
-	default:
-	    break;
-	}
-
-    __android_log_print(ANDROID_LOG_INFO, "SDL","Keycode: %d, %d, %d\n", keysym->sym, SDLK_LEFT, SDLK_RIGHT);
-
-    return;
-}
-
-/* general OpenGL initialization function */
-int initGL( GLvoid )
-{
-
-    /* Enable smooth shading */
-    glShadeModel( GL_SMOOTH );
-
-    /* Set the background black */
-    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
-
-    /* Depth buffer setup */
-    //glClearDepth( 1.0f );
-
-    /* Enables Depth Testing */
-    glEnable( GL_DEPTH_TEST );
-
-    /* The Type Of Depth Test To Do */
-    glDepthFunc( GL_LEQUAL );
-
-    /* Really Nice Perspective Calculations */
-    glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
-
-    return( TRUE );
-}
-
-/* Here goes our drawing code */
-int drawGLScene( GLvoid )
-{
-      
-	static int Frames = 0;
-	static int T0 = 0;
-	
-    glViewport(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
-
-    glClearColorx(0,0,0,255);
-    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
-
-    glMatrixMode(GL_PROJECTION);
-    glLoadIdentity();
-    gluPerspective(45, (float)SCREEN_WIDTH / SCREEN_HEIGHT, 0.5f, 150);
-
-    glMatrixMode(GL_MODELVIEW);
-
-    glLoadIdentity();
-
-	//Camera
-	gluLookAt(0,0,5, 0,0,0, 0,1,0);
-			
-	//Draw a triangle
-	//glRotatef(iRot, 0, 1, 0);
-
-	glRotatef( rotation, 0.0f, 1.0f, 0.0f );
-
-
-	glEnableClientState (GL_VERTEX_ARRAY);
-	glEnableClientState (GL_COLOR_ARRAY);
-	
-	/* Rotate The Triangle On The Y axis ( NEW ) */
-    //glRotatef( Frames % 360, 0.0f, 1.0f, 0.0f );
-
-    /* GLES variant of drawing a triangle */
-    const GLfloat triVertices[][9] = {
-      {     /* Front Triangle */
-	 0.0f,  1.0f,  0.0f,               /* Top Of Triangle               */
-	-1.0f, -1.0f,  1.0f,               /* Left Of Triangle              */
-	 1.0f, -1.0f,  1.0f                /* Right Of Triangle             */
-      }, {  /* Right Triangle */
-	 0.0f,  1.0f,  0.0f,               /* Top Of Triangle               */
-	 1.0f, -1.0f,  1.0f,               /* Left Of Triangle              */
-	 1.0f, -1.0f, -1.0f                /* Right Of Triangle             */
-      }, {  /* Back Triangle */
-	 0.0f,  1.0f,  0.0f,               /* Top Of Triangle               */
-	 1.0f, -1.0f, -1.0f,               /* Left Of Triangle              */
-	-1.0f, -1.0f, -1.0f                /* Right Of Triangle             */
-      }, {  /* Left Triangle */
-	 0.0f,  1.0f,  0.0f,               /* Top Of Triangle               */
-	-1.0f, -1.0f, -1.0f,               /* Left Of Triangle              */
-	-1.0f, -1.0f,  1.0f                /* Right Of Triangle             */
-      }
-    };
-
-    /* unlike GL, GLES does not support RGB. We have to use RGBA instead */
-    const GLfloat triColors[][12] = {
-      {     /* Front triangle */
-        1.0f, 0.0f, 0.0f, 1.0f,            /* Red                           */
-	0.0f, 1.0f, 0.0f, 1.0f,            /* Green                         */
-	0.0f, 0.0f, 1.0f, 1.0f             /* Blue                          */
-      }, {  /* Right triangle */
-        1.0f, 0.0f, 0.0f, 1.0f,            /* Red                           */
-	0.0f, 0.0f, 1.0f, 1.0f,            /* Blue                          */
-	0.0f, 1.0f, 0.0f, 1.0f             /* Green                         */
-      }, {  /* Back triangle */
-        1.0f, 0.0f, 0.0f, 1.0f,            /* Red                           */
-	0.0f, 1.0f, 0.0f, 1.0f,            /* Green                         */
-	0.0f, 0.0f, 1.0f, 1.0f             /* Blue                          */
-      }, {  /* Left triangle */
-        1.0f, 0.0f, 0.0f, 1.0f,            /* Red                           */
-	0.0f, 0.0f, 1.0f, 1.0f,            /* Blue                          */
-	0.0f, 1.0f, 0.0f, 1.0f             /* Green                         */
-      }
-    };
-
-    glEnableClientState(GL_COLOR_ARRAY);
-
-    int tri=0;
-
-    /* Loop through all Triangles */
-    for(tri=0;tri<sizeof(triVertices)/(9*sizeof(GLfloat));tri++) 
-    {
-      glVertexPointer(3, GL_FLOAT, 0, triVertices[tri]);
-      glColorPointer(4, GL_FLOAT, 0, triColors[tri]);
-      
-      glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
-    }
-		
-    //__android_log_print(ANDROID_LOG_INFO, "SDL", "render %d", Frames++);
-
-    /* Draw it to the screen */
-    SDL_GL_SwapBuffers( );
-
-    /* Gather our frames per second */
-    Frames++;
-    {
-	GLint t = SDL_GetTicks();
-	if (t - T0 >= 5000) {
-	    GLfloat seconds = (t - T0) / 1000.0;
-	    GLfloat fps = Frames / seconds;
-	    __android_log_print(ANDROID_LOG_INFO, "SDL","%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
-	    T0 = t;
-	    Frames = 0;
-	}
-    }
-
-    rotation++;
-
-    return( TRUE );
-}
-
-
-struct
-{
-    SDL_AudioSpec spec;
-    Uint8 *sound;               /* Pointer to wave data */
-    Uint32 soundlen;            /* Length of wave data */
-    int soundpos;               /* Current play position */
-} wave;
-
-void SDLCALL
-fillerup(void *unused, Uint8 * stream, int len)
-{
-    __android_log_print(ANDROID_LOG_INFO, "SDL","FILLERUP\n");
-    
-    Uint8 *waveptr;
-    int waveleft;
-
-    /* Set up the pointers */
-    waveptr = wave.sound + wave.soundpos;
-    waveleft = wave.soundlen - wave.soundpos;
-
-    /* Go! */
-    while (waveleft <= len) {
-        SDL_memcpy(stream, waveptr, waveleft);
-        stream += waveleft;
-        len -= waveleft;
-        waveptr = wave.sound;
-        waveleft = wave.soundlen;
-        wave.soundpos = 0;
-    }
-    SDL_memcpy(stream, waveptr, len);
-    wave.soundpos += len;
-}
-
-void testAudio(){
-
-    const char *file = "/sdcard/sample.wav";
-
-    /* Load the SDL library */
-    if (SDL_Init(SDL_INIT_AUDIO) < 0) {
-        __android_log_print(ANDROID_LOG_INFO, "SDL","Couldn't initialize SDL Audio: %s\n", SDL_GetError());
-        return;
-    }else{
-        __android_log_print(ANDROID_LOG_INFO, "SDL","Init audio ok\n");
-    }
-
-    /* Load the wave file into memory */
-    if (SDL_LoadWAV(file, &wave.spec, &wave.sound, &wave.soundlen) == NULL) {
-        __android_log_print(ANDROID_LOG_INFO, "SDL", "Couldn't load %s: %s\n", file, SDL_GetError());
-        return;
-    }
-
-    wave.spec.callback = fillerup;
-
-    __android_log_print(ANDROID_LOG_INFO, "SDL","Loaded: %d\n", wave.soundlen);
-
-
-    /* Initialize fillerup() variables */
-    if (SDL_OpenAudio(&wave.spec, NULL) < 0) {
-        __android_log_print(ANDROID_LOG_INFO, "SDL", "Couldn't open audio: %s\n", SDL_GetError());
-        SDL_FreeWAV(wave.sound);
-        return;
-    }
-
-     __android_log_print(ANDROID_LOG_INFO, "SDL","Using audio driver: %s\n", SDL_GetCurrentAudioDriver());
-
-    /* Let the audio run */
-    SDL_PauseAudio(0);
-
-     __android_log_print(ANDROID_LOG_INFO, "SDL","Playing\n");
-    
-    while (SDL_GetAudioStatus() == SDL_AUDIO_PLAYING){
-         //__android_log_print(ANDROID_LOG_INFO, "SDL","Still playing\n");
-        SDL_Delay(100);
-    }
-
-     __android_log_print(ANDROID_LOG_INFO, "SDL","Closing down\n");
-
-    /* Clean up on signal */
-    SDL_CloseAudio();
-    SDL_FreeWAV(wave.sound);
-}
-
-int SDL_main( int argc, char **argv )
-{
-
-	__android_log_print(ANDROID_LOG_INFO, "SDL","entry\n");
-
-    /* Flags to pass to SDL_SetVideoMode */
-    int videoFlags;
-    /* main loop variable */
-    int done = FALSE;
-    /* used to collect events */
-    SDL_Event event;
-    /* this holds some info about our display */
-    const SDL_VideoInfo *videoInfo;
-    /* whether or not the window is active */
-    int isActive = TRUE;
-
-    /* initialize SDL */
-    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
-	{
-	    __android_log_print(ANDROID_LOG_INFO, "SDL", "Video initialization failed: %s\n",
-		     SDL_GetError( ) );
-	    Quit( 1 );
-	}
-
-    /* Fetch the video info */
-    videoInfo = SDL_GetVideoInfo( );
-
-    if ( !videoInfo )
-	{
-	    __android_log_print(ANDROID_LOG_INFO, "SDL", "Video query failed: %s\n",
-		     SDL_GetError( ) );
-	    Quit( 1 );
-	}
-
-    /* the flags to pass to SDL_SetVideoMode */
-    videoFlags  = SDL_OPENGL;          /* Enable OpenGL in SDL */
-    videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
-    videoFlags |= SDL_HWPALETTE;       /* Store the palette in hardware */
-    videoFlags |= SDL_RESIZABLE;       /* Enable window resizing */
-
-    /* This checks to see if surfaces can be stored in memory */
-    if ( videoInfo->hw_available )
-	videoFlags |= SDL_HWSURFACE;
-    else
-	videoFlags |= SDL_SWSURFACE;
-
-    /* This checks if hardware blits can be done */
-    if ( videoInfo->blit_hw )
-	videoFlags |= SDL_HWACCEL;
-
-    /* Sets up OpenGL double buffering */
-    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
-
-    /* get a SDL surface */
-    surface = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,
-				videoFlags );
-
-    /* Verify there is a surface */
-    if ( !surface )
-	{
-	    __android_log_print(ANDROID_LOG_INFO, "SDL",  "Video mode set failed: %s\n", SDL_GetError( ) );
-	    Quit( 1 );
-	}
-
-	__android_log_print(ANDROID_LOG_INFO, "SDL","Made a video mode!\n");
-
-    /* initialize OpenGL */
-    initGL( );
-
-    /* resize the initial window */
-    resizeWindow( SCREEN_WIDTH, SCREEN_HEIGHT );
-
-
-    //testAudio();
-
-
-    /* wait for events */ 
-    while ( !done )
-	{
-	    /* handle the events in the queue */
-
-	    while ( SDL_PollEvent( &event ) )
-		{
-		    switch( event.type )
-			{
-			case SDL_ACTIVEEVENT:
-			    /* Something's happend with our focus
-			     * If we lost focus or we are iconified, we
-			     * shouldn't draw the screen
-			     */
-			    if ( event.active.gain == 0 )
-				isActive = FALSE;
-			    else
-				isActive = TRUE;
-			    break;			    
-			case SDL_VIDEORESIZE:
-			    /* handle resize event */
-			    surface = SDL_SetVideoMode( event.resize.w,
-							event.resize.h,
-							16, videoFlags );
-			    if ( !surface )
-				{
-				    __android_log_print(ANDROID_LOG_INFO, "SDL","Could not get a surface after resize: %s\n", SDL_GetError( ) );
-				    Quit( 1 );
-				}
-			    resizeWindow( event.resize.w, event.resize.h );
-			    break;
-			case SDL_KEYDOWN:
-			    /* handle key presses */
-			    handleKeyPress( &event.key.keysym );
-			    break;
-			case SDL_QUIT:
-			    /* handle quit requests */
-			    done = TRUE;
-			    __android_log_print(ANDROID_LOG_INFO, "SDL","App is shutting down\n");
-			    break;
-			default:
-			    break;
-			}
-		}
-
-	    /* draw the scene */
-	    if ( isActive )
-		drawGLScene( );
-	}
-
-    /* clean ourselves up and exit */
-    Quit( 0 );
-
-    /* Should never get here */
-    return( 0 );
-}
-
-
--- a/android/project/local.properties	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-# This file is automatically generated by Android Tools.
-# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
-# 
-# This file must *NOT* be checked in Version Control Systems,
-# as it contains information specific to your local configuration.
-
-# location of the SDK. This is only used by Ant
-# For customization when using a Version Control System, please read the
-# header note.
-sdk.dir=/home/paul/Projects/gsoc/sdk/android-sdk-linux_86
Binary file android/project/res/drawable-hdpi/icon.png has changed
Binary file android/project/res/drawable-ldpi/icon.png has changed
Binary file android/project/res/drawable-mdpi/icon.png has changed
--- a/android/project/res/layout/main.xml	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,13 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="vertical"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
-    >
-<TextView  
-    android:layout_width="fill_parent" 
-    android:layout_height="wrap_content" 
-    android:text="Hello World, SDLActivity"
-    />
-</LinearLayout>
-
--- a/android/project/res/values/strings.xml	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <string name="app_name">SDLActivity</string>
-</resources>
--- a/android/project/src/org/libsdl/app/SDLActivity.java	Wed Jan 05 00:09:19 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,388 +0,0 @@
-package org.libsdl.app;
-
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.opengles.GL10;
-import javax.microedition.khronos.egl.*;
-
-import android.app.*;
-import android.content.*;
-import android.view.*;
-import android.os.*;
-import android.util.Log;
-import android.graphics.*;
-import android.text.method.*;
-import android.text.*;
-import android.media.*;
-import android.hardware.*;
-import android.content.*;
-
-import java.lang.*;
-
-
-/**
-    SDL Activity
-*/
-public class SDLActivity extends Activity {
-
-    //Main components
-    private static SDLActivity mSingleton;
-    private static SDLSurface mSurface;
-
-    //Audio
-    private static AudioTrack mAudioTrack;
-    private static boolean bAudioIsEnabled;
-
-    //Sensors
-    private static boolean bAccelIsEnabled;
-
-    //feature IDs. Must match up on the C side as well.
-    private static int FEATURE_AUDIO = 1;
-    private static int FEATURE_ACCEL = 2;
-
-    //Load the .so
-    static {
-        System.loadLibrary("sdlapp");
-    }
-
-    //Setup
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        
-        //So we can call stuff from static callbacks
-        mSingleton = this;
-
-        //Set up the surface
-        mSurface = new SDLSurface(getApplication());
-        setContentView(mSurface);
-        SurfaceHolder holder = mSurface.getHolder();
-        holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
-        
-    }
-
-    //Audio
-    public static boolean initAudio(){        
-
-        //blah. Hardcoded things are bad. FIXME when we have more sound stuff
-        //working properly. 
-        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
-                    11025,
-                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
-                    AudioFormat.ENCODING_PCM_8BIT,
-                    2048,
-                    AudioTrack.MODE_STREAM);   
-        bAudioIsEnabled = true;     
-        return true;
-    }
-
-    //Accel
-    public static boolean initAccel(){
-        mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
-        bAccelIsEnabled = true;
-        return true;
-    }
-    
-    public static boolean closeAccel(){
-        mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false);
-        bAccelIsEnabled = false;
-        return true;
-    }
-    
-
-    //Events
-    protected void onPause() {
-        super.onPause();
-    }
-
-    protected void onResume() {
-        super.onResume();
-    }
-
-    
-
-
-
-    //C functions we call
-    public static native void nativeInit();
-    public static native void nativeQuit();
-    public static native void nativeSetScreenSize(int width, int height);
-    public static native void onNativeKeyDown(int keycode);
-    public static native void onNativeKeyUp(int keycode);
-    public static native void onNativeTouch(int action, float x, 
-                                            float y, float p);
-    public static native void onNativeResize(int x, int y, int format);
-    public static native void onNativeAccel(float x, float y, float z);
-
-
-
-    //Java functions called from C
-    private static void createGLContext(){
-        mSurface.initEGL();
-    }
-
-    public static void flipBuffers(){
-        mSurface.flipEGL();
-    }
-
-    public static void updateAudio(byte [] buf){
-    
-        if(mAudioTrack == null){
-            return;
-        }
-        
-        mAudioTrack.write(buf, 0, buf.length);
-        mAudioTrack.play();
-        
-        Log.v("SDL","Played some audio");
-    }
-
-    public static void enableFeature(int featureid, int enabled){
-         Log.v("SDL","Feature " + featureid + " = " + enabled);
-
-        //Yuck. This is all horribly inelegent. If it gets to more than a few
-        //'features' I'll rip this out and make something nicer, I promise :)
-        if(featureid == FEATURE_AUDIO){
-            if(enabled == 1){
-                initAudio();
-            }else{
-                //We don't have one of these yet...
-                //closeAudio(); 
-            }
-        }
-
-        else if(featureid == FEATURE_ACCEL){
-            if(enabled == 1){
-                initAccel();
-            }else{
-                closeAccel();
-            }
-        }
-    }
-
-
-
-
-
-    
-    
-}
-
-/**
-    Simple nativeInit() runnable
-*/
-class SDLRunner implements Runnable{
-    public void run(){
-        //SDLActivity.initAudio();
-        
-        //Runs SDL_main()
-        SDLActivity.nativeInit();
-
-        Log.v("SDL","SDL thread terminated");
-    }
-}
-
-
-/**
-    SDLSurface. This is what we draw on, so we need to know when it's created
-    in order to do anything useful. 
-
-    Because of this, that's where we set up the SDL thread
-*/
-class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, 
-    View.OnKeyListener, View.OnTouchListener, SensorEventListener  {
-
-    //This is what SDL runs in. It invokes SDL_main(), eventually
-    private Thread mSDLThread;    
-    
-    //EGL private objects
-    private EGLContext  mEGLContext;
-    private EGLSurface  mEGLSurface;
-    private EGLDisplay  mEGLDisplay;
-
-    //Sensors
-    private static SensorManager mSensorManager;
-
-    //Startup    
-    public SDLSurface(Context context) {
-        super(context);
-        getHolder().addCallback(this); 
-    
-        setFocusable(true);
-        setFocusableInTouchMode(true);
-        requestFocus();
-        setOnKeyListener(this); 
-        setOnTouchListener(this);   
-        
-        mSensorManager = (SensorManager)context.getSystemService("sensor");  
-    }
-
-    //Called when we have a valid drawing surface
-    public void surfaceCreated(SurfaceHolder holder) {
-        Log.v("SDL","Surface created"); 
-
-        int width = getWidth();
-        int height = getHeight();
-
-        //Set the width and height variables in C before we start SDL so we have
-        //it available on init
-        SDLActivity.nativeSetScreenSize(width, height);
-
-        //Now start up the C app thread
-        mSDLThread = new Thread(new SDLRunner(), "SDLThread"); 
-		mSDLThread.start();       
-    }
-
-    //Called when we lose the surface
-    public void surfaceDestroyed(SurfaceHolder holder) {
-        Log.v("SDL","Surface destroyed");
-        
-        SDLActivity.nativeQuit();
-
-        //Now wait for the SDL thread to quit
-        try{
-            mSDLThread.wait();
-        }catch(Exception e){
-            Log.v("SDL","Problem stopping thread: " + e);
-        }
-    }
-
-    //Called when the surface is resized
-    public void surfaceChanged(SurfaceHolder holder, int format, 
-                                int width, int height) {
-        Log.v("SDL","Surface resized");
-        
-        SDLActivity.onNativeResize(width, height, format);
-    }
-
-    //unused
-    public void onDraw(Canvas canvas) {}
-
-    
-    //EGL functions
-    public boolean initEGL(){
-        Log.v("SDL","Starting up");
-
-        try{
-
-            EGL10 egl = (EGL10)EGLContext.getEGL();
-
-            EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
-
-            int[] version = new int[2];
-            egl.eglInitialize(dpy, version);
-
-            int[] configSpec = {
-                    //EGL10.EGL_DEPTH_SIZE,   16,
-                    EGL10.EGL_NONE
-            };
-            EGLConfig[] configs = new EGLConfig[1];
-            int[] num_config = new int[1];
-            egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config);
-            EGLConfig config = configs[0];
-
-            EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, null);
-
-            EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, this, null);
-
-            egl.eglMakeCurrent(dpy, surface, surface, ctx);
-
-            mEGLContext = ctx;
-            mEGLDisplay = dpy;
-            mEGLSurface = surface;
-            
-            
-        }catch(Exception e){
-            Log.v("SDL", e + "");
-            for(StackTraceElement s : e.getStackTrace()){
-                Log.v("SDL", s.toString());
-            }
-        }
-        Log.v("SDL","Done making!");
-
-        return true;
-    }
-
-    //EGL buffer flip
-    public void flipEGL(){      
-        try{
-        
-            EGL10 egl = (EGL10)EGLContext.getEGL();
-            GL10 gl = (GL10)mEGLContext.getGL();
-
-            egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null);
-
-            //drawing here
-
-            egl.eglWaitGL();
-
-            egl.eglSwapBuffers(mEGLDisplay, mEGLSurface);
-
-            
-        }catch(Exception e){
-            Log.v("SDL", "flipEGL(): " + e);
-
-            for(StackTraceElement s : e.getStackTrace()){
-                Log.v("SDL", s.toString());
-            }
-        }
-    }
-
-
-  
-    //Key events
-    public boolean onKey(View  v, int keyCode, KeyEvent event){
-
-        if(event.getAction() == KeyEvent.ACTION_DOWN){
-            SDLActivity.onNativeKeyDown(keyCode);
-            return true;
-        }
-        
-        else if(event.getAction() == KeyEvent.ACTION_UP){
-            SDLActivity.onNativeKeyUp(keyCode);
-            return true;
-        }
-        
-        return false;
-    }
-
-    //Touch events
-    public boolean onTouch(View v, MotionEvent event){
-    
-        int action = event.getAction();
-        float x = event.getX();
-        float y = event.getY();
-        float p = event.getPressure();
-
-        //TODO: Anything else we need to pass?        
-        SDLActivity.onNativeTouch(action, x, y, p);
-        return true;
-    }
-
-    //Sensor events
-    public void enableSensor(int sensortype, boolean enabled){
-        //TODO: This uses getDefaultSensor - what if we have >1 accels?
-        if(enabled){
-            mSensorManager.registerListener(this, 
-                            mSensorManager.getDefaultSensor(sensortype), 
-                            SensorManager.SENSOR_DELAY_GAME, null);
-        }else{
-            mSensorManager.unregisterListener(this, 
-                            mSensorManager.getDefaultSensor(sensortype));
-        }
-    }
-    
-    public void onAccuracyChanged(Sensor sensor, int accuracy){
-        //TODO
-    }
-
-    public void onSensorChanged(SensorEvent event){
-        if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
-            SDLActivity.onNativeAccel(  event.values[0],
-                                        event.values[1],
-                                        event.values[2] );
-        }
-    }
-
-
-}
-
-
--- a/include/SDL_config_android.h	Wed Jan 05 00:09:19 2011 -0800
+++ b/include/SDL_config_android.h	Thu Jan 06 16:11:21 2011 -0800
@@ -127,7 +127,7 @@
 #define SDL_HAPTIC_DUMMY	1
 
 /* Enable various shared object loading systems */
-#define SDL_LOADSO_DUMMY	1
+#define SDL_LOADSO_DLOPEN	1
 
 /* Enable various threading systems */
 #define SDL_THREAD_PTHREAD	1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/SDL_android.cpp	Thu Jan 06 16:11:21 2011 -0800
@@ -0,0 +1,231 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2010 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*******************************************************************************
+ This file links the Java side of Android with libsdl
+*******************************************************************************/
+#include <jni.h>
+#include <android/log.h>
+
+
+/*******************************************************************************
+                               Globals
+*******************************************************************************/
+JavaVM* mVM = NULL;
+JNIEnv* mEnv = NULL;
+JNIEnv* mAudioThreadEnv = NULL; //See the note below for why this is necessary
+
+//Main activity
+jclass mActivityInstance;
+
+//method signatures
+jmethodID midCreateGLContext;
+jmethodID midFlipBuffers;
+jmethodID midEnableFeature;
+jmethodID midUpdateAudio;
+
+extern "C" int Android_OnKeyDown(int keycode);
+extern "C" int Android_OnKeyUp(int keycode);
+extern "C" void Android_SetScreenResolution(int width, int height);
+extern "C" void Android_OnResize(int width, int height, int format);
+extern "C" int SDL_SendQuit();
+extern "C" void Android_EnableFeature(int featureid, bool enabled);
+
+//If we're not the active app, don't try to render
+bool bRenderingEnabled = false;
+
+//Feature IDs
+static const int FEATURE_AUDIO = 1;
+static const int FEATURE_ACCEL = 2;
+
+//Accelerometer data storage
+float fLastAccelerometer[3];
+
+
+/*******************************************************************************
+                 Functions called by JNI
+*******************************************************************************/
+
+// Library init
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+    mVM = vm;
+
+    return JNI_VERSION_1_4;
+}
+
+// Called before SDL_main() to initialize JNI bindings
+extern "C" void SDL_Android_Init(JNIEnv* env)
+{
+    mEnv = env;
+
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL_Android_Init()");
+
+    jclass cls = mEnv->FindClass ("org/libsdl/app/SDLActivity"); 
+    mActivityInstance = cls;
+    midCreateGLContext = mEnv->GetStaticMethodID(cls,"createGLContext","()V");
+    midFlipBuffers = mEnv->GetStaticMethodID(cls,"flipBuffers","()V");
+    midEnableFeature = mEnv->GetStaticMethodID(cls,"enableFeature","(II)V");
+    midUpdateAudio = mEnv->GetStaticMethodID(cls,"updateAudio","([B)V");
+
+    if(!midCreateGLContext || !midFlipBuffers || !midEnableFeature ||
+        !midUpdateAudio) {
+        __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Bad mids\n");
+    } else {
+#ifdef DEBUG
+        __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Good mids\n");
+#endif
+    }
+}
+
+// Keydown
+extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyDown(JNIEnv* env, 
+               jobject obj, jint keycode)
+{
+    int r = Android_OnKeyDown(keycode);
+#ifdef DEBUG
+    __android_log_print(ANDROID_LOG_INFO, "SDL", 
+                        "SDL: native key down %d, %d\n", keycode, r);
+#endif
+}
+
+// Keyup
+extern "C" void Java_org_libsdl_app_SDLActivity_onNativeKeyUp(JNIEnv* env, 
+               jobject obj, jint keycode)
+{
+    int r = Android_OnKeyUp(keycode);
+#ifdef DEBUG
+    __android_log_print(ANDROID_LOG_INFO, "SDL", 
+                        "SDL: native key up %d, %d\n", keycode, r);
+#endif
+}
+
+// Touch
+extern "C" void Java_org_libsdl_app_SDLActivity_onNativeTouch(JNIEnv* env, 
+               jobject obj, jint action, jfloat x, jfloat y, jfloat p)
+{
+#ifdef DEBUG
+    __android_log_print(ANDROID_LOG_INFO, "SDL", 
+                        "SDL: native touch event %d @ %f/%f, pressure %f\n", 
+                        action, x, y, p);
+#endif
+
+    //TODO: Pass this off to the SDL multitouch stuff
+}
+
+// Quit
+extern "C" void Java_org_libsdl_app_SDLActivity_nativeQuit( JNIEnv*  env, 
+                                                                jobject obj )
+{    
+    // Stop rendering as we're no longer in the foreground
+    bRenderingEnabled = false;
+
+    // Inject a SDL_QUIT event
+    SDL_SendQuit();
+}
+
+// Screen size
+extern "C" void Java_org_libsdl_app_SDLActivity_nativeSetScreenSize(
+                JNIEnv*  env, jobject obj, jint width, jint height)
+{
+    __android_log_print(ANDROID_LOG_INFO, "SDL", 
+                        "SDL: Set screen size on init: %d/%d\n", width, height);
+    Android_SetScreenResolution(width, height);
+}
+
+// Resize
+extern "C" void Java_org_libsdl_app_SDLActivity_onNativeResize(
+                                        JNIEnv*  env, jobject obj, jint width, 
+                                        jint height, jint format)
+{
+    Android_OnResize(width, height, format);
+}
+
+extern "C" void Java_org_libsdl_app_SDLActivity_onNativeAccel(
+                                        JNIEnv*  env, jobject obj,
+                                        jfloat x, jfloat y, jfloat z)
+{
+    fLastAccelerometer[0] = x;
+    fLastAccelerometer[1] = y;
+    fLastAccelerometer[2] = z;   
+}
+
+
+
+/*******************************************************************************
+             Functions called by SDL into Java
+*******************************************************************************/
+extern "C" void Android_CreateContext()
+{
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: sdl_create_context()\n");
+
+    bRenderingEnabled = true;
+
+    mEnv->CallStaticVoidMethod(mActivityInstance, midCreateGLContext ); 
+}
+
+extern "C" void Android_Render()
+{
+    if (!bRenderingEnabled) {
+        return;
+    }
+
+    // When we get here, we've accumulated a full frame    
+    mEnv->CallStaticVoidMethod(mActivityInstance, midFlipBuffers); 
+}
+
+extern "C" void Android_EnableFeature(int featureid, bool enabled)
+{
+    mEnv->CallStaticVoidMethod(mActivityInstance, midEnableFeature, 
+                                featureid, (int)enabled); 
+}
+
+extern "C" void Android_UpdateAudioBuffer(unsigned char *buf, int len)
+{
+    //Annoyingly we can't just call into Java from any thread. Because the audio
+    //callback is dispatched from the SDL audio thread (that wasn't made from
+    //java, we have to do some magic here to let the JVM know about the thread.
+    //Because everything it touches on the Java side is static anyway, it's 
+    //not a big deal, just annoying.
+    if(!mAudioThreadEnv) {
+        __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: Need to set up audio thread env\n");
+
+        mVM->AttachCurrentThread(&mAudioThreadEnv, NULL);
+
+        __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: ok\n");
+    }
+    
+    jbyteArray arr = mAudioThreadEnv->NewByteArray(len);
+
+    //blah. We probably should rework this so we avoid the copy. 
+    mAudioThreadEnv->SetByteArrayRegion(arr, 0, len, (jbyte *)buf);
+    
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: copied\n");
+
+    mAudioThreadEnv->CallStaticVoidMethod(  mActivityInstance, 
+                                            midUpdateAudio, arr );
+
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "SDL: invoked\n");
+    
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/main/android/SDL_android_main.cpp	Thu Jan 06 16:11:21 2011 -0800
@@ -0,0 +1,30 @@
+
+/* Include the SDL main definition header */
+#include "SDL_main.h"
+
+/*******************************************************************************
+                 Functions called by JNI
+*******************************************************************************/
+#include <jni.h>
+
+// Called before SDL_main() to initialize JNI bindings in SDL library
+extern "C" void SDL_Android_Init(JNIEnv* env);
+
+// Library init
+extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
+{
+    return JNI_VERSION_1_4;
+}
+
+// Start up the SDL app
+extern "C" void Java_org_libsdl_app_SDLActivity_nativeInit( JNIEnv* env, jobject obj )
+{
+    /* This interface could expand with ABI negotiation, calbacks, etc. */
+    SDL_Android_Init(env);
+
+    /* Run the application code! */
+    char *argv[2];
+    argv[0] = strdup("SDL_app");
+    argv[1] = NULL;
+    SDL_main(1, argv);
+}