1 // This string is autogenerated by ChangeAppSettings.sh, do not change spaces amount 2 package org.warmux; 3 4 import javax.microedition.khronos.opengles.GL10; 5 6 import javax.microedition.khronos.egl.EGL10; 7 import javax.microedition.khronos.egl.EGL11; 8 import javax.microedition.khronos.egl.EGLConfig; 9 import javax.microedition.khronos.egl.EGLContext; 10 import javax.microedition.khronos.egl.EGLDisplay; 11 import javax.microedition.khronos.egl.EGLSurface; 12 13 import android.app.Activity; 14 import android.content.Context; 15 import android.os.Bundle; 16 import android.view.MotionEvent; 17 import android.view.KeyEvent; 18 import android.view.Window; 19 import android.view.WindowManager; 20 import android.os.Environment; 21 import java.io.File; 22 23 import android.widget.TextView; 24 import java.lang.Thread; 25 import java.util.concurrent.locks.ReentrantLock; 26 import android.os.Build; 27 import java.lang.reflect.Method; 28 import java.util.LinkedList; 29 30 // For mail 31 import android.content.Intent; 32 import android.net.Uri; 33 import java.util.ArrayList; 34 35 abstract class DifferentTouchInput 36 { getInstance()37 public static DifferentTouchInput getInstance() 38 { 39 boolean multiTouchAvailable1 = false; 40 boolean multiTouchAvailable2 = false; 41 // Not checking for getX(int), getY(int) etc 'cause I'm lazy 42 Method methods [] = MotionEvent.class.getDeclaredMethods(); 43 for(Method m: methods) 44 { 45 if( m.getName().equals("getPointerCount") ) 46 multiTouchAvailable1 = true; 47 if( m.getName().equals("getPointerId") ) 48 multiTouchAvailable2 = true; 49 } 50 51 if (multiTouchAvailable1 && multiTouchAvailable2) 52 return MultiTouchInput.Holder.sInstance; 53 else 54 return SingleTouchInput.Holder.sInstance; 55 } process(final MotionEvent event)56 public abstract void process(final MotionEvent event); 57 private static class SingleTouchInput extends DifferentTouchInput 58 { 59 private static class Holder 60 { 61 private static final SingleTouchInput sInstance = new SingleTouchInput(); 62 } process(final MotionEvent event)63 public void process(final MotionEvent event) 64 { 65 int action = -1; 66 if( event.getAction() == MotionEvent.ACTION_DOWN ) 67 action = 0; 68 if( event.getAction() == MotionEvent.ACTION_UP ) 69 action = 1; 70 if( event.getAction() == MotionEvent.ACTION_MOVE ) 71 action = 2; 72 if ( action >= 0 ) 73 DemoGLSurfaceView.nativeMouse( (int)event.getX(), (int)event.getY(), action, 0, 74 (int)(event.getPressure() * 1000.0), 75 (int)(event.getSize() * 1000.0) ); 76 } 77 } 78 private static class MultiTouchInput extends DifferentTouchInput 79 { 80 81 private static final int touchEventMax = 16; // Max multitouch pointers 82 83 private class touchEvent 84 { 85 public boolean down = false; 86 public int x = 0; 87 public int y = 0; 88 public int pressure = 0; 89 public int size = 0; 90 } 91 92 private touchEvent touchEvents[]; 93 MultiTouchInput()94 MultiTouchInput() 95 { 96 touchEvents = new touchEvent[touchEventMax]; 97 for( int i = 0; i < touchEventMax; i++ ) 98 touchEvents[i] = new touchEvent(); 99 } 100 101 private static class Holder 102 { 103 private static final MultiTouchInput sInstance = new MultiTouchInput(); 104 } process(final MotionEvent event)105 public void process(final MotionEvent event) 106 { 107 int action = -1; 108 109 if( event.getAction() == MotionEvent.ACTION_UP ) 110 { 111 action = 1; 112 for( int i = 0; i < touchEventMax; i++ ) 113 { 114 if( touchEvents[i].down ) 115 { 116 touchEvents[i].down = false; 117 DemoGLSurfaceView.nativeMouse( touchEvents[i].x, touchEvents[i].y, action, i, touchEvents[i].pressure, touchEvents[i].size ); 118 } 119 } 120 } 121 if( event.getAction() == MotionEvent.ACTION_DOWN ) 122 { 123 action = 0; 124 for( int i = 0; i < event.getPointerCount(); i++ ) 125 { 126 int id = event.getPointerId(i); 127 if( id >= touchEventMax ) 128 id = touchEventMax-1; 129 touchEvents[id].down = true; 130 touchEvents[id].x = (int)event.getX(i); 131 touchEvents[id].y = (int)event.getY(i); 132 touchEvents[id].pressure = (int)(event.getPressure(i) * 1000.0); 133 touchEvents[id].size = (int)(event.getSize(i) * 1000.0); 134 DemoGLSurfaceView.nativeMouse( touchEvents[i].x, touchEvents[i].y, action, id, touchEvents[i].pressure, touchEvents[i].size ); 135 } 136 } 137 138 if( event.getAction() == MotionEvent.ACTION_MOVE ) 139 { 140 for( int i = 0; i < touchEventMax; i++ ) 141 { 142 int ii; 143 for( ii = 0; ii < event.getPointerCount(); ii++ ) 144 { 145 if( i == event.getPointerId(ii) ) 146 break; 147 } 148 if( ii >= event.getPointerCount() ) 149 { 150 // Up event 151 if( touchEvents[i].down ) 152 { 153 action = 1; 154 touchEvents[i].down = false; 155 DemoGLSurfaceView.nativeMouse( touchEvents[i].x, touchEvents[i].y, action, i, touchEvents[i].pressure, touchEvents[i].size ); 156 } 157 } 158 else 159 { 160 int id = event.getPointerId(ii); 161 if( id >= touchEventMax ) 162 id = touchEventMax-1; 163 if( touchEvents[id].down ) 164 action = 2; 165 else 166 action = 0; 167 touchEvents[id].down = true; 168 touchEvents[id].x = (int)event.getX(i); 169 touchEvents[id].y = (int)event.getY(i); 170 touchEvents[id].pressure = (int)(event.getPressure(i) * 1000.0); 171 touchEvents[id].size = (int)(event.getSize(i) * 1000.0); 172 DemoGLSurfaceView.nativeMouse( touchEvents[i].x, touchEvents[i].y, action, id, touchEvents[i].pressure, touchEvents[i].size ); 173 } 174 } 175 } 176 } 177 } 178 } 179 180 181 class DemoRenderer extends GLSurfaceView_SDL.Renderer { 182 DemoRenderer(MainActivity _context)183 public DemoRenderer(MainActivity _context) 184 { 185 context = _context; 186 } 187 onSurfaceCreated(GL10 gl, EGLConfig config)188 public void onSurfaceCreated(GL10 gl, EGLConfig config) { 189 System.out.println("libSDL: DemoRenderer.onSurfaceCreated(): paused " + mPaused + " mFirstTimeStart " + mFirstTimeStart ); 190 mGlSurfaceCreated = true; 191 if( ! mPaused && ! mFirstTimeStart ) 192 nativeGlContextRecreated(); 193 mFirstTimeStart = false; 194 } 195 onSurfaceChanged(GL10 gl, int w, int h)196 public void onSurfaceChanged(GL10 gl, int w, int h) { 197 nativeResize(w, h, Globals.KeepAspectRatio ? 1 : 0); 198 } 199 onSurfaceDestroyed()200 public void onSurfaceDestroyed() { 201 mGlSurfaceCreated = false; 202 mGlContextLost = true; 203 nativeGlContextLost(); 204 }; 205 onDrawFrame(GL10 gl)206 public void onDrawFrame(GL10 gl) { 207 208 nativeInitJavaCallbacks(); 209 210 // Make main thread priority lower so audio thread won't get underrun 211 // Thread.currentThread().setPriority((Thread.currentThread().getPriority() + Thread.MIN_PRIORITY)/2); 212 213 mGlContextLost = false; 214 215 String libs[] = { "application", "sdl_main" }; 216 try 217 { 218 for(String l : libs) 219 { 220 System.loadLibrary(l); 221 } 222 } 223 catch ( UnsatisfiedLinkError e ) 224 { 225 for(String l : libs) 226 { 227 String libname = System.mapLibraryName(l); 228 File libpath = new File(context.getCacheDir(), libname); 229 System.out.println("libSDL: loading lib " + libpath.getPath()); 230 System.load(libpath.getPath()); 231 libpath.delete(); 232 } 233 } 234 235 Settings.Apply(context); 236 accelerometer = new AccelerometerReader(context); 237 URLDownloader tmp = new URLDownloader(); 238 // Tweak video thread priority, if user selected big audio buffer 239 if(Globals.AudioBufferConfig >= 2) 240 Thread.currentThread().setPriority( (Thread.NORM_PRIORITY + Thread.MIN_PRIORITY) / 2 ); // Lower than normal 241 nativeInit( Globals.DataDir, 242 Globals.CommandLine, 243 ( Globals.SwVideoMode && Globals.MultiThreadedVideo ) ? 1 : 0 ); 244 { 245 //need to "send multiple" to get more than one attachment 246 final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE); 247 emailIntent.setType("plain/text"); 248 emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "kurosu@free.fr"); 249 emailIntent.putExtra(Intent.EXTRA_SUBJECT, "[Warmux] Automatic debug output"); 250 //has to be an ArrayList 251 ArrayList<Uri> uris = new ArrayList<Uri>(); 252 //convert from paths to Android friendly Parcelable Uri's 253 uris.add(Uri.parse("file:///sdcard/Warmux/stdout.txt")); 254 uris.add(Uri.parse("file:///sdcard/Warmux/stderr.txt")); 255 emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); 256 context.startActivity(Intent.createChooser(emailIntent, "Send mail...")); 257 } 258 System.exit(0); // The main() returns here - I don't bother with deinit stuff, just terminate process 259 } 260 swapBuffers()261 public int swapBuffers() // Called from native code 262 { 263 synchronized(this) { 264 this.notify(); 265 } 266 if( ! super.SwapBuffers() && Globals.NonBlockingSwapBuffers ) 267 return 0; 268 if(mGlContextLost) { 269 mGlContextLost = false; 270 Settings.SetupTouchscreenKeyboardGraphics(context); // Reload on-screen buttons graphics 271 } 272 273 return 1; 274 } 275 showScreenKeyboard(final String oldText, int sendBackspace)276 public void showScreenKeyboard(final String oldText, int sendBackspace) // Called from native code 277 { 278 class Callback implements Runnable 279 { 280 public MainActivity parent; 281 public String oldText; 282 public boolean sendBackspace; 283 public void run() 284 { 285 parent.showScreenKeyboard(oldText, sendBackspace); 286 } 287 } 288 Callback cb = new Callback(); 289 cb.parent = context; 290 cb.oldText = oldText; 291 cb.sendBackspace = (sendBackspace != 0); 292 context.runOnUiThread(cb); 293 } 294 exitApp()295 public void exitApp() { 296 nativeDone(); 297 }; 298 nativeInitJavaCallbacks()299 private native void nativeInitJavaCallbacks(); nativeInit(String CurrentPath, String CommandLine, int multiThreadedVideo)300 private native void nativeInit(String CurrentPath, String CommandLine, int multiThreadedVideo); nativeResize(int w, int h, int keepAspectRatio)301 private native void nativeResize(int w, int h, int keepAspectRatio); nativeDone()302 private native void nativeDone(); nativeGlContextLost()303 private native void nativeGlContextLost(); nativeGlContextRecreated()304 public native void nativeGlContextRecreated(); nativeTextInput( int ascii, int unicode )305 public static native void nativeTextInput( int ascii, int unicode ); nativeTextInputFinished()306 public static native void nativeTextInputFinished(); 307 308 private MainActivity context = null; 309 private AccelerometerReader accelerometer = null; 310 311 private EGL10 mEgl = null; 312 private EGLDisplay mEglDisplay = null; 313 private EGLSurface mEglSurface = null; 314 private EGLContext mEglContext = null; 315 private boolean mGlContextLost = false; 316 public boolean mGlSurfaceCreated = false; 317 public boolean mPaused = false; 318 private boolean mFirstTimeStart = true; 319 } 320 321 class DemoGLSurfaceView extends GLSurfaceView_SDL { DemoGLSurfaceView(MainActivity context)322 public DemoGLSurfaceView(MainActivity context) { 323 super(context); 324 mParent = context; 325 touchInput = DifferentTouchInput.getInstance(); 326 setEGLConfigChooser(Globals.NeedDepthBuffer); 327 mRenderer = new DemoRenderer(context); 328 setRenderer(mRenderer); 329 } 330 331 @Override onTouchEvent(final MotionEvent event)332 public boolean onTouchEvent(final MotionEvent event) 333 { 334 touchInput.process(event); 335 // Wait a bit, and try to synchronize to app framerate, or event thread will eat all CPU and we'll lose FPS 336 if( event.getAction() == MotionEvent.ACTION_MOVE ) { 337 synchronized(mRenderer) { 338 try { 339 mRenderer.wait(300L); 340 } catch (InterruptedException e) { } 341 } 342 } 343 return true; 344 }; 345 exitApp()346 public void exitApp() { 347 mRenderer.exitApp(); 348 }; 349 350 @Override onPause()351 public void onPause() { 352 super.onPause(); 353 mRenderer.mPaused = true; 354 }; 355 isPaused()356 public boolean isPaused() { 357 return mRenderer.mPaused; 358 } 359 360 @Override onResume()361 public void onResume() { 362 super.onResume(); 363 mRenderer.mPaused = false; 364 System.out.println("libSDL: DemoGLSurfaceView.onResume(): mRenderer.mGlSurfaceCreated " + mRenderer.mGlSurfaceCreated + " mRenderer.mPaused " + mRenderer.mPaused); 365 if( mRenderer.mGlSurfaceCreated && ! mRenderer.mPaused || Globals.NonBlockingSwapBuffers ) 366 mRenderer.nativeGlContextRecreated(); 367 }; 368 369 @Override onKeyDown(int keyCode, final KeyEvent event)370 public boolean onKeyDown(int keyCode, final KeyEvent event) { 371 nativeKey( keyCode, 1 ); 372 return true; 373 } 374 375 @Override onKeyUp(int keyCode, final KeyEvent event)376 public boolean onKeyUp(int keyCode, final KeyEvent event) { 377 nativeKey( keyCode, 0 ); 378 return true; 379 } 380 381 DemoRenderer mRenderer; 382 MainActivity mParent; 383 DifferentTouchInput touchInput = null; 384 nativeMouse( int x, int y, int action, int pointerId, int pressure, int radius )385 public static native void nativeMouse( int x, int y, int action, int pointerId, int pressure, int radius ); nativeKey( int keyCode, int down )386 public static native void nativeKey( int keyCode, int down ); initJavaCallbacks()387 public static native void initJavaCallbacks(); 388 389 } 390 391 392