project_files/Android-build/SDL-android-project/src/org/hedgewars/hedgeroid/SDLActivity.java
changeset 10017 de822cd3df3a
parent 9998 736015b847e3
child 11046 47a8c19ecb60
equal deleted inserted replaced
10015:4feced261c68 10017:de822cd3df3a
    60 
    60 
    61 /**
    61 /**
    62     SDL Activity
    62     SDL Activity
    63  */
    63  */
    64 public class SDLActivity extends Activity {
    64 public class SDLActivity extends Activity {
    65 	/**
    65     /**
    66 	 * Set startConfig to the desired config when starting this activity. This avoids having to parcel all
    66      * Set startConfig to the desired config when starting this activity. This avoids having to parcel all
    67 	 * the config objects into the Intent. Not particularly elegant, but it's actually a recommended
    67      * the config objects into the Intent. Not particularly elegant, but it's actually a recommended
    68 	 * way to do this (http://developer.android.com/guide/faq/framework.html#3)
    68      * way to do this (http://developer.android.com/guide/faq/framework.html#3)
    69 	 */
    69      */
    70 	public static volatile GameConfig startConfig;
    70     public static volatile GameConfig startConfig;
    71 	public static volatile boolean startNetgame;
    71     public static volatile boolean startNetgame;
    72 	
    72 
    73 	// Main components
    73     // Main components
    74 	public static SDLActivity mSingleton;
    74     public static SDLActivity mSingleton;
    75 	private static SDLSurface mSurface;
    75     private static SDLSurface mSurface;
    76 	private static Thread mSDLThread;
    76     private static Thread mSDLThread;
    77 
    77 
    78 	// Audio
    78     // Audio
    79 	private static Thread mAudioThread;
    79     private static Thread mAudioThread;
    80 	private static AudioTrack mAudioTrack;
    80     private static AudioTrack mAudioTrack;
    81 
    81 
    82 	// EGL private objects
    82     // EGL private objects
    83 	private static EGLContext  mEGLContext;
    83     private static EGLContext  mEGLContext;
    84 	private static EGLSurface  mEGLSurface;
    84     private static EGLSurface  mEGLSurface;
    85 	private static EGLDisplay  mEGLDisplay;
    85     private static EGLDisplay  mEGLDisplay;
    86 	private static EGLConfig   mEGLConfig;
    86     private static EGLConfig   mEGLConfig;
    87 	private static int mGLMajor, mGLMinor;
    87     private static int mGLMajor, mGLMinor;
    88 
    88 
    89 	// Load the .so
    89     // Load the .so
    90 	static {
    90     static {
    91 		System.loadLibrary("SDL");
    91         System.loadLibrary("SDL");
    92 		System.loadLibrary("main");
    92         System.loadLibrary("main");
    93 	}
    93     }
    94 
    94 
    95 	// Setup
    95     // Setup
    96 	protected void onCreate(Bundle savedInstanceState) {
    96     protected void onCreate(Bundle savedInstanceState) {
    97 		super.onCreate(savedInstanceState);
    97         super.onCreate(savedInstanceState);
    98 
    98 
    99 		// So we can call stuff from static callbacks
    99         // So we can call stuff from static callbacks
   100 		mSingleton = this;
   100         mSingleton = this;
   101 
   101 
   102 		// Set up the surface
   102         // Set up the surface
   103 		mSurface = new SDLSurface(getApplication(), startConfig, startNetgame);
   103         mSurface = new SDLSurface(getApplication(), startConfig, startNetgame);
   104 		startConfig = null;
   104         startConfig = null;
   105 		setContentView(mSurface);
   105         setContentView(mSurface);
   106 	}
   106     }
   107 
   107 
   108 	// Events
   108     // Events
   109 	protected void onPause() {
   109     protected void onPause() {
   110 		Log.v("SDL", "onPause()");
   110         Log.v("SDL", "onPause()");
   111 		super.onPause();
   111         super.onPause();
   112 
   112 
   113 		if(mEGLDisplay != null && mEGLContext != null){
   113         if(mEGLDisplay != null && mEGLContext != null){
   114 			EGL10 egl = (EGL10)EGLContext.getEGL();
   114             EGL10 egl = (EGL10)EGLContext.getEGL();
   115 			egl.eglDestroyContext(mEGLDisplay, mEGLContext);
   115             egl.eglDestroyContext(mEGLDisplay, mEGLContext);
   116 			mEGLDisplay = null;
   116             mEGLDisplay = null;
   117 			mEGLContext = null;
   117             mEGLContext = null;
   118 		}
   118         }
   119 
   119 
   120 		SDLActivity.nativePause();
   120         SDLActivity.nativePause();
   121 	}
   121     }
   122 
   122 
   123 	protected void onResume() {
   123     protected void onResume() {
   124 		Log.v("SDL", "onResume()");
   124         Log.v("SDL", "onResume()");
   125 		super.onResume();
   125         super.onResume();
   126 	}
   126     }
   127 
   127 
   128 	protected void onDestroy() {
   128     protected void onDestroy() {
   129 		super.onDestroy();
   129         super.onDestroy();
   130 		Log.v("SDL", "onDestroy()");
   130         Log.v("SDL", "onDestroy()");
   131 		// Send a quit message to the application
   131         // Send a quit message to the application
   132 		SDLActivity.nativeQuit();
   132         SDLActivity.nativeQuit();
   133 		// Now wait for the SDL thread to quit
   133         // Now wait for the SDL thread to quit
   134 		if (mSDLThread != null) {
   134         if (mSDLThread != null) {
   135 			try {
   135             try {
   136 				mSDLThread.join();
   136                 mSDLThread.join();
   137 			} catch(Exception e) {
   137             } catch(Exception e) {
   138 				Log.w("SDL", "Problem stopping thread: " + e);
   138                 Log.w("SDL", "Problem stopping thread: " + e);
   139 			}
   139             }
   140 			mSDLThread = null;
   140             mSDLThread = null;
   141 		}
   141         }
   142 		mSingleton = null;
   142         mSingleton = null;
   143 	}
   143     }
   144 	
   144 
   145 	public static void synchronizedNativeInit(String...args) {
   145     public static void synchronizedNativeInit(String...args) {
   146 		synchronized(PascalExports.engineMutex) {
   146         synchronized(PascalExports.engineMutex) {
   147 			nativeInit(args);
   147             nativeInit(args);
   148 		}
   148         }
   149 	}
   149     }
   150 	
   150 
   151 	// C functions we call
   151     // C functions we call
   152 	private static native void nativeInit(String...args);
   152     private static native void nativeInit(String...args);
   153 	public static native void nativeQuit();
   153     public static native void nativeQuit();
   154 	public static native void nativePause();
   154     public static native void nativePause();
   155 	public static native void nativeResume();
   155     public static native void nativeResume();
   156 	public static native void onNativeResize(int x, int y, int format);
   156     public static native void onNativeResize(int x, int y, int format);
   157 	public static native void onNativeKeyDown(int keycode);
   157     public static native void onNativeKeyDown(int keycode);
   158 	public static native void onNativeKeyUp(int keycode);
   158     public static native void onNativeKeyUp(int keycode);
   159 	public static native void onNativeTouch(int touchDevId, int pointerFingerId,
   159     public static native void onNativeTouch(int touchDevId, int pointerFingerId,
   160 			int action, float x, 
   160             int action, float x,
   161 			float y, float p);
   161             float y, float p);
   162 	public static native void onNativeAccel(float x, float y, float z);
   162     public static native void onNativeAccel(float x, float y, float z);
   163 	public static native void nativeRunAudioThread();
   163     public static native void nativeRunAudioThread();
   164 
   164 
   165 
   165 
   166 	// Java functions called from C
   166     // Java functions called from C
   167 
   167 
   168 	public static boolean createGLContext(int majorVersion, int minorVersion) {
   168     public static boolean createGLContext(int majorVersion, int minorVersion) {
   169 		return initEGL(majorVersion, minorVersion);
   169         return initEGL(majorVersion, minorVersion);
   170 	}
   170     }
   171 
   171 
   172 	public static void flipBuffers() {
   172     public static void flipBuffers() {
   173 		flipEGL();
   173         flipEGL();
   174 	}
   174     }
   175 
   175 
   176 	public static void setActivityTitle(final String title) {
   176     public static void setActivityTitle(final String title) {
   177 		// Called from SDLMain() thread and can't directly affect the view
   177         // Called from SDLMain() thread and can't directly affect the view
   178 		mSingleton.runOnUiThread(new Runnable() {
   178         mSingleton.runOnUiThread(new Runnable() {
   179 			public void run() {
   179             public void run() {
   180 				mSingleton.setTitle(title);
   180                 mSingleton.setTitle(title);
   181 			}
   181             }
   182 		});
   182         });
   183 	}
   183     }
   184 
   184 
   185 	public static Context getContext() {
   185     public static Context getContext() {
   186 		return mSingleton;
   186         return mSingleton;
   187 	}
   187     }
   188 
   188 
   189 	public static void startApp(final int width, final int height, GameConfig config, boolean netgame) {
   189     public static void startApp(final int width, final int height, GameConfig config, boolean netgame) {
   190 		// Start up the C app thread
   190         // Start up the C app thread
   191 		if (mSDLThread == null) {
   191         if (mSDLThread == null) {
   192 			mSDLThread = new Thread(new SDLMain(width, height, config, netgame));
   192             mSDLThread = new Thread(new SDLMain(width, height, config, netgame));
   193 			mSDLThread.start();
   193             mSDLThread.start();
   194 		} else {
   194         } else {
   195 			SDLActivity.nativeResume();
   195             SDLActivity.nativeResume();
   196 		}
   196         }
   197 	}
   197     }
   198 
   198 
   199 	// EGL functions
   199     // EGL functions
   200 	public static boolean initEGL(int majorVersion, int minorVersion) {
   200     public static boolean initEGL(int majorVersion, int minorVersion) {
   201 		if (SDLActivity.mEGLDisplay == null) {
   201         if (SDLActivity.mEGLDisplay == null) {
   202 			try {
   202             try {
   203 				EGL10 egl = (EGL10)EGLContext.getEGL();
   203                 EGL10 egl = (EGL10)EGLContext.getEGL();
   204 
   204 
   205 				EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
   205                 EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
   206 
   206 
   207 				int[] version = new int[2];
   207                 int[] version = new int[2];
   208 				egl.eglInitialize(dpy, version);
   208                 egl.eglInitialize(dpy, version);
   209 
   209 
   210 				int EGL_OPENGL_ES_BIT = 1;
   210                 int EGL_OPENGL_ES_BIT = 1;
   211 				int EGL_OPENGL_ES2_BIT = 4;
   211                 int EGL_OPENGL_ES2_BIT = 4;
   212 				int renderableType = 0;
   212                 int renderableType = 0;
   213 				if (majorVersion == 2) {
   213                 if (majorVersion == 2) {
   214 					renderableType = EGL_OPENGL_ES2_BIT;
   214                     renderableType = EGL_OPENGL_ES2_BIT;
   215 				} else if (majorVersion == 1) {
   215                 } else if (majorVersion == 1) {
   216 					renderableType = EGL_OPENGL_ES_BIT;
   216                     renderableType = EGL_OPENGL_ES_BIT;
   217 				}
   217                 }
   218 				int[] configSpec = {
   218                 int[] configSpec = {
   219 						EGL10.EGL_RENDERABLE_TYPE, renderableType,
   219                         EGL10.EGL_RENDERABLE_TYPE, renderableType,
   220 						EGL10.EGL_NONE
   220                         EGL10.EGL_NONE
   221 				};
   221                 };
   222 				EGLConfig[] configs = new EGLConfig[1];
   222                 EGLConfig[] configs = new EGLConfig[1];
   223 				int[] num_config = new int[1];
   223                 int[] num_config = new int[1];
   224 				if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0) {
   224                 if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0) {
   225 					Log.e("SDL", "No EGL config available");
   225                     Log.e("SDL", "No EGL config available");
   226 					return false;
   226                     return false;
   227 				}
   227                 }
   228 				EGLConfig config = configs[0];
   228                 EGLConfig config = configs[0];
   229 
   229 
   230 				SDLActivity.mEGLDisplay = dpy;
   230                 SDLActivity.mEGLDisplay = dpy;
   231 				SDLActivity.mEGLConfig = config;
   231                 SDLActivity.mEGLConfig = config;
   232 				SDLActivity.mGLMajor = majorVersion;
   232                 SDLActivity.mGLMajor = majorVersion;
   233 				SDLActivity.mGLMinor = minorVersion;
   233                 SDLActivity.mGLMinor = minorVersion;
   234 
   234 
   235 				SDLActivity.createEGLSurface();
   235                 SDLActivity.createEGLSurface();
   236 			} catch(Exception e) {
   236             } catch(Exception e) {
   237 				Log.v("SDL", e + "");
   237                 Log.v("SDL", e + "");
   238 				for (StackTraceElement s : e.getStackTrace()) {
   238                 for (StackTraceElement s : e.getStackTrace()) {
   239 					Log.v("SDL", s.toString());
   239                     Log.v("SDL", s.toString());
   240 				}
   240                 }
   241 			}
   241             }
   242 		}
   242         }
   243 		else SDLActivity.createEGLSurface();
   243         else SDLActivity.createEGLSurface();
   244 
   244 
   245 		return true;
   245         return true;
   246 	}
   246     }
   247 
   247 
   248 	public static boolean createEGLContext() {
   248     public static boolean createEGLContext() {
   249 		EGL10 egl = (EGL10)EGLContext.getEGL();
   249         EGL10 egl = (EGL10)EGLContext.getEGL();
   250 		int EGL_CONTEXT_CLIENT_VERSION=0x3098;
   250         int EGL_CONTEXT_CLIENT_VERSION=0x3098;
   251 		int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE };
   251         int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE };
   252 		SDLActivity.mEGLContext = egl.eglCreateContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs);
   252         SDLActivity.mEGLContext = egl.eglCreateContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs);
   253 		if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) {
   253         if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) {
   254 			Log.e("SDL", "Couldn't create context");
   254             Log.e("SDL", "Couldn't create context");
   255 			return false;
   255             return false;
   256 		}
   256         }
   257 		return true;
   257         return true;
   258 	}
   258     }
   259 
   259 
   260 	public static boolean createEGLSurface() {
   260     public static boolean createEGLSurface() {
   261 		if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) {
   261         if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) {
   262 			EGL10 egl = (EGL10)EGLContext.getEGL();
   262             EGL10 egl = (EGL10)EGLContext.getEGL();
   263 			if (SDLActivity.mEGLContext == null) createEGLContext();
   263             if (SDLActivity.mEGLContext == null) createEGLContext();
   264 
   264 
   265 			Log.v("SDL", "Creating new EGL Surface");
   265             Log.v("SDL", "Creating new EGL Surface");
   266 			EGLSurface surface = egl.eglCreateWindowSurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null);
   266             EGLSurface surface = egl.eglCreateWindowSurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null);
   267 			if (surface == EGL10.EGL_NO_SURFACE) {
   267             if (surface == EGL10.EGL_NO_SURFACE) {
   268 				Log.e("SDL", "Couldn't create surface");
   268                 Log.e("SDL", "Couldn't create surface");
   269 				return false;
   269                 return false;
   270 			}
   270             }
   271 
   271 
   272 			if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
   272             if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
   273 				Log.e("SDL", "Old EGL Context doesnt work, trying with a new one");
   273                 Log.e("SDL", "Old EGL Context doesnt work, trying with a new one");
   274 				createEGLContext();
   274                 createEGLContext();
   275 				if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
   275                 if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
   276 					Log.e("SDL", "Failed making EGL Context current");
   276                     Log.e("SDL", "Failed making EGL Context current");
   277 					return false;
   277                     return false;
   278 				}
   278                 }
   279 			}
   279             }
   280 			SDLActivity.mEGLSurface = surface;
   280             SDLActivity.mEGLSurface = surface;
   281 			return true;
   281             return true;
   282 		}
   282         }
   283 		return false;
   283         return false;
   284 	}
   284     }
   285 
   285 
   286 	// EGL buffer flip
   286     // EGL buffer flip
   287 	public static void flipEGL() {
   287     public static void flipEGL() {
   288 		try {
   288         try {
   289 			EGL10 egl = (EGL10)EGLContext.getEGL();
   289             EGL10 egl = (EGL10)EGLContext.getEGL();
   290 
   290 
   291 			egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null);
   291             egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null);
   292 
   292 
   293 			// drawing here
   293             // drawing here
   294 
   294 
   295 			egl.eglWaitGL();
   295             egl.eglWaitGL();
   296 
   296 
   297 			egl.eglSwapBuffers(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface);
   297             egl.eglSwapBuffers(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface);
   298 
   298 
   299 
   299 
   300 		} catch(Exception e) {
   300         } catch(Exception e) {
   301 			Log.v("SDL", "flipEGL(): " + e);
   301             Log.v("SDL", "flipEGL(): " + e);
   302 			for (StackTraceElement s : e.getStackTrace()) {
   302             for (StackTraceElement s : e.getStackTrace()) {
   303 				Log.v("SDL", s.toString());
   303                 Log.v("SDL", s.toString());
   304 			}
   304             }
   305 		}
   305         }
   306 	}
   306     }
   307 
   307 
   308 	// Audio
   308     // Audio
   309 	private static Object buf;
   309     private static Object buf;
   310 
   310 
   311 	public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
   311     public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
   312 		int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
   312         int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
   313 		int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
   313         int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
   314 		int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
   314         int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
   315 
   315 
   316 		Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
   316         Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
   317 
   317 
   318 		// Let the user pick a larger buffer if they really want -- but ye
   318         // Let the user pick a larger buffer if they really want -- but ye
   319 		// gods they probably shouldn't, the minimums are horrifyingly high
   319         // gods they probably shouldn't, the minimums are horrifyingly high
   320 		// latency already
   320         // latency already
   321 		desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
   321         desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
   322 
   322 
   323 		mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
   323         mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
   324 				channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
   324                 channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
   325 
   325 
   326 		audioStartThread();
   326         audioStartThread();
   327 
   327 
   328 		Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
   328         Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
   329 
   329 
   330 		if (is16Bit) {
   330         if (is16Bit) {
   331 			buf = new short[desiredFrames * (isStereo ? 2 : 1)];
   331             buf = new short[desiredFrames * (isStereo ? 2 : 1)];
   332 		} else {
   332         } else {
   333 			buf = new byte[desiredFrames * (isStereo ? 2 : 1)]; 
   333             buf = new byte[desiredFrames * (isStereo ? 2 : 1)];
   334 		}
   334         }
   335 		return buf;
   335         return buf;
   336 	}
   336     }
   337 
   337 
   338 	public static void audioStartThread() {
   338     public static void audioStartThread() {
   339 		mAudioThread = new Thread(new Runnable() {
   339         mAudioThread = new Thread(new Runnable() {
   340 			public void run() {
   340             public void run() {
   341 				mAudioTrack.play();
   341                 mAudioTrack.play();
   342 				nativeRunAudioThread();
   342                 nativeRunAudioThread();
   343 			}
   343             }
   344 		});
   344         });
   345 
   345 
   346 		// I'd take REALTIME if I could get it!
   346         // I'd take REALTIME if I could get it!
   347 		mAudioThread.setPriority(Thread.MAX_PRIORITY);
   347         mAudioThread.setPriority(Thread.MAX_PRIORITY);
   348 		mAudioThread.start();
   348         mAudioThread.start();
   349 	}
   349     }
   350 
   350 
   351 	public static void audioWriteShortBuffer(short[] buffer) {
   351     public static void audioWriteShortBuffer(short[] buffer) {
   352 		for (int i = 0; i < buffer.length; ) {
   352         for (int i = 0; i < buffer.length; ) {
   353 			int result = mAudioTrack.write(buffer, i, buffer.length - i);
   353             int result = mAudioTrack.write(buffer, i, buffer.length - i);
   354 			if (result > 0) {
   354             if (result > 0) {
   355 				i += result;
   355                 i += result;
   356 			} else if (result == 0) {
   356             } else if (result == 0) {
   357 				try {
   357                 try {
   358 					Thread.sleep(1);
   358                     Thread.sleep(1);
   359 				} catch(InterruptedException e) {
   359                 } catch(InterruptedException e) {
   360 					// Nom nom
   360                     // Nom nom
   361 				}
   361                 }
   362 			} else {
   362             } else {
   363 				Log.w("SDL", "SDL audio: error return from write(short)");
   363                 Log.w("SDL", "SDL audio: error return from write(short)");
   364 				return;
   364                 return;
   365 			}
   365             }
   366 		}
   366         }
   367 	}
   367     }
   368 
   368 
   369 	public static void audioWriteByteBuffer(byte[] buffer) {
   369     public static void audioWriteByteBuffer(byte[] buffer) {
   370 		for (int i = 0; i < buffer.length; ) {
   370         for (int i = 0; i < buffer.length; ) {
   371 			int result = mAudioTrack.write(buffer, i, buffer.length - i);
   371             int result = mAudioTrack.write(buffer, i, buffer.length - i);
   372 			if (result > 0) {
   372             if (result > 0) {
   373 				i += result;
   373                 i += result;
   374 			} else if (result == 0) {
   374             } else if (result == 0) {
   375 				try {
   375                 try {
   376 					Thread.sleep(1);
   376                     Thread.sleep(1);
   377 				} catch(InterruptedException e) {
   377                 } catch(InterruptedException e) {
   378 					// Nom nom
   378                     // Nom nom
   379 				}
   379                 }
   380 			} else {
   380             } else {
   381 				Log.w("SDL", "SDL audio: error return from write(short)");
   381                 Log.w("SDL", "SDL audio: error return from write(short)");
   382 				return;
   382                 return;
   383 			}
   383             }
   384 		}
   384         }
   385 	}
   385     }
   386 
   386 
   387 	public static void audioQuit() {
   387     public static void audioQuit() {
   388 		if (mAudioThread != null) {
   388         if (mAudioThread != null) {
   389 			try {
   389             try {
   390 				mAudioThread.join();
   390                 mAudioThread.join();
   391 			} catch(Exception e) {
   391             } catch(Exception e) {
   392 				Log.v("SDL", "Problem stopping audio thread: " + e);
   392                 Log.v("SDL", "Problem stopping audio thread: " + e);
   393 			}
   393             }
   394 			mAudioThread = null;
   394             mAudioThread = null;
   395 
   395 
   396 			//Log.v("SDL", "Finished waiting for audio thread");
   396             //Log.v("SDL", "Finished waiting for audio thread");
   397 		}
   397         }
   398 
   398 
   399 		if (mAudioTrack != null) {
   399         if (mAudioTrack != null) {
   400 			mAudioTrack.stop();
   400             mAudioTrack.stop();
   401 			mAudioTrack = null;
   401             mAudioTrack = null;
   402 		}
   402         }
   403 	}
   403     }
   404 	
   404 
   405 	public static int getDensity(){
   405     public static int getDensity(){
   406 		DisplayMetrics dm = SDLActivity.getContext().getResources().getDisplayMetrics();
   406         DisplayMetrics dm = SDLActivity.getContext().getResources().getDisplayMetrics();
   407 		return dm.densityDpi;
   407         return dm.densityDpi;
   408 	}
   408     }
   409 }
   409 }
   410 
   410 
   411 /**
   411 /**
   412     Simple nativeInit() runnable
   412     Simple nativeInit() runnable
   413  */
   413  */
   414 class SDLMain implements Runnable {
   414 class SDLMain implements Runnable {
   415 	public static final String TAG = "SDLMain";
   415     public static final String TAG = "SDLMain";
   416 	
   416 
   417     public static final int RQ_LOWRES            = 0x00000001; // use half land array
   417     public static final int RQ_LOWRES            = 0x00000001; // use half land array
   418     public static final int RQ_BLURRY_LAND       = 0x00000002; // downscaled terrain
   418     public static final int RQ_BLURRY_LAND       = 0x00000002; // downscaled terrain
   419     public static final int RQ_NO_BACKGROUND     = 0x00000004; // don't draw background
   419     public static final int RQ_NO_BACKGROUND     = 0x00000004; // don't draw background
   420     public static final int RQ_SIMPLE_ROPE       = 0x00000008; // avoid drawing rope
   420     public static final int RQ_SIMPLE_ROPE       = 0x00000008; // avoid drawing rope
   421     public static final int RQ_2D_WATER          = 0x00000010; // disabe 3D water effect
   421     public static final int RQ_2D_WATER          = 0x00000010; // disabe 3D water effect
   424     public static final int RQ_NO_MENU_ANIM      = 0x00000080; // ammomenu appears with no animation
   424     public static final int RQ_NO_MENU_ANIM      = 0x00000080; // ammomenu appears with no animation
   425     public static final int RQ_NO_DROPLETS       = 0x00000100; // no droplets
   425     public static final int RQ_NO_DROPLETS       = 0x00000100; // no droplets
   426     public static final int RQ_NO_CLAMPING       = 0x00000200; // don't clamp textures
   426     public static final int RQ_NO_CLAMPING       = 0x00000200; // don't clamp textures
   427     public static final int RQ_NO_TOOLTIPS       = 0x00000400; // tooltips are not drawn
   427     public static final int RQ_NO_TOOLTIPS       = 0x00000400; // tooltips are not drawn
   428     public static final int RQ_NO_VSYNC          = 0x00000800; // don't sync on vblank
   428     public static final int RQ_NO_VSYNC          = 0x00000800; // don't sync on vblank
   429 	
   429 
   430 	private final int surfaceWidth, surfaceHeight;
   430     private final int surfaceWidth, surfaceHeight;
   431 	private final String playerName;
   431     private final String playerName;
   432 	private final GameConfig config;
   432     private final GameConfig config;
   433 	private final boolean netgame;
   433     private final boolean netgame;
   434 	
   434 
   435 	public SDLMain(int width, int height, GameConfig config, boolean netgame) {
   435     public SDLMain(int width, int height, GameConfig config, boolean netgame) {
   436 		surfaceWidth = width;
   436         surfaceWidth = width;
   437 		surfaceHeight = height;
   437         surfaceHeight = height;
   438 		if(netgame) {
   438         if(netgame) {
   439 			playerName = Netplay.getAppInstance(SDLActivity.getContext().getApplicationContext()).getPlayerName();
   439             playerName = Netplay.getAppInstance(SDLActivity.getContext().getApplicationContext()).getPlayerName();
   440 		} else {
   440         } else {
   441 			playerName = "Player";
   441             playerName = "Player";
   442 		}
   442         }
   443 		this.config = config;
   443         this.config = config;
   444 		this.netgame = netgame;
   444         this.netgame = netgame;
   445 	}
   445     }
   446 
   446 
   447 	public void run() {
   447     public void run() {
   448 		//Set up the IPC socket server to communicate with the engine
   448         //Set up the IPC socket server to communicate with the engine
   449 		GameConnection gameConn;
   449         GameConnection gameConn;
   450 		String path;
   450         String path;
   451 		try {
   451         try {
   452 			if(netgame) {
   452             if(netgame) {
   453 				Netplay netplay = Netplay.getAppInstance(SDLActivity.mSingleton.getApplicationContext());
   453                 Netplay netplay = Netplay.getAppInstance(SDLActivity.mSingleton.getApplicationContext());
   454 				gameConn = GameConnection.forNetgame(config, netplay);
   454                 gameConn = GameConnection.forNetgame(config, netplay);
   455 			} else {
   455             } else {
   456 				gameConn = GameConnection.forLocalGame(config);
   456                 gameConn = GameConnection.forLocalGame(config);
   457 			}
   457             }
   458 			
   458 
   459 			path = FileUtils.getDataPathFile(SDLActivity.mSingleton).getAbsolutePath();
   459             path = FileUtils.getDataPathFile(SDLActivity.mSingleton).getAbsolutePath();
   460 			Log.d(TAG, "Starting engine");
   460             Log.d(TAG, "Starting engine");
   461 			// Runs SDL_main() with added parameters
   461             // Runs SDL_main() with added parameters
   462 			try {
   462             try {
   463 				String pPort = String.valueOf(gameConn.port);
   463                 String pPort = String.valueOf(gameConn.port);
   464 				String pWidth = String.valueOf(surfaceWidth);
   464                 String pWidth = String.valueOf(surfaceWidth);
   465 				String pHeight = String.valueOf(surfaceHeight);
   465                 String pHeight = String.valueOf(surfaceHeight);
   466 				String pQuality = Integer.toString(RQ_NO_FLAKES|RQ_NO_DROPLETS|RQ_SIMPLE_EXPLOSIONS);
   466                 String pQuality = Integer.toString(RQ_NO_FLAKES|RQ_NO_DROPLETS|RQ_SIMPLE_EXPLOSIONS);
   467 				String pPlayerName = Base64.encodeToString(playerName.getBytes("UTF-8"), 0);
   467                 String pPlayerName = Base64.encodeToString(playerName.getBytes("UTF-8"), 0);
   468 				SDLActivity.synchronizedNativeInit(new String[] { pPort, pWidth, pHeight, pQuality, "en.txt", pPlayerName, "1", "1", "1", path, ""  });
   468                 SDLActivity.synchronizedNativeInit(new String[] { pPort, pWidth, pHeight, pQuality, "en.txt", pPlayerName, "1", "1", "1", path, ""  });
   469 			} catch (UnsupportedEncodingException e) {
   469             } catch (UnsupportedEncodingException e) {
   470 				throw new AssertionError(e); // never happens
   470                 throw new AssertionError(e); // never happens
   471 			}
   471             }
   472 			Log.d(TAG, "Engine stopped");
   472             Log.d(TAG, "Engine stopped");
   473 		} catch(ConnectException e) {
   473         } catch(ConnectException e) {
   474 			Log.e(TAG, "Error starting IPC connection");
   474             Log.e(TAG, "Error starting IPC connection");
   475 		} catch (IOException e) {
   475         } catch (IOException e) {
   476 			Log.e(TAG, "Missing SDCard");
   476             Log.e(TAG, "Missing SDCard");
   477 		}
   477         }
   478 		SDLActivity.mSingleton.runOnUiThread(new Runnable() { public void run() {
   478         SDLActivity.mSingleton.runOnUiThread(new Runnable() { public void run() {
   479 			if(SDLActivity.mSingleton != null) {
   479             if(SDLActivity.mSingleton != null) {
   480 				SDLActivity.mSingleton.finish();
   480                 SDLActivity.mSingleton.finish();
   481 			}
   481             }
   482 		}});
   482         }});
   483 	}
   483     }
   484 }
   484 }
   485 
   485 
   486 
   486 
   487 /**
   487 /**
   488     SDLSurface. This is what we draw on, so we need to know when it's created
   488     SDLSurface. This is what we draw on, so we need to know when it's created
   489     in order to do anything useful. 
   489     in order to do anything useful.
   490 
   490 
   491     Because of this, that's where we set up the SDL thread
   491     Because of this, that's where we set up the SDL thread
   492  */
   492  */
   493 class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, 
   493 class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
   494 View.OnKeyListener, View.OnTouchListener, SensorEventListener  {
   494 View.OnKeyListener, View.OnTouchListener, SensorEventListener  {
   495 
   495 
   496 	private GameConfig config;
   496     private GameConfig config;
   497 	private boolean netgame;
   497     private boolean netgame;
   498 	
   498 
   499 	// Sensors
   499     // Sensors
   500 	private static SensorManager mSensorManager;
   500     private static SensorManager mSensorManager;
   501 
   501 
   502 	// Startup    
   502     // Startup
   503 	public SDLSurface(Context context, GameConfig _config, boolean netgame) {
   503     public SDLSurface(Context context, GameConfig _config, boolean netgame) {
   504 		super(context);
   504         super(context);
   505 		getHolder().addCallback(this); 
   505         getHolder().addCallback(this);
   506 
   506 
   507 		setFocusable(true);
   507         setFocusable(true);
   508 		setFocusableInTouchMode(true);
   508         setFocusableInTouchMode(true);
   509 		requestFocus();
   509         requestFocus();
   510 		setOnKeyListener(this); 
   510         setOnKeyListener(this);
   511 		setOnTouchListener(this);   
   511         setOnTouchListener(this);
   512 
   512 
   513 		mSensorManager = (SensorManager)context.getSystemService("sensor");
   513         mSensorManager = (SensorManager)context.getSystemService("sensor");
   514 		config = _config;
   514         config = _config;
   515 		this.netgame = netgame;
   515         this.netgame = netgame;
   516 	}
   516     }
   517 
   517 
   518 	// Called when we have a valid drawing surface
   518     // Called when we have a valid drawing surface
   519 	public void surfaceCreated(SurfaceHolder holder) {
   519     public void surfaceCreated(SurfaceHolder holder) {
   520 		Log.v("SDL", "surfaceCreated()");
   520         Log.v("SDL", "surfaceCreated()");
   521 		holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
   521         holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
   522 		SDLActivity.createEGLSurface();
   522         SDLActivity.createEGLSurface();
   523 		//		enableSensor(Sensor.TYPE_ACCELEROMETER, true);
   523         //      enableSensor(Sensor.TYPE_ACCELEROMETER, true);
   524 	}
   524     }
   525 
   525 
   526 	// Called when we lose the surface
   526     // Called when we lose the surface
   527 	public void surfaceDestroyed(SurfaceHolder holder) {
   527     public void surfaceDestroyed(SurfaceHolder holder) {
   528 		Log.v("SDL", "surfaceDestroyed()");
   528         Log.v("SDL", "surfaceDestroyed()");
   529 		SDLActivity.nativePause();
   529         SDLActivity.nativePause();
   530 		//		enableSensor(Sensor.TYPE_ACCELEROMETER, false);
   530         //      enableSensor(Sensor.TYPE_ACCELEROMETER, false);
   531 	}
   531     }
   532 
   532 
   533 	// Called when the surface is resized
   533     // Called when the surface is resized
   534 	public void surfaceChanged(SurfaceHolder holder,
   534     public void surfaceChanged(SurfaceHolder holder,
   535 			int format, int width, int height) {
   535             int format, int width, int height) {
   536 		Log.v("SDL", "surfaceChanged()");
   536         Log.v("SDL", "surfaceChanged()");
   537 
   537 
   538 		int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default
   538         int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default
   539 		switch (format) {
   539         switch (format) {
   540 		case PixelFormat.A_8:
   540         case PixelFormat.A_8:
   541 			Log.v("SDL", "pixel format A_8");
   541             Log.v("SDL", "pixel format A_8");
   542 			break;
   542             break;
   543 		case PixelFormat.LA_88:
   543         case PixelFormat.LA_88:
   544 			Log.v("SDL", "pixel format LA_88");
   544             Log.v("SDL", "pixel format LA_88");
   545 			break;
   545             break;
   546 		case PixelFormat.L_8:
   546         case PixelFormat.L_8:
   547 			Log.v("SDL", "pixel format L_8");
   547             Log.v("SDL", "pixel format L_8");
   548 			break;
   548             break;
   549 		case PixelFormat.RGBA_4444:
   549         case PixelFormat.RGBA_4444:
   550 			Log.v("SDL", "pixel format RGBA_4444");
   550             Log.v("SDL", "pixel format RGBA_4444");
   551 			sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444
   551             sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444
   552 			break;
   552             break;
   553 		case PixelFormat.RGBA_5551:
   553         case PixelFormat.RGBA_5551:
   554 			Log.v("SDL", "pixel format RGBA_5551");
   554             Log.v("SDL", "pixel format RGBA_5551");
   555 			sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551
   555             sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551
   556 			break;
   556             break;
   557 		case PixelFormat.RGBA_8888:
   557         case PixelFormat.RGBA_8888:
   558 			Log.v("SDL", "pixel format RGBA_8888");
   558             Log.v("SDL", "pixel format RGBA_8888");
   559 			sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888
   559             sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888
   560 			break;
   560             break;
   561 		case PixelFormat.RGBX_8888:
   561         case PixelFormat.RGBX_8888:
   562 			Log.v("SDL", "pixel format RGBX_8888");
   562             Log.v("SDL", "pixel format RGBX_8888");
   563 			sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888
   563             sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888
   564 			break;
   564             break;
   565 		case PixelFormat.RGB_332:
   565         case PixelFormat.RGB_332:
   566 			Log.v("SDL", "pixel format RGB_332");
   566             Log.v("SDL", "pixel format RGB_332");
   567 			sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332
   567             sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332
   568 			break;
   568             break;
   569 		case PixelFormat.RGB_565:
   569         case PixelFormat.RGB_565:
   570 			Log.v("SDL", "pixel format RGB_565");
   570             Log.v("SDL", "pixel format RGB_565");
   571 			sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565
   571             sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565
   572 			break;
   572             break;
   573 		case PixelFormat.RGB_888:
   573         case PixelFormat.RGB_888:
   574 			Log.v("SDL", "pixel format RGB_888");
   574             Log.v("SDL", "pixel format RGB_888");
   575 			// Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
   575             // Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
   576 			sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888
   576             sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888
   577 			break;
   577             break;
   578 		default:
   578         default:
   579 			Log.v("SDL", "pixel format unknown " + format);
   579             Log.v("SDL", "pixel format unknown " + format);
   580 			break;
   580             break;
   581 		}
   581         }
   582 		SDLActivity.onNativeResize(width, height, sdlFormat);
   582         SDLActivity.onNativeResize(width, height, sdlFormat);
   583 		Log.v("SDL", "Window size:" + width + "x"+height);
   583         Log.v("SDL", "Window size:" + width + "x"+height);
   584 
   584 
   585 		SDLActivity.startApp(width, height, config, netgame);
   585         SDLActivity.startApp(width, height, config, netgame);
   586 	}
   586     }
   587 
   587 
   588 	// unused
   588     // unused
   589 	public void onDraw(Canvas canvas) {}
   589     public void onDraw(Canvas canvas) {}
   590 
   590 
   591 
   591 
   592 
   592 
   593 
   593 
   594 	// Key events
   594     // Key events
   595 	public boolean onKey(View  v, int keyCode, KeyEvent event) {
   595     public boolean onKey(View  v, int keyCode, KeyEvent event) {
   596 		switch(keyCode){
   596         switch(keyCode){
   597 		case KeyEvent.KEYCODE_BACK:
   597         case KeyEvent.KEYCODE_BACK:
   598 			Log.d("SDL", "KEYCODE_BACK");
   598             Log.d("SDL", "KEYCODE_BACK");
   599 			SDLActivity.nativeQuit();
   599             SDLActivity.nativeQuit();
   600             return true;
   600             return true;
   601 		case KeyEvent.KEYCODE_VOLUME_DOWN:
   601         case KeyEvent.KEYCODE_VOLUME_DOWN:
   602 		case KeyEvent.KEYCODE_VOLUME_UP:
   602         case KeyEvent.KEYCODE_VOLUME_UP:
   603 		case KeyEvent.KEYCODE_VOLUME_MUTE:
   603         case KeyEvent.KEYCODE_VOLUME_MUTE:
   604 			return false;
   604             return false;
   605 		}
   605         }
   606 		if (event.getAction() == KeyEvent.ACTION_DOWN) {
   606         if (event.getAction() == KeyEvent.ACTION_DOWN) {
   607 			//Log.v("SDL", "key down: " + keyCode);
   607             //Log.v("SDL", "key down: " + keyCode);
   608 			SDLActivity.onNativeKeyDown(keyCode);
   608             SDLActivity.onNativeKeyDown(keyCode);
   609 			return true;
   609             return true;
   610 		}
   610         }
   611 		else if (event.getAction() == KeyEvent.ACTION_UP) {
   611         else if (event.getAction() == KeyEvent.ACTION_UP) {
   612 			//Log.v("SDL", "key up: " + keyCode);
   612             //Log.v("SDL", "key up: " + keyCode);
   613 			SDLActivity.onNativeKeyUp(keyCode);
   613             SDLActivity.onNativeKeyUp(keyCode);
   614 			return true;
   614             return true;
   615 		}
   615         }
   616 
   616 
   617 		return false;
   617         return false;
   618 	}
   618     }
   619 
   619 
   620 	// Touch events
   620     // Touch events
   621 	public boolean onTouch(View v, MotionEvent event) {
   621     public boolean onTouch(View v, MotionEvent event) {
   622 		final int action = event.getAction() & MotionEvent.ACTION_MASK;
   622         final int action = event.getAction() & MotionEvent.ACTION_MASK;
   623 		final int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;		
   623         final int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
   624 
   624 
   625 		if (action == MotionEvent.ACTION_MOVE) {
   625         if (action == MotionEvent.ACTION_MOVE) {
   626 			// TODO send motion to every pointer if its position has
   626             // TODO send motion to every pointer if its position has
   627 			// changed since prev event.
   627             // changed since prev event.
   628 			for (int i = 0; i < event.getPointerCount(); i++) {
   628             for (int i = 0; i < event.getPointerCount(); i++) {
   629 				sendNativeTouch(event, action, i);
   629                 sendNativeTouch(event, action, i);
   630 			}
   630             }
   631 		} else {
   631         } else {
   632 			sendNativeTouch(event, action, actionPointerIndex);
   632             sendNativeTouch(event, action, actionPointerIndex);
   633 		}
   633         }
   634 		return true;
   634         return true;
   635 	} 
   635     }
   636 	
   636 
   637 	private static void sendNativeTouch(MotionEvent event, int action, int pointerIndex) {
   637     private static void sendNativeTouch(MotionEvent event, int action, int pointerIndex) {
   638 		int touchDevId = event.getDeviceId();
   638         int touchDevId = event.getDeviceId();
   639 		int pointerFingerId = event.getPointerId(pointerIndex);
   639         int pointerFingerId = event.getPointerId(pointerIndex);
   640 		float x = event.getX(pointerIndex);
   640         float x = event.getX(pointerIndex);
   641 		float y = event.getY(pointerIndex);
   641         float y = event.getY(pointerIndex);
   642 		float pressure = event.getPressure(pointerIndex);
   642         float pressure = event.getPressure(pointerIndex);
   643 		SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, pressure);
   643         SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, pressure);
   644 	}
   644     }
   645 
   645 
   646 	// Sensor events
   646     // Sensor events
   647 	public void enableSensor(int sensortype, boolean enabled) {
   647     public void enableSensor(int sensortype, boolean enabled) {
   648 		// TODO: This uses getDefaultSensor - what if we have >1 accels?
   648         // TODO: This uses getDefaultSensor - what if we have >1 accels?
   649 		if (enabled) {
   649         if (enabled) {
   650 			mSensorManager.registerListener(this, 
   650             mSensorManager.registerListener(this,
   651 					mSensorManager.getDefaultSensor(sensortype), 
   651                     mSensorManager.getDefaultSensor(sensortype),
   652 					SensorManager.SENSOR_DELAY_GAME, null);
   652                     SensorManager.SENSOR_DELAY_GAME, null);
   653 		} else {
   653         } else {
   654 			mSensorManager.unregisterListener(this, 
   654             mSensorManager.unregisterListener(this,
   655 					mSensorManager.getDefaultSensor(sensortype));
   655                     mSensorManager.getDefaultSensor(sensortype));
   656 		}
   656         }
   657 	}
   657     }
   658 
   658 
   659 	public void onAccuracyChanged(Sensor sensor, int accuracy) {
   659     public void onAccuracyChanged(Sensor sensor, int accuracy) {
   660 		// TODO
   660         // TODO
   661 	}
   661     }
   662 
   662 
   663 	public void onSensorChanged(SensorEvent event) {
   663     public void onSensorChanged(SensorEvent event) {
   664 		if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
   664         if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
   665 			SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH,
   665             SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH,
   666 					event.values[1] / SensorManager.GRAVITY_EARTH,
   666                     event.values[1] / SensorManager.GRAVITY_EARTH,
   667 					event.values[2] / SensorManager.GRAVITY_EARTH);
   667                     event.values[2] / SensorManager.GRAVITY_EARTH);
   668 		}
   668         }
   669 	}
   669     }
   670 }
   670 }
   671 
   671