Merged Paul's Google Summer of Code work from SDL-gsoc2010_android
authorSam Lantinga <slouken@libsdl.org>
Sun, 22 Aug 2010 12:23:55 -0700
changeset 4729 1f7ad083fd3c
parent 4694 c24ba2cc9583 (current diff)
parent 4728 431c0381c696 (diff)
child 4762 833a225613e2
Merged Paul's Google Summer of Code work from SDL-gsoc2010_android
include/SDL_stdinc.h
src/SDL_compat.c
src/audio/SDL_audio.c
src/events/SDL_events.c
src/events/SDL_keyboard.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile.android	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,52 @@
+# Makefile to build the SDL library
+
+include ./android/config.cfg #get ANDROID_NDK
+
+TOOLS_PATH=$(ANDROID_NDK)/build/prebuilt/linux-x86/arm-eabi-4.2.1/bin
+ANDROID_INCLUDES = 	-I$(ANDROID_NDK)/build/platforms/android-4/common/include \
+					-I$(ANDROID_NDK)/build/platforms/android-4/arch-arm/usr/include 
+INCLUDE = -I./include
+CFLAGS  = -g -O2 $(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/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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.android	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,45 @@
+================================================================================
+Simple DirectMedia Layer for Android
+================================================================================
+
+Requirements: Android NDK r4 or later
+
+================================================================================
+ How the port works
+================================================================================
+
+- Android applications are Java-based, optionally with parts written in C
+- As SDL apps are C-based, we use a small Java shim that uses JNI to talk to 
+the SDL library
+- This means that your application C code must be placed inside an android 
+Java project, along with some C support code that communicates with Java
+- 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
+5. Run 'ndk-build' (a script provided by the NDK). This compiles the C source
+6. Run 'ant' in android/testproject. 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)
+
+
+
+
+================================================================================
+ Known issues
+================================================================================
+
+- SDL audio (although it's mostly written, just not working properly yet)
+- TODO. I'm sure there's a bunch more stuff I haven't thought of 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/config.cfg	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,1 @@
+ANDROID_NDK=/home/paul/Projects/gsoc/sdk/android-ndk-r4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/AndroidManifest.xml	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,15 @@
+<?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> 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/build.properties	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,17 @@
+# 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.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/build.xml	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,67 @@
+<?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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/default.properties	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,11 @@
+# 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-7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/jni/Android.mk	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,18 @@
+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)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/jni/android-support.cpp	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ 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();
+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);
+
+    SDL_main();
+}
+
+//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");
+    
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/jni/lesson05.c	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,574 @@
+/*
+ * 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 );
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/local.properties	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,10 @@
+# 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/res/layout/main.xml	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,13 @@
+<?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>
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/res/values/strings.xml	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">SDLActivity</string>
+</resources>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/project/src/org/libsdl/app/SDLActivity.java	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,388 @@
+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] );
+        }
+    }
+
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/scripts/acc.sh	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,15 @@
+#!/bin/bash
+ANDROID_NDK="/home/paul/Projects/gsoc/sdk/android-ndk-r4"
+TOOLS_PATH="$ANDROID_NDK/build/prebuilt/linux-x86/arm-eabi-4.2.1/bin"
+
+export PATH=$TOOLS_PATH:$PATH
+
+CC="arm-eabi-gcc"
+
+#cflags
+ACC_C="	-I$ANDROID_NDK/build/platforms/android-8/common/include \
+		-I$ANDROID_NDK/build/platforms/android-8/arch-arm/usr/include \
+		-DANDROID -DANDROID_NDK -c"
+		
+		
+$CC $CFLAGS $ACC_C $@
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/android/scripts/ald.sh	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,20 @@
+#!/bin/bash
+ANDROID_NDK="/home/paul/Projects/gsoc/sdk/android-ndk-r4"
+TOOLS_PATH="$ANDROID_NDK/build/prebuilt/linux-x86/arm-eabi-4.2.1/bin"
+ADDITIONAL_LIBS=`dirname "$0"`/android_libs/
+
+export PATH=$TOOLS_PATH:$PATH
+
+LD="arm-eabi-ld"
+
+#ldflags
+ACC_L="	-rpath-link=$ANDROID_NDK/build/platforms/android-8/arch-arm/usr/lib/ \
+		-dynamic-linker=/system/bin/linker \
+		-lc -nostdlib \
+ 		$ANDROID_NDK/build/platforms/android-8/arch-arm/usr/lib/crtbegin_static.o \
+ 		-L$ANDROID_NDK/build/platforms/android-8/arch-arm/usr/lib/ \
+ 		-L$ANDROID_NDK/build/prebuilt/linux-x86/arm-eabi-4.2.1/lib/gcc/arm-eabi/4.2.1 \
+ 		-L$ADDITIONAL_LIBS "
+		
+$LD $ACC_L $LDFLAGS $@ -lgcc
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/SDL_config_android.h	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,145 @@
+/*
+    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
+*/
+
+#ifndef _SDL_config_android_h
+#define _SDL_config_android_h
+
+#include "SDL_platform.h"
+
+/**
+ *  \file SDL_config_android.h
+ *  
+ *  This is a configuration that can be used to build SDL for Android
+ */
+
+#include <stdarg.h>
+
+/*
+typedef signed char int8_t;
+typedef unsigned char uint8_t;
+typedef signed short int16_t;
+typedef unsigned short uint16_t;
+typedef signed int int32_t;
+typedef unsigned int uint32_t;
+*/
+
+
+#define HAVE_ALLOCA_H		1
+#define HAVE_SYS_TYPES_H	1
+#define HAVE_STDIO_H	1
+#define STDC_HEADERS	1
+#define HAVE_STRING_H	1
+#define HAVE_INTTYPES_H	1
+#define HAVE_STDINT_H	1
+#define HAVE_CTYPE_H	1
+#define HAVE_MATH_H	1
+#define HAVE_SIGNAL_H	1
+
+/* C library functions */
+#define HAVE_MALLOC	1
+#define HAVE_CALLOC	1
+#define HAVE_REALLOC	1
+#define HAVE_FREE	1
+#define HAVE_ALLOCA	1
+#define HAVE_GETENV	1
+#define HAVE_SETENV	1
+#define HAVE_PUTENV	1
+#define HAVE_SETENV	1
+#define HAVE_UNSETENV	1
+#define HAVE_QSORT	1
+#define HAVE_ABS	1
+#define HAVE_BCOPY	1
+#define HAVE_MEMSET	1
+#define HAVE_MEMCPY	1
+#define HAVE_MEMMOVE	1
+#define HAVE_MEMCMP	1
+#define HAVE_STRLEN	1
+#define HAVE_STRLCPY	1
+#define HAVE_STRLCAT	1
+#define HAVE_STRDUP	1
+#define HAVE_STRCHR	1
+#define HAVE_STRRCHR	1
+#define HAVE_STRSTR	1
+#define HAVE_STRTOL	1
+#define HAVE_STRTOUL	1
+#define HAVE_STRTOLL	1
+#define HAVE_STRTOULL	1
+#define HAVE_STRTOD	1
+#define HAVE_ATOI	1
+#define HAVE_ATOF	1
+#define HAVE_STRCMP	1
+#define HAVE_STRNCMP	1
+#define HAVE_STRCASECMP	1
+#define HAVE_STRNCASECMP 1
+#define HAVE_SSCANF	1
+#define HAVE_SNPRINTF	1
+#define HAVE_VSNPRINTF	1
+#define HAVE_CEIL	1
+#define HAVE_COPYSIGN	1
+#define HAVE_COS	1
+#define HAVE_COSF	1
+#define HAVE_FABS	1
+#define HAVE_FLOOR	1
+#define HAVE_LOG	1
+#define HAVE_POW	1
+#define HAVE_SCALBN	1
+#define HAVE_SIN	1
+#define HAVE_SINF	1
+#define HAVE_SQRT	1
+#define HAVE_SIGACTION	1
+#define HAVE_SETJMP	1
+#define HAVE_NANOSLEEP	1
+#define HAVE_SYSCONF	1
+
+#define SIZEOF_VOIDP 4
+
+typedef unsigned int size_t;
+//typedef unsigned long uintptr_t;
+
+#define SDL_AUDIO_DRIVER_ANDROID	1
+
+#define SDL_CDROM_DISABLED 1
+
+#define SDL_HAPTIC_DISABLED 1
+
+#define SDL_JOYSTICK_ANDROID 1
+
+#define SDL_LOADSO_DISABLED 1
+
+/* Enable various threading systems */
+#define SDL_THREAD_PTHREAD	1
+#define SDL_THREAD_PTHREAD_RECURSIVE_MUTEX	1
+
+/* Enable various timer systems */
+#define SDL_TIMER_UNIX	1
+
+#define SDL_VIDEO_DRIVER_ANDROID 1
+
+#define HAVE_STDIO_H 1
+#define HAVE_SYS_TYPES_H 1
+
+#define HAVE_M_PI 1
+
+#define SDL_VIDEO_RENDER_OGL_ES 1
+
+#endif /* _SDL_config_minimal_h */
+
--- a/include/SDL_platform.h	Sun Aug 22 12:07:55 2010 -0700
+++ b/include/SDL_platform.h	Sun Aug 22 12:23:55 2010 -0700
@@ -65,6 +65,11 @@
 #undef __LINUX__
 #define __LINUX__	1
 #endif
