Added the Android project and lots of info to README.android
authorSam Lantinga <slouken@libsdl.org>
Thu, 06 Jan 2011 17:12:31 -0800
changeset 496591d0085b7560
parent 4964 6c645018741e
child 4966 a130bc2f0a18
Added the Android project and lots of info to README.android
README.android
android-project/AndroidManifest.xml
android-project/build.properties
android-project/build.xml
android-project/default.properties
android-project/jni/Android.mk
android-project/jni/src/Android.mk
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
     1.1 --- a/README.android	Thu Jan 06 16:11:21 2011 -0800
     1.2 +++ b/README.android	Thu Jan 06 17:12:31 2011 -0800
     1.3 @@ -2,8 +2,13 @@
     1.4  Simple DirectMedia Layer for Android
     1.5  ================================================================================
     1.6  
     1.7 -Requirements: Android SDK and Android NDK r4 or later
     1.8 -http://developer.android.com/
     1.9 +Requirements:
    1.10 +
    1.11 +Android SDK
    1.12 +http://developer.android.com/sdk/index.html
    1.13 +
    1.14 +Android NDK r4 or later
    1.15 +http://developer.android.com/sdk/ndk/index.html
    1.16  
    1.17  ================================================================================
    1.18   How the port works
    1.19 @@ -22,7 +27,7 @@
    1.20  ================================================================================
    1.21  
    1.22  Instructions:
    1.23 -1. Copy the android-project directory wherever you want your Android project to go
    1.24 +1. Copy the android-project directory wherever you want to keep your projects and rename it to the name of your project.
    1.25  2. Move this SDL directory into the <project>/jni directory
    1.26  3. Place your application source files in the <project>/jni/src directory
    1.27  4. Edit <project>/jni/src/Android.mk to include your source files
    1.28 @@ -35,16 +40,54 @@
    1.29  creates a .apk with the native code embedded
    1.30  8. 'ant install' will push the apk to the device or emulator (if connected)
    1.31  
    1.32 +Here's an explanation of the files in the Android project, so you can customize them:
    1.33 +
    1.34 +android-project/
    1.35 +	AndroidManifest.xml	- package manifest, do not modify
    1.36 +	build.properties	- empty
    1.37 +	build.xml		- build description file, used by ant
    1.38 +	default.properties	- holds the ABI for the application, currently android-4 which corresponds to the Android 1.6 system image
    1.39 +	local.properties	- holds the SDK path, you should change this to the path to your SDK
    1.40 +	jni/			- directory holding native code and Android.mk
    1.41 +	jni/Android.mk		- Android makefile that includes all subdirectories
    1.42 +	jni/SDL/		- directory holding the SDL library files
    1.43 +	jni/SDL/Android.mk	- Android makefile for creating the SDL shared library
    1.44 +	jni/src/		- directory holding your application source
    1.45 +	jni/src/Android.mk	- Android makefile that you should customize to include your source code and any library references
    1.46 +	res/			- directory holding resources for your application
    1.47 +	res/drawable-*		- directories holding icons for different phone hardware
    1.48 +	res/layout/main.xml	- place holder for the main screen layout, overridden by the SDL video output
    1.49 +	res/values/strings.xml	- strings used in your application, including the application name shown on the phone.
    1.50 +	src/org/libsdl/app/SDLActivity.java	- the Java class handling the initialization and binding to SDL.  Be very careful changing this, as the SDL library relies on this implementation.
    1.51 +
    1.52 +
    1.53 +================================================================================
    1.54 + Additional documentation
    1.55 +================================================================================
    1.56 +
    1.57 +The documentation in the NDK docs directory is very helpful in understanding the build process and how to work with native code on the Android platform.
    1.58 +
    1.59 +The best place to start is with docs/OVERVIEW.TXT
    1.60 +
    1.61  
    1.62  ================================================================================
    1.63   Using Eclipse
    1.64  ================================================================================
    1.65  
    1.66 -NEED CONTENT
    1.67 +First make sure that you've installed Eclipse and the Android extensions as described here:
    1.68 +	http://developer.android.com/sdk/eclipse-adt.html
    1.69 +
    1.70 +Once you've copied the SDL android project and customized it, you can create an Eclipse project from it:
    1.71 + * File -> New -> Other
    1.72 + * Select the Android -> Android Project wizard and click Next
    1.73 + * Enter the name you'd like your project to have
    1.74 + * Select "Create project from existing source" and browse for your project directory
    1.75 + * Make sure the Build Target is set to Android 1.6
    1.76 + * Click Finish
    1.77  
    1.78  
    1.79  ================================================================================
    1.80 - Loading files
    1.81 + Loading files and resources
    1.82  ================================================================================
    1.83  
    1.84  NEED CONTENT
    1.85 @@ -54,7 +97,20 @@
    1.86   Troubleshooting
    1.87  ================================================================================
    1.88  
    1.89 -NEED CONTENT
    1.90 +You can create and run an emulator from the Eclipse IDE:
    1.91 + * Window -> Android SDK and AVD Manager
    1.92 +
    1.93 +You can see if adb can see any devices with the following command:
    1.94 +	adb devices
    1.95 +
    1.96 +You can see the output of log messages on the default device with:
    1.97 +	adb logcat
    1.98 +
    1.99 +You can push files to the device with:
   1.100 +	adb push local_file remote_path_and_file
   1.101 +
   1.102 +You can push files to the SD Card at /sdcard, for example:
   1.103 +	adb push moose.dat /sdcard/moose.dat
   1.104  
   1.105  
   1.106  ================================================================================
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/android-project/AndroidManifest.xml	Thu Jan 06 17:12:31 2011 -0800
     2.3 @@ -0,0 +1,15 @@
     2.4 +<?xml version="1.0" encoding="utf-8"?>
     2.5 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     2.6 +      package="org.libsdl.app"
     2.7 +      android:versionCode="1"
     2.8 +      android:versionName="1.0">
     2.9 +    <application android:label="@string/app_name" android:icon="@drawable/icon">
    2.10 +        <activity android:name="SDLActivity"
    2.11 +                  android:label="@string/app_name">
    2.12 +            <intent-filter>
    2.13 +                <action android:name="android.intent.action.MAIN" />
    2.14 +                <category android:name="android.intent.category.LAUNCHER" />
    2.15 +            </intent-filter>
    2.16 +        </activity>
    2.17 +    </application>
    2.18 +</manifest> 
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/android-project/build.properties	Thu Jan 06 17:12:31 2011 -0800
     3.3 @@ -0,0 +1,17 @@
     3.4 +# This file is used to override default values used by the Ant build system.
     3.5 +# 
     3.6 +# This file must be checked in Version Control Systems, as it is
     3.7 +# integral to the build system of your project.
     3.8 +
     3.9 +# This file is only used by the Ant script.
    3.10 +
    3.11 +# You can use this to override default values such as
    3.12 +#  'source.dir' for the location of your java source folder and
    3.13 +#  'out.dir' for the location of your output folder.
    3.14 +
    3.15 +# You can also use it define how the release builds are signed by declaring
    3.16 +# the following properties:
    3.17 +#  'key.store' for the location of your keystore and
    3.18 +#  'key.alias' for the name of the key to use.
    3.19 +# The password will be asked during the build when you use the 'release' target.
    3.20 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/android-project/build.xml	Thu Jan 06 17:12:31 2011 -0800
     4.3 @@ -0,0 +1,67 @@
     4.4 +<?xml version="1.0" encoding="UTF-8"?>
     4.5 +<project name="SDLApp" default="help">
     4.6 +
     4.7 +    <!-- The local.properties file is created and updated by the 'android' tool.
     4.8 +         It contains the path to the SDK. It should *NOT* be checked in in Version
     4.9 +         Control Systems. -->
    4.10 +    <property file="local.properties" />
    4.11 +
    4.12 +    <!-- The build.properties file can be created by you and is never touched
    4.13 +         by the 'android' tool. This is the place to change some of the default property values
    4.14 +         used by the Ant rules.
    4.15 +         Here are some properties you may want to change/update:
    4.16 +
    4.17 +         application.package
    4.18 +             the name of your application package as defined in the manifest. Used by the
    4.19 +             'uninstall' rule.
    4.20 +         source.dir
    4.21 +             the name of the source directory. Default is 'src'.
    4.22 +         out.dir
    4.23 +             the name of the output directory. Default is 'bin'.
    4.24 +
    4.25 +         Properties related to the SDK location or the project target should be updated
    4.26 +          using the 'android' tool with the 'update' action.
    4.27 +
    4.28 +         This file is an integral part of the build system for your application and
    4.29 +         should be checked in in Version Control Systems.
    4.30 +
    4.31 +         -->
    4.32 +    <property file="build.properties" />
    4.33 +
    4.34 +    <!-- The default.properties file is created and updated by the 'android' tool, as well
    4.35 +         as ADT.
    4.36 +         This file is an integral part of the build system for your application and
    4.37 +         should be checked in in Version Control Systems. -->
    4.38 +    <property file="default.properties" />
    4.39 +
    4.40 +    <!-- Custom Android task to deal with the project target, and import the proper rules.
    4.41 +         This requires ant 1.6.0 or above. -->
    4.42 +    <path id="android.antlibs">
    4.43 +        <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
    4.44 +        <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
    4.45 +        <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
    4.46 +        <pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
    4.47 +        <pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
    4.48 +    </path>
    4.49 +
    4.50 +    <taskdef name="setup"
    4.51 +        classname="com.android.ant.SetupTask"
    4.52 +        classpathref="android.antlibs" />
    4.53 +
    4.54 +    <!-- Execute the Android Setup task that will setup some properties specific to the target,
    4.55 +         and import the build rules files.
    4.56 +
    4.57 +         The rules file is imported from
    4.58 +            <SDK>/platforms/<target_platform>/templates/android_rules.xml
    4.59 +
    4.60 +         To customize some build steps for your project:
    4.61 +         - copy the content of the main node <project> from android_rules.xml
    4.62 +         - paste it in this build.xml below the <setup /> task.
    4.63 +         - disable the import by changing the setup task below to <setup import="false" />
    4.64 +
    4.65 +         This will ensure that the properties are setup correctly but that your customized
    4.66 +         build steps are used.
    4.67 +    -->
    4.68 +    <setup />
    4.69 +
    4.70 +</project>
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/android-project/default.properties	Thu Jan 06 17:12:31 2011 -0800
     5.3 @@ -0,0 +1,11 @@
     5.4 +# This file is automatically generated by Android Tools.
     5.5 +# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
     5.6 +# 
     5.7 +# This file must be checked in Version Control Systems.
     5.8 +# 
     5.9 +# To customize properties used by the Ant build system use,
    5.10 +# "build.properties", and override values to adapt the script to your
    5.11 +# project structure.
    5.12 +
    5.13 +# Project target.
    5.14 +target=android-4
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/android-project/jni/Android.mk	Thu Jan 06 17:12:31 2011 -0800
     6.3 @@ -0,0 +1,1 @@
     6.4 +include $(call all-subdir-makefiles)
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/android-project/jni/src/Android.mk	Thu Jan 06 17:12:31 2011 -0800
     7.3 @@ -0,0 +1,19 @@
     7.4 +LOCAL_PATH := $(call my-dir)
     7.5 +
     7.6 +include $(CLEAR_VARS)
     7.7 +
     7.8 +LOCAL_MODULE := main
     7.9 +
    7.10 +SDL_PATH := ../SDL
    7.11 +
    7.12 +LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include
    7.13 +
    7.14 +# Add your application source files here...
    7.15 +LOCAL_SRC_FILES := $(SDL_PATH)/src/main/android/SDL_android_main.cpp \
    7.16 +	YourSourceHere.c
    7.17 +
    7.18 +LOCAL_SHARED_LIBRARIES := SDL
    7.19 +
    7.20 +LOCAL_LDLIBS := -lGLESv1_CM -llog
    7.21 +
    7.22 +include $(BUILD_SHARED_LIBRARY)
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/android-project/local.properties	Thu Jan 06 17:12:31 2011 -0800
     8.3 @@ -0,0 +1,10 @@
     8.4 +# This file is automatically generated by Android Tools.
     8.5 +# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
     8.6 +# 
     8.7 +# This file must *NOT* be checked in Version Control Systems,
     8.8 +# as it contains information specific to your local configuration.
     8.9 +
    8.10 +# location of the SDK. This is only used by Ant
    8.11 +# For customization when using a Version Control System, please read the
    8.12 +# header note.
    8.13 +sdk.dir=/Users/hercules/eclipse/android-sdk-mac_86
     9.1 Binary file android-project/res/drawable-hdpi/icon.png has changed
    10.1 Binary file android-project/res/drawable-ldpi/icon.png has changed
    11.1 Binary file android-project/res/drawable-mdpi/icon.png has changed
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/android-project/res/layout/main.xml	Thu Jan 06 17:12:31 2011 -0800
    12.3 @@ -0,0 +1,13 @@
    12.4 +<?xml version="1.0" encoding="utf-8"?>
    12.5 +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    12.6 +    android:orientation="vertical"
    12.7 +    android:layout_width="fill_parent"
    12.8 +    android:layout_height="fill_parent"
    12.9 +    >
   12.10 +<TextView  
   12.11 +    android:layout_width="fill_parent" 
   12.12 +    android:layout_height="wrap_content" 
   12.13 +    android:text="Hello World, SDLActivity"
   12.14 +    />
   12.15 +</LinearLayout>
   12.16 +
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/android-project/res/values/strings.xml	Thu Jan 06 17:12:31 2011 -0800
    13.3 @@ -0,0 +1,4 @@
    13.4 +<?xml version="1.0" encoding="utf-8"?>
    13.5 +<resources>
    13.6 +    <string name="app_name">SDL App</string>
    13.7 +</resources>
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/android-project/src/org/libsdl/app/SDLActivity.java	Thu Jan 06 17:12:31 2011 -0800
    14.3 @@ -0,0 +1,389 @@
    14.4 +package org.libsdl.app;
    14.5 +
    14.6 +import javax.microedition.khronos.egl.EGLConfig;
    14.7 +import javax.microedition.khronos.opengles.GL10;
    14.8 +import javax.microedition.khronos.egl.*;
    14.9 +
   14.10 +import android.app.*;
   14.11 +import android.content.*;
   14.12 +import android.view.*;
   14.13 +import android.os.*;
   14.14 +import android.util.Log;
   14.15 +import android.graphics.*;
   14.16 +import android.text.method.*;
   14.17 +import android.text.*;
   14.18 +import android.media.*;
   14.19 +import android.hardware.*;
   14.20 +import android.content.*;
   14.21 +
   14.22 +import java.lang.*;
   14.23 +
   14.24 +
   14.25 +/**
   14.26 +    SDL Activity
   14.27 +*/
   14.28 +public class SDLActivity extends Activity {
   14.29 +
   14.30 +    //Main components
   14.31 +    private static SDLActivity mSingleton;
   14.32 +    private static SDLSurface mSurface;
   14.33 +
   14.34 +    //Audio
   14.35 +    private static AudioTrack mAudioTrack;
   14.36 +    private static boolean bAudioIsEnabled;
   14.37 +
   14.38 +    //Sensors
   14.39 +    private static boolean bAccelIsEnabled;
   14.40 +
   14.41 +    //feature IDs. Must match up on the C side as well.
   14.42 +    private static int FEATURE_AUDIO = 1;
   14.43 +    private static int FEATURE_ACCEL = 2;
   14.44 +
   14.45 +    //Load the .so
   14.46 +    static {
   14.47 +        System.loadLibrary("SDL");
   14.48 +        System.loadLibrary("main");
   14.49 +    }
   14.50 +
   14.51 +    //Setup
   14.52 +    protected void onCreate(Bundle savedInstanceState) {
   14.53 +        super.onCreate(savedInstanceState);
   14.54 +        
   14.55 +        //So we can call stuff from static callbacks
   14.56 +        mSingleton = this;
   14.57 +
   14.58 +        //Set up the surface
   14.59 +        mSurface = new SDLSurface(getApplication());
   14.60 +        setContentView(mSurface);
   14.61 +        SurfaceHolder holder = mSurface.getHolder();
   14.62 +        holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
   14.63 +        
   14.64 +    }
   14.65 +
   14.66 +    //Audio
   14.67 +    public static boolean initAudio(){        
   14.68 +
   14.69 +        //blah. Hardcoded things are bad. FIXME when we have more sound stuff
   14.70 +        //working properly. 
   14.71 +        mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
   14.72 +                    11025,
   14.73 +                    AudioFormat.CHANNEL_CONFIGURATION_MONO,
   14.74 +                    AudioFormat.ENCODING_PCM_8BIT,
   14.75 +                    2048,
   14.76 +                    AudioTrack.MODE_STREAM);   
   14.77 +        bAudioIsEnabled = true;     
   14.78 +        return true;
   14.79 +    }
   14.80 +
   14.81 +    //Accel
   14.82 +    public static boolean initAccel(){
   14.83 +        mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
   14.84 +        bAccelIsEnabled = true;
   14.85 +        return true;
   14.86 +    }
   14.87 +    
   14.88 +    public static boolean closeAccel(){
   14.89 +        mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false);
   14.90 +        bAccelIsEnabled = false;
   14.91 +        return true;
   14.92 +    }
   14.93 +    
   14.94 +
   14.95 +    //Events
   14.96 +    protected void onPause() {
   14.97 +        super.onPause();
   14.98 +    }
   14.99 +
  14.100 +    protected void onResume() {
  14.101 +        super.onResume();
  14.102 +    }
  14.103 +
  14.104 +    
  14.105 +
  14.106 +
  14.107 +
  14.108 +    //C functions we call
  14.109 +    public static native void nativeInit();
  14.110 +    public static native void nativeQuit();
  14.111 +    public static native void nativeSetScreenSize(int width, int height);
  14.112 +    public static native void onNativeKeyDown(int keycode);
  14.113 +    public static native void onNativeKeyUp(int keycode);
  14.114 +    public static native void onNativeTouch(int action, float x, 
  14.115 +                                            float y, float p);
  14.116 +    public static native void onNativeResize(int x, int y, int format);
  14.117 +    public static native void onNativeAccel(float x, float y, float z);
  14.118 +
  14.119 +
  14.120 +
  14.121 +    //Java functions called from C
  14.122 +    private static void createGLContext(){
  14.123 +        mSurface.initEGL();
  14.124 +    }
  14.125 +
  14.126 +    public static void flipBuffers(){
  14.127 +        mSurface.flipEGL();
  14.128 +    }
  14.129 +
  14.130 +    public static void updateAudio(byte [] buf){
  14.131 +    
  14.132 +        if(mAudioTrack == null){
  14.133 +            return;
  14.134 +        }
  14.135 +        
  14.136 +        mAudioTrack.write(buf, 0, buf.length);
  14.137 +        mAudioTrack.play();
  14.138 +        
  14.139 +        Log.v("SDL","Played some audio");
  14.140 +    }
  14.141 +
  14.142 +    public static void enableFeature(int featureid, int enabled){
  14.143 +         Log.v("SDL","Feature " + featureid + " = " + enabled);
  14.144 +
  14.145 +        //Yuck. This is all horribly inelegent. If it gets to more than a few
  14.146 +        //'features' I'll rip this out and make something nicer, I promise :)
  14.147 +        if(featureid == FEATURE_AUDIO){
  14.148 +            if(enabled == 1){
  14.149 +                initAudio();
  14.150 +            }else{
  14.151 +                //We don't have one of these yet...
  14.152 +                //closeAudio(); 
  14.153 +            }
  14.154 +        }
  14.155 +
  14.156 +        else if(featureid == FEATURE_ACCEL){
  14.157 +            if(enabled == 1){
  14.158 +                initAccel();
  14.159 +            }else{
  14.160 +                closeAccel();
  14.161 +            }
  14.162 +        }
  14.163 +    }
  14.164 +
  14.165 +
  14.166 +
  14.167 +
  14.168 +
  14.169 +    
  14.170 +    
  14.171 +}
  14.172 +
  14.173 +/**
  14.174 +    Simple nativeInit() runnable
  14.175 +*/
  14.176 +class SDLRunner implements Runnable{
  14.177 +    public void run(){
  14.178 +        //SDLActivity.initAudio();
  14.179 +        
  14.180 +        //Runs SDL_main()
  14.181 +        SDLActivity.nativeInit();
  14.182 +
  14.183 +        Log.v("SDL","SDL thread terminated");
  14.184 +    }
  14.185 +}
  14.186 +
  14.187 +
  14.188 +/**
  14.189 +    SDLSurface. This is what we draw on, so we need to know when it's created
  14.190 +    in order to do anything useful. 
  14.191 +
  14.192 +    Because of this, that's where we set up the SDL thread
  14.193 +*/
  14.194 +class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, 
  14.195 +    View.OnKeyListener, View.OnTouchListener, SensorEventListener  {
  14.196 +
  14.197 +    //This is what SDL runs in. It invokes SDL_main(), eventually
  14.198 +    private Thread mSDLThread;    
  14.199 +    
  14.200 +    //EGL private objects
  14.201 +    private EGLContext  mEGLContext;
  14.202 +    private EGLSurface  mEGLSurface;
  14.203 +    private EGLDisplay  mEGLDisplay;
  14.204 +
  14.205 +    //Sensors
  14.206 +    private static SensorManager mSensorManager;
  14.207 +
  14.208 +    //Startup    
  14.209 +    public SDLSurface(Context context) {
  14.210 +        super(context);
  14.211 +        getHolder().addCallback(this); 
  14.212 +    
  14.213 +        setFocusable(true);
  14.214 +        setFocusableInTouchMode(true);
  14.215 +        requestFocus();
  14.216 +        setOnKeyListener(this); 
  14.217 +        setOnTouchListener(this);   
  14.218 +        
  14.219 +        mSensorManager = (SensorManager)context.getSystemService("sensor");  
  14.220 +    }
  14.221 +
  14.222 +    //Called when we have a valid drawing surface
  14.223 +    public void surfaceCreated(SurfaceHolder holder) {
  14.224 +        Log.v("SDL","Surface created"); 
  14.225 +
  14.226 +        int width = getWidth();
  14.227 +        int height = getHeight();
  14.228 +
  14.229 +        //Set the width and height variables in C before we start SDL so we have
  14.230 +        //it available on init
  14.231 +        SDLActivity.nativeSetScreenSize(width, height);
  14.232 +
  14.233 +        //Now start up the C app thread
  14.234 +        mSDLThread = new Thread(new SDLRunner(), "SDLThread"); 
  14.235 +		mSDLThread.start();       
  14.236 +    }
  14.237 +
  14.238 +    //Called when we lose the surface
  14.239 +    public void surfaceDestroyed(SurfaceHolder holder) {
  14.240 +        Log.v("SDL","Surface destroyed");
  14.241 +        
  14.242 +        SDLActivity.nativeQuit();
  14.243 +
  14.244 +        //Now wait for the SDL thread to quit
  14.245 +        try{
  14.246 +            mSDLThread.wait();
  14.247 +        }catch(Exception e){
  14.248 +            Log.v("SDL","Problem stopping thread: " + e);
  14.249 +        }
  14.250 +    }
  14.251 +
  14.252 +    //Called when the surface is resized
  14.253 +    public void surfaceChanged(SurfaceHolder holder, int format, 
  14.254 +                                int width, int height) {
  14.255 +        Log.v("SDL","Surface resized");
  14.256 +        
  14.257 +        SDLActivity.onNativeResize(width, height, format);
  14.258 +    }
  14.259 +
  14.260 +    //unused
  14.261 +    public void onDraw(Canvas canvas) {}
  14.262 +
  14.263 +    
  14.264 +    //EGL functions
  14.265 +    public boolean initEGL(){
  14.266 +        Log.v("SDL","Starting up");
  14.267 +
  14.268 +        try{
  14.269 +
  14.270 +            EGL10 egl = (EGL10)EGLContext.getEGL();
  14.271 +
  14.272 +            EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
  14.273 +
  14.274 +            int[] version = new int[2];
  14.275 +            egl.eglInitialize(dpy, version);
  14.276 +
  14.277 +            int[] configSpec = {
  14.278 +                    //EGL10.EGL_DEPTH_SIZE,   16,
  14.279 +                    EGL10.EGL_NONE
  14.280 +            };
  14.281 +            EGLConfig[] configs = new EGLConfig[1];
  14.282 +            int[] num_config = new int[1];
  14.283 +            egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config);
  14.284 +            EGLConfig config = configs[0];
  14.285 +
  14.286 +            EGLContext ctx = egl.eglCreateContext(dpy, config, EGL10.EGL_NO_CONTEXT, null);
  14.287 +
  14.288 +            EGLSurface surface = egl.eglCreateWindowSurface(dpy, config, this, null);
  14.289 +
  14.290 +            egl.eglMakeCurrent(dpy, surface, surface, ctx);
  14.291 +
  14.292 +            mEGLContext = ctx;
  14.293 +            mEGLDisplay = dpy;
  14.294 +            mEGLSurface = surface;
  14.295 +            
  14.296 +            
  14.297 +        }catch(Exception e){
  14.298 +            Log.v("SDL", e + "");
  14.299 +            for(StackTraceElement s : e.getStackTrace()){
  14.300 +                Log.v("SDL", s.toString());
  14.301 +            }
  14.302 +        }
  14.303 +        Log.v("SDL","Done making!");
  14.304 +
  14.305 +        return true;
  14.306 +    }
  14.307 +
  14.308 +    //EGL buffer flip
  14.309 +    public void flipEGL(){      
  14.310 +        try{
  14.311 +        
  14.312 +            EGL10 egl = (EGL10)EGLContext.getEGL();
  14.313 +            GL10 gl = (GL10)mEGLContext.getGL();
  14.314 +
  14.315 +            egl.eglWaitNative(EGL10.EGL_NATIVE_RENDERABLE, null);
  14.316 +
  14.317 +            //drawing here
  14.318 +
  14.319 +            egl.eglWaitGL();
  14.320 +
  14.321 +            egl.eglSwapBuffers(mEGLDisplay, mEGLSurface);
  14.322 +
  14.323 +            
  14.324 +        }catch(Exception e){
  14.325 +            Log.v("SDL", "flipEGL(): " + e);
  14.326 +
  14.327 +            for(StackTraceElement s : e.getStackTrace()){
  14.328 +                Log.v("SDL", s.toString());
  14.329 +            }
  14.330 +        }
  14.331 +    }
  14.332 +
  14.333 +
  14.334 +  
  14.335 +    //Key events
  14.336 +    public boolean onKey(View  v, int keyCode, KeyEvent event){
  14.337 +
  14.338 +        if(event.getAction() == KeyEvent.ACTION_DOWN){
  14.339 +            SDLActivity.onNativeKeyDown(keyCode);
  14.340 +            return true;
  14.341 +        }
  14.342 +        
  14.343 +        else if(event.getAction() == KeyEvent.ACTION_UP){
  14.344 +            SDLActivity.onNativeKeyUp(keyCode);
  14.345 +            return true;
  14.346 +        }
  14.347 +        
  14.348 +        return false;
  14.349 +    }
  14.350 +
  14.351 +    //Touch events
  14.352 +    public boolean onTouch(View v, MotionEvent event){
  14.353 +    
  14.354 +        int action = event.getAction();
  14.355 +        float x = event.getX();
  14.356 +        float y = event.getY();
  14.357 +        float p = event.getPressure();
  14.358 +
  14.359 +        //TODO: Anything else we need to pass?        
  14.360 +        SDLActivity.onNativeTouch(action, x, y, p);
  14.361 +        return true;
  14.362 +    }
  14.363 +
  14.364 +    //Sensor events
  14.365 +    public void enableSensor(int sensortype, boolean enabled){
  14.366 +        //TODO: This uses getDefaultSensor - what if we have >1 accels?
  14.367 +        if(enabled){
  14.368 +            mSensorManager.registerListener(this, 
  14.369 +                            mSensorManager.getDefaultSensor(sensortype), 
  14.370 +                            SensorManager.SENSOR_DELAY_GAME, null);
  14.371 +        }else{
  14.372 +            mSensorManager.unregisterListener(this, 
  14.373 +                            mSensorManager.getDefaultSensor(sensortype));
  14.374 +        }
  14.375 +    }
  14.376 +    
  14.377 +    public void onAccuracyChanged(Sensor sensor, int accuracy){
  14.378 +        //TODO
  14.379 +    }
  14.380 +
  14.381 +    public void onSensorChanged(SensorEvent event){
  14.382 +        if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
  14.383 +            SDLActivity.onNativeAccel(  event.values[0],
  14.384 +                                        event.values[1],
  14.385 +                                        event.values[2] );
  14.386 +        }
  14.387 +    }
  14.388 +
  14.389 +
  14.390 +}
  14.391 +
  14.392 +