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