+#if defined(ANDROID)
+#undef __ANDROID__
+#undef __LINUX__ /*do we need to do this?*/
+#define __ANDROID__ 1
+#endif
 
 #if defined(__APPLE__)
 /* lets us know what version of Mac OS X we're compiling on */
--- a/include/SDL_stdinc.h	Sun Aug 22 12:07:55 2010 -0700
+++ b/include/SDL_stdinc.h	Sun Aug 22 12:23:55 2010 -0700
@@ -174,9 +174,10 @@
 SDL_COMPILE_TIME_ASSERT(sint16, sizeof(Sint16) == 2);
 SDL_COMPILE_TIME_ASSERT(uint32, sizeof(Uint32) == 4);
 SDL_COMPILE_TIME_ASSERT(sint32, sizeof(Sint32) == 4);
-#ifndef __NINTENDODS__          /* TODO: figure out why the following happens:
-                                   include/SDL_stdinc.h:150: error: size of array 'SDL_dummy_uint64' is negative
-                                   include/SDL_stdinc.h:151: error: size of array 'SDL_dummy_sint64' is negative */
+#if !defined(__NINTENDODS__) && !defined(__ANDROID__)
+/* TODO: figure out why the following happens:
+ include/SDL_stdinc.h:150: error: size of array 'SDL_dummy_uint64' is negative
+ include/SDL_stdinc.h:151: error: size of array 'SDL_dummy_sint64' is negative */
 SDL_COMPILE_TIME_ASSERT(uint64, sizeof(Uint64) == 8);
 SDL_COMPILE_TIME_ASSERT(sint64, sizeof(Sint64) == 8);
 #endif
@@ -195,7 +196,8 @@
 
 /** \cond */
 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
-#ifndef __NINTENDODS__          /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */
+#if !defined(__NINTENDODS__) && !defined(__ANDROID__) 
+   /* TODO: include/SDL_stdinc.h:174: error: size of array 'SDL_dummy_enum' is negative */
 typedef enum
 {
     DUMMY_ENUM_VALUE
--- a/src/SDL_compat.c	Sun Aug 22 12:07:55 2010 -0700
+++ b/src/SDL_compat.c	Sun Aug 22 12:23:55 2010 -0700
@@ -639,18 +639,29 @@
 
     /* If we're in OpenGL mode, just create a stub surface and we're done! */
     if (flags & SDL_OPENGL) {
+        
+       printf("1\n");
+    
         SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow);
         if (!SDL_VideoContext) {
             return NULL;
         }
+
+        
+    printf("2\n");
+    
         if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) {
             return NULL;
         }
+        
+    printf("3\n");
         SDL_VideoSurface =
             SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0);
         if (!SDL_VideoSurface) {
             return NULL;
         }
+        
+    printf("4\n");
         SDL_VideoSurface->flags |= surface_flags;
         SDL_PublicSurface = SDL_VideoSurface;
         return SDL_PublicSurface;
--- a/src/audio/SDL_audio.c	Sun Aug 22 12:07:55 2010 -0700
+++ b/src/audio/SDL_audio.c	Sun Aug 22 12:23:55 2010 -0700
@@ -69,6 +69,7 @@
 extern AudioBootStrap DART_bootstrap;
 extern AudioBootStrap NDSAUD_bootstrap;
 extern AudioBootStrap FUSIONSOUND_bootstrap;
+extern AudioBootStrap ANDROIDAUD_bootstrap;
 
 
 /* Available audio drivers */
@@ -137,6 +138,9 @@
 #if SDL_AUDIO_DRIVER_FUSIONSOUND
     &FUSIONSOUND_bootstrap,
 #endif
+#if SDL_AUDIO_DRIVER_ANDROID
+    &ANDROIDAUD_bootstrap,
+#endif
     NULL
 };
 
@@ -318,6 +322,8 @@
 }
 
 
+#include <android/log.h>
+
 /* The general mixing thread function */
 int SDLCALL
 SDL_RunAudio(void *devicep)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/android/SDL_androidaudio.c	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,140 @@
+/*
+    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
+
+    This file written by Ryan C. Gordon (icculus@icculus.org)
+*/
+#include "SDL_config.h"
+
+/* Output audio to Android */
+
+#include "SDL_audio.h"
+#include "../SDL_audio_c.h"
+#include "SDL_androidaudio.h"
+
+extern void Android_UpdateAudioBuffer(unsigned char *buf, int len);
+
+#include <android/log.h>
+
+static int
+AndroidAUD_OpenDevice(_THIS, const char *devname, int iscapture)
+{
+    SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
+    int valid_datatype = 0;
+    
+    //TODO: Sample rates etc
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "AndroidAudio Open\n");
+
+    this->hidden = SDL_malloc(sizeof(*(this->hidden)));
+    if (!this->hidden) {
+        SDL_OutOfMemory();
+        return 0;
+    }
+    SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
+    while ((!valid_datatype) && (test_format)) {
+        this->spec.format = test_format;
+        switch (test_format) {
+        case AUDIO_S8:
+            /*case AUDIO_S16LSB: */
+            valid_datatype = 1;
+            break;
+        default:
+            test_format = SDL_NextAudioFormat();
+            break;
+        }
+    }
+    
+    return 1;
+}
+
+static void
+AndroidAUD_PlayDevice(_THIS)
+{
+    __android_log_print(ANDROID_LOG_INFO, "SDL", "AndroidAudio Play\n");
+    
+
+    //playGenericSound(this->hidden->mixbuf, this->hidden->mixlen);
+    
+#if 0
+
+//    sound->rate = 22050; /* sample rate = 22050Hz */
+//    sound->vol = 127;    /* volume [0..127] for [min..max] */
+//    sound->pan = 64;     /* balance [0..127] for [left..right] */
+//    sound->format = 0;   /* 0 for 16-bit, 1 for 8-bit */
+//    playSound(sound);
+#endif
+}
+
+
+static Uint8 *
+AndroidAUD_GetDeviceBuf(_THIS)
+{
+     //__android_log_print(ANDROID_LOG_INFO, "SDL", "****** get device buf\n");
+
+     
+    //    sound->data = this->hidden->mixbuf;/* pointer to raw audio data */
+//    sound->len = this->hidden->mixlen; /* size of raw data pointed to above */
+
+
+    Android_UpdateAudioBuffer(this->hidden->mixbuf, this->hidden->mixlen);
+    
+    return this->hidden->mixbuf;        /* is this right? */
+}
+
+static void
+AndroidAUD_WaitDevice(_THIS)
+{
+    /* stub */
+     __android_log_print(ANDROID_LOG_INFO, "SDL", "****** wait device buf\n");
+}
+
+static void
+AndroidAUD_CloseDevice(_THIS)
+{
+    /* stub */
+     __android_log_print(ANDROID_LOG_INFO, "SDL", "****** close device buf\n");
+}
+
+static int
+AndroidAUD_Init(SDL_AudioDriverImpl * impl)
+{
+    /* Set the function pointers */
+    impl->OpenDevice = AndroidAUD_OpenDevice;
+    impl->PlayDevice = AndroidAUD_PlayDevice;
+    impl->WaitDevice = AndroidAUD_WaitDevice;
+    impl->GetDeviceBuf = AndroidAUD_GetDeviceBuf;
+    impl->CloseDevice = AndroidAUD_CloseDevice;
+
+    /* and the capabilities */
+    impl->HasCaptureSupport = 0; //TODO
+    impl->OnlyHasDefaultOutputDevice = 1;
+    impl->OnlyHasDefaultInputDevice = 1;
+
+    __android_log_print(ANDROID_LOG_INFO, "SDL","Audio init\n");
+
+    return 1;   /* this audio target is available. */
+}
+
+AudioBootStrap ANDROIDAUD_bootstrap = {
+    "android", "SDL Android audio driver", AndroidAUD_Init, 0       /*1? */
+};
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/audio/android/SDL_androidaudio.h	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,42 @@
+/*
+    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"
+
+#ifndef _SDL_androidaudio_h
+#define _SDL_androidaudio_h
+
+#include "../SDL_sysaudio.h"
+
+/* Hidden "this" pointer for the audio functions */
+#define _THIS	SDL_AudioDevice *this
+
+struct SDL_PrivateAudioData
+{
+    /* The file descriptor for the audio device */
+    Uint8 *mixbuf;
+    Uint32 mixlen;
+    Uint32 write_delay;
+    Uint32 initial_calls;
+};
+
+#endif /* _SDL_androidaudio_h */
+/* vi: set ts=4 sw=4 expandtab: */
--- a/src/events/SDL_events.c	Sun Aug 22 12:07:55 2010 -0700
+++ b/src/events/SDL_events.c	Sun Aug 22 12:23:55 2010 -0700
@@ -92,11 +92,13 @@
 static __inline__ SDL_bool
 SDL_ShouldPollJoystick()
 {
+#if !SDL_JOYSTICK_DISABLED
     if (SDL_numjoysticks &&
         (!SDL_disabled_events[SDL_JOYAXISMOTION >> 8] ||
          SDL_JoystickEventState(SDL_QUERY))) {
         return SDL_TRUE;
     }
+#endif
     return SDL_FALSE;
 }
 
--- a/src/events/SDL_keyboard.c	Sun Aug 22 12:07:55 2010 -0700
+++ b/src/events/SDL_keyboard.c	Sun Aug 22 12:23:55 2010 -0700
@@ -729,7 +729,7 @@
         break;
     default:
         /* Invalid state -- bail */
-        return 0;
+        return 2;
     }
 
     /* Drop events that don't change state */
@@ -738,14 +738,14 @@
 #if 0
         printf("Keyboard event didn't change state - dropped!\n");
 #endif
-        return 0;
+        return 3;
     }
 
     /* Update internal keyboard state */
     keyboard->keystate[scancode] = state;
 
     /* Post the event, if desired */
-    posted = 0;
+    posted = 4;
     if (SDL_GetEventState(type) == SDL_ENABLE) {
         SDL_Event event;
         event.key.type = type;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/joystick/android/SDL_sysjoystick.c	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,106 @@
+/*
+    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"
+
+#ifdef SDL_JOYSTICK_ANDROID
+
+/* This is the system specific header for the SDL joystick API */
+#include <stdio.h>              /* For the definition of NULL */
+
+#include "SDL_error.h"
+#include "SDL_events.h"
+#include "SDL_joystick.h"
+#include "../SDL_sysjoystick.h"
+#include "../SDL_joystick_c.h"
+
+extern float fLastAccelerometer[3];
+
+const char *accelerometerName = "Android accelerometer";
+
+/* Function to scan the system for joysticks.
+ * This function should set SDL_numjoysticks to the number of available
+ * joysticks.  Joystick 0 should be the system default joystick.
+ * It should return 0, or -1 on an unrecoverable fatal error.
+ */
+int
+SDL_SYS_JoystickInit(void)
+{
+    SDL_numjoysticks = 1;
+    
+return (1);
+}
+
+/* Function to get the device-dependent name of a joystick */
+const char *
+SDL_SYS_JoystickName(int index)
+{
+    if (!index)
+        return accelerometerName;
+    SDL_SetError("No joystick available with that index");
+    return (NULL);
+}
+
+/* Function to open a joystick for use.
+   The joystick to open is specified by the index field of the joystick.
+   This should fill the nbuttons and naxes fields of the joystick structure.
+   It returns 0, or -1 if there is an error.
+ */
+int
+SDL_SYS_JoystickOpen(SDL_Joystick * joystick)
+{
+    joystick->nbuttons = 0;
+    joystick->nhats = 0;
+    joystick->nballs = 0;
+    joystick->naxes = 3;
+    joystick->name = accelerometerName;
+    return 0;
+}
+
+
+/* Function to update the state of a joystick - called as a device poll.
+ * This function shouldn't update the joystick structure directly,
+ * but instead should call SDL_PrivateJoystick*() to deliver events
+ * and update joystick device state.
+ */
+    void
+SDL_SYS_JoystickUpdate(SDL_Joystick * joystick)
+{
+    int i=0; 
+    for(i=0;i<3;i++){
+        SDL_PrivateJoystickAxis(joystick, i, fLastAccelerometer[i]);
+    }
+}
+
+/* Function to close a joystick after use */
+void
+SDL_SYS_JoystickClose(SDL_Joystick * joystick)
+{
+}
+
+/* Function to perform any system-specific joystick related cleanup */
+void
+SDL_SYS_JoystickQuit(void)
+{
+}
+
+#endif /* SDL_JOYSTICK_NDS */
--- a/src/video/SDL_sysvideo.h	Sun Aug 22 12:07:55 2010 -0700
+++ b/src/video/SDL_sysvideo.h	Sun Aug 22 12:23:55 2010 -0700
@@ -417,6 +417,9 @@
 #if SDL_VIDEO_DRIVER_PANDORA
 extern VideoBootStrap PND_bootstrap;
 #endif
+#if SDL_VIDEO_DRIVER_ANDROID
+extern VideoBootStrap Android_bootstrap;
+#endif
 
 #define SDL_CurrentDisplay	(&_this->displays[_this->current_display])
 #define SDL_CurrentRenderer	(SDL_CurrentDisplay->current_renderer)
--- a/src/video/SDL_video.c	Sun Aug 22 12:07:55 2010 -0700
+++ b/src/video/SDL_video.c	Sun Aug 22 12:23:55 2010 -0700
@@ -97,6 +97,9 @@
 #if SDL_VIDEO_DRIVER_PANDORA
     &PND_bootstrap,
 #endif
+#if SDL_VIDEO_DRIVER_ANDROID
+    &Android_bootstrap,
+#endif
     NULL
 };
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/android/SDL_androidevents.c	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,85 @@
+/*
+    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"
+
+/* Being a null driver, there's no event stream. We just define stubs for
+   most of the API. */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "../../events/SDL_sysevents.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_androidevents.h"
+
+void Android_InitEvents(){
+
+    SDL_Keyboard keyboard;
+
+    SDL_zero(keyboard);
+    SDL_AddKeyboard(&keyboard, -1);
+
+    SDLKey keymap[SDL_NUM_SCANCODES];
+
+    /* Add default scancode to key mapping */
+    SDL_GetDefaultKeymap(keymap);
+    SDL_SetKeymap(0, 0, keymap, SDL_NUM_SCANCODES);
+
+
+}
+
+void
+Android_PumpEvents(_THIS)
+{
+
+    //scanKeys();
+    /* TODO: defer click-age */
+    /*
+    if (keysDown() & KEY_TOUCH) {
+        SDL_SendMouseButton(0, SDL_PRESSED, 0);
+    } else if (keysUp() & KEY_TOUCH) {
+        SDL_SendMouseButton(0, SDL_RELEASED, 0);
+    }
+    if (keysHeld() & KEY_TOUCH) {
+        touchPosition t = touchReadXY();
+        SDL_SendMouseMotion(0, 0, t.px, t.py, 1);       
+    }
+    */
+}
+
+
+void Android_OnResize(int width, int height, int format){
+
+}
+
+int
+Android_OnKeyDown(int keycode){
+    return SDL_SendKeyboardKey(0, SDL_PRESSED, (SDL_scancode)keycode);
+}
+
+int
+Android_OnKeyUp(int keycode){
+    return SDL_SendKeyboardKey(0, SDL_RELEASED, (SDL_scancode)keycode);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/android/SDL_androidevents.h	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,29 @@
+/*
+    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"
+
+#include "SDL_androidvideo.h"
+
+extern void Android_PumpEvents(_THIS);
+extern void Android_InitEvents();
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/android/SDL_androidgl.c	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,96 @@
+/*
+    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"
+
+/* Android SDL video driver implementation
+*/
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_androidvideo.h"
+#include "SDL_androidevents.h"
+#include "SDL_androidrender.h"
+
+#include <android/log.h>
+
+#include <pthread.h>
+
+/*
+These things are in the JNI android support
+*/
+extern void Android_CreateContext();
+extern void Android_Render();
+
+/* GL functions */
+int Android_GL_LoadLibrary(_THIS, const char *path){
+	__android_log_print(ANDROID_LOG_INFO, "SDL", "[STUB] GL_LoadLibrary\n");
+	return 0;
+}
+
+void *Android_GL_GetProcAddress(_THIS, const char *proc){
+	__android_log_print(ANDROID_LOG_INFO, "SDL", "[STUB] GL_GetProcAddress\n");
+	return 0;
+}
+
+void Android_GL_UnloadLibrary(_THIS){
+	__android_log_print(ANDROID_LOG_INFO, "SDL", "[STUB] GL_UnloadLibrary\n");
+}
+
+/*
+int *Android_GL_GetVisual(_THIS, Display * display, int screen){
+	__android_log_print(ANDROID_LOG_INFO, "SDL","[STUB] GL_GetVisual\n");
+	return 0;
+}
+*/
+
+SDL_GLContext Android_GL_CreateContext(_THIS, SDL_Window * window){
+	Android_CreateContext();
+	return 1;
+}
+
+int Android_GL_MakeCurrent(_THIS, SDL_Window * window,
+                              SDL_GLContext context){
+	__android_log_print(ANDROID_LOG_INFO, "SDL", "[STUB] GL_MakeCurrent\n");
+	return 0;
+}
+
+int Android_GL_SetSwapInterval(_THIS, int interval){
+	__android_log_print(ANDROID_LOG_INFO, "SDL", "[STUB] GL_SetSwapInterval\n");
+	return 0;
+}
+
+int Android_GL_GetSwapInterval(_THIS){
+	__android_log_print(ANDROID_LOG_INFO, "SDL", "[STUB] GL_GetSwapInterval\n");
+	return 0;
+}
+
+void Android_GL_SwapWindow(_THIS, SDL_Window * window){
+	Android_Render();
+}
+
+void Android_GL_DeleteContext(_THIS, SDL_GLContext context){
+	__android_log_print(ANDROID_LOG_INFO, "SDL", "[STUB] GL_DeleteContext\n");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/android/SDL_androidrender.c	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,344 @@
+/*
+    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"
+
+#include "SDL_video.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_yuv_sw_c.h"
+#include "../SDL_renderer_sw.h"
+
+
+/* SDL surface based renderer implementation */
+
+static SDL_Renderer *Android_CreateRenderer(SDL_Window * window,
+                                              Uint32 flags);
+static int Android_RenderDrawPoints(SDL_Renderer * renderer,
+                                      const SDL_Point * points, int count);
+static int Android_RenderDrawLines(SDL_Renderer * renderer,
+                                     const SDL_Point * points, int count);
+static int Android_RenderDrawRects(SDL_Renderer * renderer,
+                                     const SDL_Rect ** rects, int count);
+static int Android_RenderFillRects(SDL_Renderer * renderer,
+                                     const SDL_Rect ** rects, int count);
+static int Android_RenderCopy(SDL_Renderer * renderer,
+                                SDL_Texture * texture,
+                                const SDL_Rect * srcrect,
+                                const SDL_Rect * dstrect);
+static int Android_RenderReadPixels(SDL_Renderer * renderer,
+                                      const SDL_Rect * rect,
+                                      Uint32 format,
+                                      void * pixels, int pitch);
+static int Android_RenderWritePixels(SDL_Renderer * renderer,
+                                       const SDL_Rect * rect,
+                                       Uint32 format,
+                                       const void * pixels, int pitch);
+static void Android_RenderPresent(SDL_Renderer * renderer);
+static void Android_DestroyRenderer(SDL_Renderer * renderer);
+
+
+SDL_RenderDriver Android_RenderDriver = {
+    Android_CreateRenderer,
+    {
+     "dummy",
+     (SDL_RENDERER_SINGLEBUFFER | SDL_RENDERER_PRESENTCOPY |
+      SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
+      SDL_RENDERER_PRESENTDISCARD),
+     }
+};
+
+typedef struct
+{
+    int current_screen;
+    SDL_Surface *screens[3];
+} Android_RenderData;
+
+SDL_Renderer *
+Android_CreateRenderer(SDL_Window * window, Uint32 flags)
+{
+    SDL_VideoDisplay *display = window->display;
+    SDL_DisplayMode *displayMode = &display->current_mode;
+    SDL_Renderer *renderer;
+    Android_RenderData *data;
+    int i, n;
+    int bpp;
+    Uint32 Rmask, Gmask, Bmask, Amask;
+
+    if (!SDL_PixelFormatEnumToMasks
+        (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) {
+        SDL_SetError("Unknown display format");
+        return NULL;
+    }
+
+    renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
+    if (!renderer) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
+    data = (Android_RenderData *) SDL_malloc(sizeof(*data));
+    if (!data) {
+        Android_DestroyRenderer(renderer);
+        SDL_OutOfMemory();
+        return NULL;
+    }
+    SDL_zerop(data);
+
+    renderer->RenderDrawPoints = Android_RenderDrawPoints;
+    renderer->RenderDrawLines = Android_RenderDrawLines;
+    renderer->RenderDrawRects = Android_RenderDrawRects;
+    renderer->RenderFillRects = Android_RenderFillRects;
+    renderer->RenderCopy = Android_RenderCopy;
+    renderer->RenderReadPixels = Android_RenderReadPixels;
+    renderer->RenderWritePixels = Android_RenderWritePixels;
+    renderer->RenderPresent = Android_RenderPresent;
+    renderer->DestroyRenderer = Android_DestroyRenderer;
+    renderer->info.name = Android_RenderDriver.info.name;
+    renderer->info.flags = 0;
+    renderer->window = window;
+    renderer->driverdata = data;
+    Setup_SoftwareRenderer(renderer);
+
+    if (flags & SDL_RENDERER_PRESENTFLIP2) {
+        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
+        n = 2;
+    } else if (flags & SDL_RENDERER_PRESENTFLIP3) {
+        renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
+        n = 3;
+    } else {
+        renderer->info.flags |= SDL_RENDERER_PRESENTCOPY;
+        n = 1;
+    }
+    for (i = 0; i < n; ++i) {
+        data->screens[i] =
+            SDL_CreateRGBSurface(0, window->w, window->h, bpp, Rmask, Gmask,
+                                 Bmask, Amask);
+        if (!data->screens[i]) {
+            Android_DestroyRenderer(renderer);
+            return NULL;
+        }
+        SDL_SetSurfacePalette(data->screens[i], display->palette);
+    }
+    data->current_screen = 0;
+
+    return renderer;
+}
+
+static int
+Android_RenderDrawPoints(SDL_Renderer * renderer,
+                           const SDL_Point * points, int count)
+{
+    Android_RenderData *data =
+        (Android_RenderData *) renderer->driverdata;
+    SDL_Surface *target = data->screens[data->current_screen];
+
+    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
+        renderer->blendMode == SDL_BLENDMODE_MASK) {
+        Uint32 color = SDL_MapRGBA(target->format,
+                                   renderer->r, renderer->g, renderer->b,
+                                   renderer->a);
+
+        return SDL_DrawPoints(target, points, count, color);
+    } else {
+        return SDL_BlendPoints(target, points, count, renderer->blendMode,
+                               renderer->r, renderer->g, renderer->b,
+                               renderer->a);
+    }
+}
+
+static int
+Android_RenderDrawLines(SDL_Renderer * renderer,
+                          const SDL_Point * points, int count)
+{
+    Android_RenderData *data =
+        (Android_RenderData *) renderer->driverdata;
+    SDL_Surface *target = data->screens[data->current_screen];
+
+    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
+        renderer->blendMode == SDL_BLENDMODE_MASK) {
+        Uint32 color = SDL_MapRGBA(target->format,
+                                   renderer->r, renderer->g, renderer->b,
+                                   renderer->a);
+
+        return SDL_DrawLines(target, points, count, color);
+    } else {
+        return SDL_BlendLines(target, points, count, renderer->blendMode,
+                              renderer->r, renderer->g, renderer->b,
+                              renderer->a);
+    }
+}
+
+static int
+Android_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
+                          int count)
+{
+    Android_RenderData *data =
+        (Android_RenderData *) renderer->driverdata;
+    SDL_Surface *target = data->screens[data->current_screen];
+
+    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
+        renderer->blendMode == SDL_BLENDMODE_MASK) {
+        Uint32 color = SDL_MapRGBA(target->format,
+                                   renderer->r, renderer->g, renderer->b,
+                                   renderer->a);
+
+        return SDL_DrawRects(target, rects, count, color);
+    } else {
+        return SDL_BlendRects(target, rects, count,
+                              renderer->blendMode,
+                              renderer->r, renderer->g, renderer->b,
+                              renderer->a);
+    }
+}
+
+static int
+Android_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect ** rects,
+                          int count)
+{
+    Android_RenderData *data =
+        (Android_RenderData *) renderer->driverdata;
+    SDL_Surface *target = data->screens[data->current_screen];
+
+    if (renderer->blendMode == SDL_BLENDMODE_NONE ||
+        renderer->blendMode == SDL_BLENDMODE_MASK) {
+        Uint32 color = SDL_MapRGBA(target->format,
+                                   renderer->r, renderer->g, renderer->b,
+                                   renderer->a);
+
+        return SDL_FillRects(target, rects, count, color);
+    } else {
+        return SDL_BlendFillRects(target, rects, count,
+                                  renderer->blendMode,
+                                  renderer->r, renderer->g, renderer->b,
+                                  renderer->a);
+    }
+}
+
+static int
+Android_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
+                     const SDL_Rect * srcrect, const SDL_Rect * dstrect)
+{
+    Android_RenderData *data =
+        (Android_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+    SDL_VideoDisplay *display = window->display;
+
+    if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
+        SDL_Surface *target = data->screens[data->current_screen];
+        void *pixels =
+            (Uint8 *) target->pixels + dstrect->y * target->pitch +
+            dstrect->x * target->format->BytesPerPixel;
+        return SDL_SW_CopyYUVToRGB((SDL_SW_YUVTexture *) texture->driverdata,
+                                   srcrect, display->current_mode.format,
+                                   dstrect->w, dstrect->h, pixels,
+                                   target->pitch);
+    } else {
+        SDL_Surface *surface = (SDL_Surface *) texture->driverdata;
+        SDL_Surface *target = data->screens[data->current_screen];
+        SDL_Rect real_srcrect = *srcrect;
+        SDL_Rect real_dstrect = *dstrect;
+
+        return SDL_LowerBlit(surface, &real_srcrect, target, &real_dstrect);
+    }
+}
+
+static int
+Android_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                           Uint32 format, void * pixels, int pitch)
+{
+    Android_RenderData *data =
+        (Android_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+    SDL_VideoDisplay *display = window->display;
+    SDL_Surface *screen = data->screens[data->current_screen];
+    Uint32 screen_format = display->current_mode.format;
+    Uint8 *screen_pixels = (Uint8 *) screen->pixels +
+                            rect->y * screen->pitch +
+                            rect->x * screen->format->BytesPerPixel;
+    int screen_pitch = screen->pitch;
+
+    return SDL_ConvertPixels(rect->w, rect->h,
+                             screen_format, screen_pixels, screen_pitch,
+                             format, pixels, pitch);
+}
+
+static int
+Android_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
+                            Uint32 format, const void * pixels, int pitch)
+{
+    Android_RenderData *data =
+        (Android_RenderData *) renderer->driverdata;
+    SDL_Window *window = renderer->window;
+    SDL_VideoDisplay *display = window->display;
+    SDL_Surface *screen = data->screens[data->current_screen];
+    Uint32 screen_format = display->current_mode.format;
+    Uint8 *screen_pixels = (Uint8 *) screen->pixels +
+                            rect->y * screen->pitch +
+                            rect->x * screen->format->BytesPerPixel;
+    int screen_pitch = screen->pitch;
+
+    return SDL_ConvertPixels(rect->w, rect->h,
+                             format, pixels, pitch,
+                             screen_format, screen_pixels, screen_pitch);
+}
+
+static void
+Android_RenderPresent(SDL_Renderer * renderer)
+{
+    static int frame_number;
+    Android_RenderData *data =
+        (Android_RenderData *) renderer->driverdata;
+
+    /* Send the data to the display */
+    if (SDL_getenv("SDL_VIDEO_DUMMY_SAVE_FRAMES")) {
+        char file[128];
+        SDL_snprintf(file, sizeof(file), "SDL_window%d-%8.8d.bmp",
+                     renderer->window->id, ++frame_number);
+        SDL_SaveBMP(data->screens[data->current_screen], file);
+    }
+
+    /* Update the flipping chain, if any */
+    if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP2) {
+        data->current_screen = (data->current_screen + 1) % 2;
+    } else if (renderer->info.flags & SDL_RENDERER_PRESENTFLIP3) {
+        data->current_screen = (data->current_screen + 1) % 3;
+    }
+}
+
+static void
+Android_DestroyRenderer(SDL_Renderer * renderer)
+{
+    Android_RenderData *data =
+        (Android_RenderData *) renderer->driverdata;
+    int i;
+
+    if (data) {
+        for (i = 0; i < SDL_arraysize(data->screens); ++i) {
+            if (data->screens[i]) {
+                SDL_FreeSurface(data->screens[i]);
+            }
+        }
+        SDL_free(data);
+    }
+    SDL_free(renderer);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/android/SDL_androidrender.h	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,28 @@
+/*
+    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"
+
+/* SDL surface based renderer implementation */
+
+extern SDL_RenderDriver Android_RenderDriver;
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/android/SDL_androidvideo.c	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,166 @@
+/*
+    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"
+
+/* Android SDL video driver implementation
+*/
+
+#include "SDL_video.h"
+#include "SDL_mouse.h"
+#include "../SDL_sysvideo.h"
+#include "../SDL_pixels_c.h"
+#include "../../events/SDL_events_c.h"
+
+#include "SDL_androidvideo.h"
+#include "SDL_androidevents.h"
+#include "SDL_androidrender.h"
+
+#define ANDROID_VID_DRIVER_NAME "Android"
+
+/* Initialization/Query functions */
+static int Android_VideoInit(_THIS);
+static int Android_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode);
+static void Android_VideoQuit(_THIS);
+
+/* GL functions (SDL_androidgl.c) */
+extern int Android_GL_LoadLibrary(_THIS, const char *path);
+extern void *Android_GL_GetProcAddress(_THIS, const char *proc);
+extern void Android_GL_UnloadLibrary(_THIS);
+//extern int *Android_GL_GetVisual(_THIS, Display * display, int screen);
+extern SDL_GLContext Android_GL_CreateContext(_THIS, SDL_Window * window);
+extern int Android_GL_MakeCurrent(_THIS, SDL_Window * window,
+                              SDL_GLContext context);
+extern int Android_GL_SetSwapInterval(_THIS, int interval);
+extern int Android_GL_GetSwapInterval(_THIS);
+extern void Android_GL_SwapWindow(_THIS, SDL_Window * window);
+extern void Android_GL_DeleteContext(_THIS, SDL_GLContext context);
+
+/* Android driver bootstrap functions */
+
+
+//These are filled in with real values in Android_SetScreenResolution on 
+//init (before SDL_Main())
+static int iScreenWidth = 320;
+static int iScreenHeight = 240;
+
+
+static int
+Android_Available(void)
+{
+    return 1;
+}
+
+static void
+Android_DeleteDevice(SDL_VideoDevice * device)
+{
+    SDL_free(device);
+}
+
+static SDL_VideoDevice *
+Android_CreateDevice(int devindex)
+{
+    printf("Creating video device\n");
+    SDL_VideoDevice *device;
+
+    /* Initialize all variables that we clean on shutdown */
+    device = (SDL_VideoDevice *) SDL_calloc(1, sizeof(SDL_VideoDevice));
+    if (!device) {
+        SDL_OutOfMemory();
+        if (device) {
+            SDL_free(device);
+        }
+        return (0);
+    }
+
+    /* Set the function pointers */
+    device->VideoInit = Android_VideoInit;
+    device->VideoQuit = Android_VideoQuit;
+    device->SetDisplayMode = Android_SetDisplayMode;
+    device->PumpEvents = Android_PumpEvents;
+   
+    device->free = Android_DeleteDevice;
+
+    /* GL pointers */
+    device->GL_LoadLibrary = Android_GL_LoadLibrary;
+    device->GL_GetProcAddress = Android_GL_GetProcAddress;
+    device->GL_UnloadLibrary = Android_GL_UnloadLibrary;
+    device->GL_CreateContext = Android_GL_CreateContext;
+    device->GL_MakeCurrent = Android_GL_MakeCurrent;
+    device->GL_SetSwapInterval = Android_GL_SetSwapInterval;
+    device->GL_GetSwapInterval = Android_GL_GetSwapInterval;
+    device->GL_SwapWindow = Android_GL_SwapWindow;
+    device->GL_DeleteContext = Android_GL_DeleteContext;
+
+    return device;
+}
+
+VideoBootStrap Android_bootstrap = {
+    ANDROID_VID_DRIVER_NAME, "SDL Android video driver",
+    Android_Available, Android_CreateDevice
+};
+
+
+int
+Android_VideoInit(_THIS)
+{
+    SDL_DisplayMode mode;
+
+    /* Use a fake 32-bpp desktop mode */
+    mode.format = SDL_PIXELFORMAT_RGB888;
+    mode.w = iScreenWidth;
+    mode.h = iScreenHeight;
+    mode.refresh_rate = 0;
+    mode.driverdata = NULL;
+    if (SDL_AddBasicVideoDisplay(&mode) < 0) {
+        return -1;
+    }
+    SDL_AddRenderDriver(&_this->displays[0], &Android_RenderDriver);
+
+    SDL_zero(mode);
+    SDL_AddDisplayMode(&_this->displays[0], &mode);
+
+    Android_InitEvents();
+
+    /* We're done! */
+    return 0;
+}
+
+static int
+Android_SetDisplayMode(_THIS, SDL_VideoDisplay * display, SDL_DisplayMode * mode)
+{
+    return 0;
+}
+
+void
+Android_VideoQuit(_THIS)
+{
+}
+
+
+void Android_SetScreenResolution(int width, int height){
+    iScreenWidth = width;
+    iScreenHeight = height;   
+}
+
+
+
+/* vi: set ts=4 sw=4 expandtab: */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/android/SDL_androidvideo.h	Sun Aug 22 12:23:55 2010 -0700
@@ -0,0 +1,31 @@
+/*
+    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"
+
+#ifndef _SDL_androidvideo_h
+#define _SDL_androidvideo_h
+
+#include "../SDL_sysvideo.h"
+
+#endif /* _SDL_ndsvideo_h */
+
+/* vi: set ts=4 sw=4 expandtab: */