* Removed various misc handling code from AndroidHarness to OGLESContext/JmeAndroidSystem to ease using jME3 outside of AndroidHarness

* Misc formatting changes in AndroidConfigChooser
 * AndroidLogHandler now takes parameters into account
 * Added additional settings in AppSettings to configure mouse emulation
 * JmeSystem will now automatically try to load JmeAndroidSystem if it fails to load JmeDesktopSystem

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9407 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Sha..rd 13 years ago
parent 05d5c611e1
commit 29b2596359
  1. 87
      engine/src/android/com/jme3/app/AndroidHarness.java
  2. 2
      engine/src/android/com/jme3/asset/plugins/AndroidLocator.java
  3. 41
      engine/src/android/com/jme3/input/android/AndroidInput.java
  4. 6
      engine/src/android/com/jme3/system/android/AndroidConfigChooser.java
  5. 67
      engine/src/android/com/jme3/system/android/JmeAndroidSystem.java
  6. 94
      engine/src/android/com/jme3/system/android/OGLESContext.java
  7. 3
      engine/src/android/com/jme3/util/AndroidLogHandler.java
  8. 8
      engine/src/core/com/jme3/input/TouchInput.java
  9. 42
      engine/src/core/com/jme3/system/AppSettings.java
  10. 27
      engine/src/core/com/jme3/system/JmeSystem.java

@ -16,7 +16,6 @@ import android.widget.TextView;
import com.jme3.audio.AudioRenderer; import com.jme3.audio.AudioRenderer;
import com.jme3.audio.android.AndroidAudioRenderer; import com.jme3.audio.android.AndroidAudioRenderer;
import com.jme3.input.TouchInput; import com.jme3.input.TouchInput;
import com.jme3.input.android.AndroidInput;
import com.jme3.input.controls.TouchListener; import com.jme3.input.controls.TouchListener;
import com.jme3.input.controls.TouchTrigger; import com.jme3.input.controls.TouchTrigger;
import com.jme3.input.event.TouchEvent; import com.jme3.input.event.TouchEvent;
@ -26,10 +25,8 @@ import com.jme3.system.SystemListener;
import com.jme3.system.android.AndroidConfigChooser.ConfigType; import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import com.jme3.system.android.JmeAndroidSystem; import com.jme3.system.android.JmeAndroidSystem;
import com.jme3.system.android.OGLESContext; import com.jme3.system.android.OGLESContext;
import com.jme3.util.JmeFormatter;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.logging.Handler;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -43,52 +40,64 @@ import java.util.logging.Logger;
public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener, SystemListener { public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener, SystemListener {
protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName()); protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName());
/** /**
* The application class to start * The application class to start
*/ */
protected String appClass = "jme3test.android.Test"; protected String appClass = "jme3test.android.Test";
/** /**
* The jme3 application object * The jme3 application object
*/ */
protected Application app = null; protected Application app = null;
/** /**
* ConfigType.FASTEST is RGB565, GLSurfaceView default ConfigType.BEST is * ConfigType.FASTEST is RGB565, GLSurfaceView default ConfigType.BEST is
* RGBA8888 or better if supported by the hardware * RGBA8888 or better if supported by the hardware
*/ */
protected ConfigType eglConfigType = ConfigType.FASTEST; protected ConfigType eglConfigType = ConfigType.FASTEST;
/** /**
* If true all valid and not valid egl configs are logged * If true all valid and not valid egl configs are logged
*/ */
protected boolean eglConfigVerboseLogging = false; protected boolean eglConfigVerboseLogging = false;
/** /**
* If true MouseEvents are generated from TouchEvents * If true MouseEvents are generated from TouchEvents
*/ */
protected boolean mouseEventsEnabled = true; protected boolean mouseEventsEnabled = true;
/** /**
* Flip X axis * Flip X axis
*/ */
protected boolean mouseEventsInvertX = true; protected boolean mouseEventsInvertX = true;
/** /**
* Flip Y axis * Flip Y axis
*/ */
protected boolean mouseEventsInvertY = true; protected boolean mouseEventsInvertY = true;
/** /**
* if true finish this activity when the jme app is stopped * if true finish this activity when the jme app is stopped
*/ */
protected boolean finishOnAppStop = true; protected boolean finishOnAppStop = true;
/** /**
* set to false if you don't want the harness to handle the exit hook * set to false if you don't want the harness to handle the exit hook
*/ */
protected boolean handleExitHook = true; protected boolean handleExitHook = true;
/** /**
* Title of the exit dialog, default is "Do you want to exit?" * Title of the exit dialog, default is "Do you want to exit?"
*/ */
protected String exitDialogTitle = "Do you want to exit?"; protected String exitDialogTitle = "Do you want to exit?";
/** /**
* Message of the exit dialog, default is "Use your home key to bring this * Message of the exit dialog, default is "Use your home key to bring this
* app into the background or exit to terminate it." * app into the background or exit to terminate it."
*/ */
protected String exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it."; protected String exitDialogMessage = "Use your home key to bring this app into the background or exit to terminate it.";
/** /**
* Set the screen window mode. If screenFullSize is true, then the * Set the screen window mode. If screenFullSize is true, then the
* notification bar and title bar are removed and the screen covers the * notification bar and title bar are removed and the screen covers the
@ -97,17 +106,20 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
* false, then the title bar is also displayed under the notification bar. * false, then the title bar is also displayed under the notification bar.
*/ */
protected boolean screenFullScreen = true; protected boolean screenFullScreen = true;
/** /**
* if screenShowTitle is true while screenFullScreen is false, then the * if screenShowTitle is true while screenFullScreen is false, then the
* title bar is also displayed under the notification bar * title bar is also displayed under the notification bar
*/ */
protected boolean screenShowTitle = true; protected boolean screenShowTitle = true;
/** /**
* Splash Screen picture Resource ID. If a Splash Screen is desired, set * Splash Screen picture Resource ID. If a Splash Screen is desired, set
* splashPicID to the value of the Resource ID (i.e. R.drawable.picname). If * splashPicID to the value of the Resource ID (i.e. R.drawable.picname). If
* splashPicID = 0, then no splash screen will be displayed. * splashPicID = 0, then no splash screen will be displayed.
*/ */
protected int splashPicID = 0; protected int splashPicID = 0;
/** /**
* Set the screen orientation, default is SENSOR * Set the screen orientation, default is SENSOR
* ActivityInfo.SCREEN_ORIENTATION_* constants package * ActivityInfo.SCREEN_ORIENTATION_* constants package
@ -127,36 +139,11 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
final private String ESCAPE_EVENT = "TouchEscape"; final private String ESCAPE_EVENT = "TouchEscape";
private boolean firstDrawFrame = true; private boolean firstDrawFrame = true;
static {
try {
System.loadLibrary("bulletjme");
} catch (UnsatisfiedLinkError e) {
}
JmeSystem.setSystemDelegate(new JmeAndroidSystem());
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Logger log = logger;
boolean bIsLogFormatSet = false;
do {
if (log.getHandlers().length == 0) {
log = logger.getParent();
if (log != null) {
for (Handler h : log.getHandlers()) {
//h.setFormatter(new SimpleFormatter());
h.setFormatter(new JmeFormatter());
bIsLogFormatSet = true;
}
}
}
} while (log != null && !bIsLogFormatSet);
JmeAndroidSystem.setResources(getResources());
JmeAndroidSystem.setActivity(this); JmeAndroidSystem.setActivity(this);
if (screenFullScreen) { if (screenFullScreen) {
requestWindowFeature(Window.FEATURE_NO_TITLE); requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
@ -171,12 +158,8 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
// Create Settings // Create Settings
AppSettings settings = new AppSettings(true); AppSettings settings = new AppSettings(true);
settings.setEmulateMouse(mouseEventsEnabled);
// Create the input class settings.setEmulateMouseFlipAxis(mouseEventsInvertX, mouseEventsInvertY);
AndroidInput input = new AndroidInput(this);
input.setMouseEventsInvertX(mouseEventsInvertX);
input.setMouseEventsInvertY(mouseEventsInvertY);
input.setMouseEventsEnabled(mouseEventsEnabled);
// Create application instance // Create application instance
try { try {
@ -189,16 +172,15 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
app.setSettings(settings); app.setSettings(settings);
app.start(); app.start();
ctx = (OGLESContext) app.getContext(); ctx = (OGLESContext) app.getContext();
view = ctx.createView(input, eglConfigType, eglConfigVerboseLogging); view = ctx.createView(eglConfigType, eglConfigVerboseLogging);
// Set the screen reolution // Set the screen reolution
WindowManager wind = this.getWindowManager(); // WindowManager wind = this.getWindowManager();
Display disp = wind.getDefaultDisplay(); // Display disp = wind.getDefaultDisplay();
ctx.getSettings().setResolution(disp.getWidth(), disp.getHeight()); // logger.log(Level.WARNING, "Resolution from Window: {0}, {1}", new Object[]{disp.getWidth(), disp.getHeight()});
// ctx.getSettings().setResolution(disp.getWidth(), disp.getHeight());
AppSettings s = ctx.getSettings(); // AndroidHarness wraps the app as a SystemListener.
logger.log(Level.INFO, "Settings: Width {0} Height {1}", new Object[]{s.getWidth(), s.getHeight()});
//setting the Harness as the system listener
ctx.setSystemListener(this); ctx.setSystemListener(this);
layoutDisplay(); layoutDisplay();
} catch (Exception ex) { } catch (Exception ex) {
@ -271,7 +253,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
logger.info("onStop"); logger.info("onStop");
} }
@ -280,7 +261,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
if (app != null) { if (app != null) {
app.stop(!isGLThreadPaused); app.stop(!isGLThreadPaused);
} }
logger.info("onDestroy"); logger.info("onDestroy");
super.onDestroy(); super.onDestroy();
} }
@ -293,6 +273,7 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
* Called when an error has occurred. By default, will show an error message * Called when an error has occurred. By default, will show an error message
* to the user and print the exception/error to the log. * to the user and print the exception/error to the log.
*/ */
@Override
public void handleError(final String errorMsg, final Throwable t) { public void handleError(final String errorMsg, final Throwable t) {
String stackTrace = ""; String stackTrace = "";
String title = "Error"; String title = "Error";
@ -441,14 +422,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
app.requestClose(esc); app.requestClose(esc);
} }
public void gainFocus() {
app.gainFocus();
}
public void loseFocus() {
app.loseFocus();
}
public void destroy() { public void destroy() {
if (app != null) { if (app != null) {
app.destroy(); app.destroy();
@ -457,4 +430,16 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt
finish(); finish();
} }
} }
public void gainFocus() {
if (app != null) {
app.gainFocus();
}
}
public void loseFocus() {
if (app != null) {
app.loseFocus();
}
}
} }

@ -58,7 +58,7 @@ public class AndroidLocator implements AssetLocator {
} }
public AndroidLocator() { public AndroidLocator() {
androidManager = JmeAndroidSystem.getResources().getAssets(); androidManager = JmeAndroidSystem.getActivity().getAssets();
} }
public void setRootPath(String rootPath) { public void setRootPath(String rootPath) {

@ -15,6 +15,7 @@ import com.jme3.input.event.MouseMotionEvent;
import com.jme3.input.event.TouchEvent; import com.jme3.input.event.TouchEvent;
import com.jme3.input.event.TouchEvent.Type; import com.jme3.input.event.TouchEvent.Type;
import com.jme3.math.Vector2f; import com.jme3.math.Vector2f;
import com.jme3.system.AppSettings;
import com.jme3.util.RingBuffer; import com.jme3.util.RingBuffer;
import java.util.HashMap; import java.util.HashMap;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -244,11 +245,9 @@ public class AndroidInput extends GLSurfaceView implements
bWasHandled = true; bWasHandled = true;
break; break;
case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_POINTER_UP:
case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP: case MotionEvent.ACTION_UP:
touch = getNextFreeTouchEvent(); touch = getNextFreeTouchEvent();
touch.set(Type.UP, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), 0, 0); touch.set(Type.UP, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), 0, 0);
touch.setPointerId(pointerId); touch.setPointerId(pointerId);
@ -256,12 +255,9 @@ public class AndroidInput extends GLSurfaceView implements
touch.setPressure(event.getPressure(pointerIndex)); touch.setPressure(event.getPressure(pointerIndex));
processEvent(touch); processEvent(touch);
bWasHandled = true; bWasHandled = true;
break; break;
case MotionEvent.ACTION_MOVE: case MotionEvent.ACTION_MOVE:
// Convert all pointers into events // Convert all pointers into events
for (int p = 0; p < event.getPointerCount(); p++) { for (int p = 0; p < event.getPointerCount(); p++) {
Vector2f lastPos = lastPositions.get(pointerIndex); Vector2f lastPos = lastPositions.get(pointerIndex);
@ -330,6 +326,12 @@ public class AndroidInput extends GLSurfaceView implements
return true; return true;
} }
} }
public void loadSettings(AppSettings settings) {
mouseEventsEnabled = settings.isEmulateMouse();
mouseEventsInvertX = settings.isEmulateMouseFlipX();
mouseEventsInvertY = settings.isEmulateMouseFlipY();
}
// ----------------------------------------- // -----------------------------------------
// JME3 Input interface // JME3 Input interface
@ -449,8 +451,6 @@ public class AndroidInput extends GLSurfaceView implements
lastY = newY; lastY = newY;
break; break;
} }
} }
} }
@ -574,15 +574,6 @@ public class AndroidInput extends GLSurfaceView implements
return true; return true;
} }
@Override
public void setSimulateMouse(boolean simulate) {
mouseEventsEnabled = simulate;
}
@Override
public boolean getSimulateMouse() {
return mouseEventsEnabled;
}
@Override @Override
public void setSimulateKeyboard(boolean simulate) { public void setSimulateKeyboard(boolean simulate) {
keyboardEventsEnabled = simulate; keyboardEventsEnabled = simulate;
@ -593,11 +584,15 @@ public class AndroidInput extends GLSurfaceView implements
this.dontSendHistory = dontSendHistory; this.dontSendHistory = dontSendHistory;
} }
// TODO: move to TouchInput /**
* @deprecated Use {@link #getSimulateMouse()};
*/
@Deprecated
public boolean isMouseEventsEnabled() { public boolean isMouseEventsEnabled() {
return mouseEventsEnabled; return mouseEventsEnabled;
} }
@Deprecated
public void setMouseEventsEnabled(boolean mouseEventsEnabled) { public void setMouseEventsEnabled(boolean mouseEventsEnabled) {
this.mouseEventsEnabled = mouseEventsEnabled; this.mouseEventsEnabled = mouseEventsEnabled;
} }
@ -617,4 +612,16 @@ public class AndroidInput extends GLSurfaceView implements
public void setMouseEventsInvertX(boolean mouseEventsInvertX) { public void setMouseEventsInvertX(boolean mouseEventsInvertX) {
this.mouseEventsInvertX = mouseEventsInvertX; this.mouseEventsInvertX = mouseEventsInvertX;
} }
public void setSimulateMouse(boolean simulate) {
mouseEventsEnabled = simulate;
}
public boolean getSimulateMouse() {
return isSimulateMouse();
}
public boolean isSimulateMouse() {
return mouseEventsEnabled;
}
} }

@ -31,10 +31,12 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* RGB565, 0 alpha, 16 depth, 0 stencil * RGB565, 0 alpha, 16 depth, 0 stencil
*/ */
FASTEST, FASTEST,
/** /**
* RGB???, 0 alpha, >=16 depth, 0 stencil * RGB???, 0 alpha, >=16 depth, 0 stencil
*/ */
BEST, BEST,
/** /**
* Turn off config chooser and use hardcoded * Turn off config chooser and use hardcoded
* setEGLContextClientVersion(2); setEGLConfigChooser(5, 6, 5, 0, 16, * setEGLContextClientVersion(2); setEGLConfigChooser(5, 6, 5, 0, 16,
@ -65,11 +67,9 @@ public class AndroidConfigChooser implements EGLConfigChooser {
* @return true if successfull, false if no config was found * @return true if successfull, false if no config was found
*/ */
public boolean findConfig(EGL10 egl, EGLDisplay display) { public boolean findConfig(EGL10 egl, EGLDisplay display) {
if (type == ConfigType.BEST) { if (type == ConfigType.BEST) {
ComponentSizeChooser compChooser = new ComponentSizeChooser(8, 8, 8, 8, 32, 0); ComponentSizeChooser compChooser = new ComponentSizeChooser(8, 8, 8, 8, 32, 0);
choosenConfig = compChooser.chooseConfig(egl, display); choosenConfig = compChooser.chooseConfig(egl, display);
if (choosenConfig == null) { if (choosenConfig == null) {
compChooser = new ComponentSizeChooser(8, 8, 8, 0, 32, 0); compChooser = new ComponentSizeChooser(8, 8, 8, 0, 32, 0);
choosenConfig = compChooser.chooseConfig(egl, display); choosenConfig = compChooser.chooseConfig(egl, display);
@ -97,7 +97,7 @@ public class AndroidConfigChooser implements EGLConfigChooser {
clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl); clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl);
return true; return true;
} else { } else {
logger.severe("###ERROR### Unable to get a valid OpenGL ES 2.0 config, nether Fastest nor Best found! Bug. Please report this."); logger.severe("ERROR: Unable to get a valid OpenGL ES 2.0 config, neither Fastest nor Best found! Bug. Please report this.");
clientOpenGLESVersion = 1; clientOpenGLESVersion = 1;
pixelFormat = PixelFormat.UNKNOWN; pixelFormat = PixelFormat.UNKNOWN;
return false; return false;

@ -1,8 +1,8 @@
package com.jme3.system.android; package com.jme3.system.android;
import android.app.Activity; import android.app.Activity;
import android.content.res.Resources;
import android.os.Environment; import android.os.Environment;
import android.util.Log;
import com.jme3.asset.AndroidAssetManager; import com.jme3.asset.AndroidAssetManager;
import com.jme3.asset.AssetManager; import com.jme3.asset.AssetManager;
import com.jme3.audio.AudioRenderer; import com.jme3.audio.AudioRenderer;
@ -12,27 +12,33 @@ import com.jme3.system.JmeContext;
import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeContext.Type;
import com.jme3.system.JmeSystemDelegate; import com.jme3.system.JmeSystemDelegate;
import com.jme3.system.Platform; import com.jme3.system.Platform;
import com.jme3.util.AndroidLogHandler;
import com.jme3.util.JmeFormatter; import com.jme3.util.JmeFormatter;
import java.io.File; import java.io.File;
import java.net.URL; import java.net.URL;
import java.util.logging.Handler; import java.util.logging.Handler;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger;
public class JmeAndroidSystem extends JmeSystemDelegate { public class JmeAndroidSystem extends JmeSystemDelegate {
private static Resources res;
private static Activity activity; private static Activity activity;
static {
try {
System.loadLibrary("bulletjme");
} catch (UnsatisfiedLinkError e) {
}
}
@Override @Override
public AssetManager newAssetManager(URL configFile) { public AssetManager newAssetManager(URL configFile) {
logger.log(Level.INFO, "newAssetManager({0})", configFile); logger.log(Level.INFO, "Creating asset manager with config {0}", configFile);
return new AndroidAssetManager(configFile); return new AndroidAssetManager(configFile);
} }
@Override @Override
public AssetManager newAssetManager() { public AssetManager newAssetManager() {
logger.log(Level.INFO, "newAssetManager()"); logger.log(Level.INFO, "Creating asset manager with default config");
return new AndroidAssetManager(null); return new AndroidAssetManager(null);
} }
@ -60,10 +66,30 @@ public class JmeAndroidSystem extends JmeSystemDelegate {
initialized = true; initialized = true;
try { try {
JmeFormatter formatter = new JmeFormatter(); // JmeFormatter formatter = new JmeFormatter();
// Handler consoleHandler = new AndroidLogHandler();
Handler consoleHandler = new AndroidLogHandler(); // consoleHandler.setFormatter(formatter);
consoleHandler.setFormatter(formatter); //
// Logger log = Logger.getLogger("");
// for (Handler h : log.getHandlers()) {
// log.removeHandler(h);
// }
// log.addHandler(consoleHandler);
Logger log = Logger.getLogger(JmeAndroidSystem.class.getName());
boolean bIsLogFormatSet = false;
do {
log.setLevel(Level.ALL);
if (log.getHandlers().length == 0) {
log = logger.getParent();
if (log != null) {
for (Handler h : log.getHandlers()) {
h.setFormatter(new JmeFormatter());
h.setLevel(Level.ALL);
bIsLogFormatSet = true;
}
}
}
} while (log != null && !bIsLogFormatSet);
} catch (SecurityException ex) { } catch (SecurityException ex) {
logger.log(Level.SEVERE, "Security error in creating log file", ex); logger.log(Level.SEVERE, "Security error in creating log file", ex);
} }
@ -93,19 +119,12 @@ public class JmeAndroidSystem extends JmeSystemDelegate {
//http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir //http://developer.android.com/reference/android/content/Context.html#getExternalFilesDir
//http://developer.android.com/guide/topics/data/data-storage.html //http://developer.android.com/guide/topics/data/data-storage.html
boolean mExternalStorageWriteable = false;
String state = Environment.getExternalStorageState(); String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) { if (Environment.MEDIA_MOUNTED.equals(state)) {
mExternalStorageWriteable = true; // getExternalFilesDir automatically creates the directory if necessary.
} else { // directory structure should be: /mnt/sdcard/Android/data/<packagename>/files
mExternalStorageWriteable = false; // when created this way, the directory is automatically removed by the Android
} // system when the app is uninstalled
if (mExternalStorageWriteable) {
//getExternalFilesDir automatically creates the directory if necessary.
//directory structure should be: /mnt/sdcard/Android/data/<packagename>/files
//when created this way, the directory is automatically removed by the Android
// system when the app is uninstalled
storageFolder = activity.getApplicationContext().getExternalFilesDir(null); storageFolder = activity.getApplicationContext().getExternalFilesDir(null);
logger.log(Level.INFO, "Storage Folder Path: {0}", storageFolder.getAbsolutePath()); logger.log(Level.INFO, "Storage Folder Path: {0}", storageFolder.getAbsolutePath());
@ -116,14 +135,6 @@ public class JmeAndroidSystem extends JmeSystemDelegate {
} }
public static void setResources(Resources res) {
JmeAndroidSystem.res = res;
}
public static Resources getResources() {
return res;
}
public static void setActivity(Activity activity) { public static void setActivity(Activity activity) {
JmeAndroidSystem.activity = activity; JmeAndroidSystem.activity = activity;
} }

@ -31,9 +31,7 @@
*/ */
package com.jme3.system.android; package com.jme3.system.android;
import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView;
import android.text.InputType; import android.text.InputType;
@ -42,24 +40,13 @@ import android.view.SurfaceHolder;
import android.view.ViewGroup.LayoutParams; import android.view.ViewGroup.LayoutParams;
import android.widget.EditText; import android.widget.EditText;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import com.jme3.app.AndroidHarness; import com.jme3.input.*;
import com.jme3.app.Application;
import com.jme3.input.JoyInput;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.SoftTextDialogInput;
import com.jme3.input.TouchInput;
import com.jme3.input.android.AndroidInput; import com.jme3.input.android.AndroidInput;
import com.jme3.input.controls.SoftTextDialogInputListener; import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.controls.TouchTrigger;
import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyKeyInput;
import com.jme3.input.dummy.DummyMouseInput; import com.jme3.input.dummy.DummyMouseInput;
import com.jme3.renderer.android.OGLESShaderRenderer; import com.jme3.renderer.android.OGLESShaderRenderer;
import com.jme3.system.AppSettings; import com.jme3.system.*;
import com.jme3.system.JmeContext;
import com.jme3.system.JmeSystem;
import com.jme3.system.SystemListener;
import com.jme3.system.Timer;
import com.jme3.system.android.AndroidConfigChooser.ConfigType; import com.jme3.system.android.AndroidConfigChooser.ConfigType;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.logging.Level; import java.util.logging.Level;
@ -86,14 +73,12 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
protected SystemListener listener; protected SystemListener listener;
protected boolean autoFlush = true; protected boolean autoFlush = true;
protected AndroidInput view; protected AndroidInput view;
//protected int minFrameDuration = 1000 / frameRate; // Set a max FPS of 33
protected int minFrameDuration = 0; // No FPS cap protected int minFrameDuration = 0; // No FPS cap
/** /**
* EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 | * EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 |
* EGL_OPENGL_ES2_BIT = OpenGL ES 2.0 * EGL_OPENGL_ES2_BIT = OpenGL ES 2.0
*/ */
protected int clientOpenGLESVersion = 1; protected int clientOpenGLESVersion = 1;
protected boolean verboseLogging = false;
public OGLESContext() { public OGLESContext() {
} }
@ -104,47 +89,28 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
} }
/** /**
* <code>createView</code> * <code>createView</code> creates the GLSurfaceView that the
* * renderer will draw to.
* @param activity The Android activity which is parent for the * <p>
* GLSurfaceView * The result GLSurfaceView will receive input events and forward
* @return GLSurfaceView The newly created view * them to the Application. Any rendering will be done into
*/ * the GLSurfaceView. Only one GLSurfaceView can be created at this time.
public GLSurfaceView createView(Activity activity) { * The given configType specifies how to determine the display configuration.
return createView(new AndroidInput(activity)); *
} *
/**
* <code>createView</code>
*
* @param view The Android input which will be used as the GLSurfaceView for
* this context
* @return GLSurfaceView The newly created view
*/
public GLSurfaceView createView(AndroidInput view) {
return createView(view, ConfigType.FASTEST, false);
}
/**
* <code>createView</code> initializes the GLSurfaceView
*
* @param view The Android input which will be used as the GLSurfaceView for
* this context
* @param configType ConfigType.FASTEST (Default) | ConfigType.LEGACY | * @param configType ConfigType.FASTEST (Default) | ConfigType.LEGACY |
* ConfigType.BEST * ConfigType.BEST
* @param eglConfigVerboseLogging if true show all found configs * @param eglConfigVerboseLogging if true show all found configs
* @return GLSurfaceView The newly created view * @return GLSurfaceView The newly created view
*/ */
public GLSurfaceView createView(AndroidInput view, ConfigType configType, boolean eglConfigVerboseLogging) { public GLSurfaceView createView(ConfigType configType, boolean eglConfigVerboseLogging) {
// Start to set up the view // Start to set up the view
this.view = view; this.view = new AndroidInput(JmeAndroidSystem.getActivity());
verboseLogging = eglConfigVerboseLogging;
if (configType == ConfigType.LEGACY) { if (configType == ConfigType.LEGACY) {
// Hardcoded egl setup // Hardcoded egl setup
clientOpenGLESVersion = 2; clientOpenGLESVersion = 2;
view.setEGLContextClientVersion(2); view.setEGLContextClientVersion(2);
//RGB565, Depth16 // RGB565, Depth16
view.setEGLConfigChooser(5, 6, 5, 0, 16, 0); view.setEGLConfigChooser(5, 6, 5, 0, 16, 0);
logger.info("ConfigType.LEGACY using RGB565"); logger.info("ConfigType.LEGACY using RGB565");
} else { } else {
@ -194,7 +160,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
// renderer:initialize // renderer:initialize
@Override @Override
public void onSurfaceCreated(GL10 gl, EGLConfig cfg) { public void onSurfaceCreated(GL10 gl, EGLConfig cfg) {
if (created.get() && renderer != null) { if (created.get() && renderer != null) {
renderer.resetGLObjects(); renderer.resetGLObjects();
} else { } else {
@ -211,13 +176,10 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
created.set(true); created.set(true);
logger.info("OGLESContext create"); logger.info("OGLESContext create");
logger.info("Running on thread: " + Thread.currentThread().getName()); logger.log(Level.INFO, "Running on thread: {0}", Thread.currentThread().getName());
// Setup unhandled Exception Handler // Setup unhandled Exception Handler
Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable thrown) { public void uncaughtException(Thread thread, Throwable thrown) {
listener.handleError("Exception thrown in " + thread.toString(), thrown); listener.handleError("Exception thrown in " + thread.toString(), thrown);
} }
@ -230,13 +192,9 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
timer = new AndroidTimer(); timer = new AndroidTimer();
renderer = new OGLESShaderRenderer(); renderer = new OGLESShaderRenderer();
renderer.setUseVA(true);
renderer.setVerboseLogging(verboseLogging);
renderer.initialize(); renderer.initialize();
listener.initialize(); listener.initialize();
JmeSystem.setSoftTextDialogInput(this); JmeSystem.setSoftTextDialogInput(this);
needClose.set(false); needClose.set(false);
@ -263,21 +221,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
logger.info("Display destroyed."); logger.info("Display destroyed.");
renderable.set(false); renderable.set(false);
}
}
protected void applySettingsToRenderer(OGLESShaderRenderer renderer, AppSettings settings) {
logger.warning("setSettings.USE_VA: [" + settings.getBoolean("USE_VA") + "]");
logger.warning("setSettings.VERBOSE_LOGGING: [" + settings.getBoolean("VERBOSE_LOGGING") + "]");
renderer.setUseVA(settings.getBoolean("USE_VA"));
renderer.setVerboseLogging(settings.getBoolean("VERBOSE_LOGGING"));
}
protected void applySettings(AppSettings settings) {
setSettings(settings);
if (renderer != null) {
applySettingsToRenderer(renderer, this.settings);
} }
} }
@ -343,10 +286,9 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
// SystemListener:reshape // SystemListener:reshape
@Override @Override
public void onSurfaceChanged(GL10 gl, int width, int height) { public void onSurfaceChanged(GL10 gl, int width, int height) {
logger.info("GL Surface changed, width: " + width + " height: " + height); logger.log(Level.INFO, "GL Surface changed, width: {0} height: {1}", new Object[]{width, height});
settings.setResolution(width, height); settings.setResolution(width, height);
listener.reshape(width, height); listener.reshape(width, height);
// androidListener.reshape(width, height);
} }
// SystemListener:update // SystemListener:update
@ -365,8 +307,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
long milliStart = System.currentTimeMillis(); long milliStart = System.currentTimeMillis();
listener.update(); listener.update();
if (autoFlush) { if (autoFlush) {
renderer.onFrame(); renderer.onFrame();
} }
@ -381,7 +321,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
} }
} }
} }
@ -435,7 +374,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex
new Object[]{title, initialValue}); new Object[]{title, initialValue});
JmeAndroidSystem.getActivity().runOnUiThread(new Runnable() { JmeAndroidSystem.getActivity().runOnUiThread(new Runnable() {
@Override @Override
public void run() { public void run() {

@ -24,8 +24,9 @@ public class AndroidLogHandler extends Handler {
public void publish(LogRecord record) { public void publish(LogRecord record) {
Level level = record.getLevel(); Level level = record.getLevel();
String clsName = record.getSourceClassName(); String clsName = record.getSourceClassName();
String msg = record.getMessage(); String msg = String.format(record.getMessage(), record.getParameters());
Throwable t = record.getThrown(); Throwable t = record.getThrown();
if (level == Level.INFO) { if (level == Level.INFO) {
Log.i(clsName, msg, t); Log.i(clsName, msg, t);
} else if (level == Level.SEVERE) { } else if (level == Level.SEVERE) {

@ -76,9 +76,15 @@ public interface TouchInput extends Input {
/** /**
* Get if mouse events are generated * Get if mouse events are generated
* * @deprecated Use {@link #isSimulateMouse() }.
*/ */
@Deprecated
public boolean getSimulateMouse(); public boolean getSimulateMouse();
/**
* @return true if mouse event simulation is enabled, false otherwise.
*/
public boolean isSimulateMouse();
/** /**
* Set if keyboard events should be generated * Set if keyboard events should be generated

@ -34,7 +34,6 @@ package com.jme3.system;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
@ -406,6 +405,47 @@ public final class AppSettings extends HashMap<String, Object> {
public void putFloat(String key, float value) { public void putFloat(String key, float value) {
put(key, Float.valueOf(value)); put(key, Float.valueOf(value));
} }
/**
* Enable or disable mouse emulation on touchscreen based devices.
* This will convert taps on the touchscreen or movement of finger
* over touchscreen (only the first) into the appropriate mouse events.
*
* @param emulateMouse If mouse emulation should be enabled.
*/
public void setEmulateMouse(boolean emulateMouse) {
putBoolean("TouchEmulateMouse", emulateMouse);
}
/**
* Returns true if mouse emulation is enabled, false otherwise.
*
* @return Mouse emulation mode.
*/
public boolean isEmulateMouse() {
return getBoolean("TouchEmulateMouse");
}
/**
* Specify if the X or Y (or both) axes should be flipped for emulated mouse.
*
* @param flipX Set to flip X axis
* @param flipY Set to flip Y axis
*
* @see #setEmulateMouse(boolean)
*/
public void setEmulateMouseFlipAxis(boolean flipX, boolean flipY) {
putBoolean("TouchEmulateMouseFlipX", flipX);
putBoolean("TouchEmulateMouseFlipY", flipY);
}
public boolean isEmulateMouseFlipX() {
return getBoolean("TouchEmulateMouseFlipX");
}
public boolean isEmulateMouseFlipY() {
return getBoolean("TouchEmulateMouseFlipY");
}
/** /**
* @param frameRate The frame-rate is the upper limit on how high * @param frameRate The frame-rate is the upper limit on how high

@ -128,19 +128,32 @@ public class JmeSystem {
systemDelegate.initialize(settings); systemDelegate.initialize(settings);
} }
private static JmeSystemDelegate tryLoadDelegate(String className) throws InstantiationException, IllegalAccessException {
try {
return (JmeSystemDelegate) Class.forName(className).newInstance();
} catch (ClassNotFoundException ex) {
return null;
}
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static void checkDelegate() { private static void checkDelegate() {
if (systemDelegate == null) { if (systemDelegate == null) {
Class<JmeSystemDelegate> systemDelegateClass;
try { try {
systemDelegateClass = (Class<JmeSystemDelegate>) Class.forName("com.jme3.system.JmeDesktopSystem"); systemDelegate = tryLoadDelegate("com.jme3.system.JmeDesktopSystem");
systemDelegate = systemDelegateClass.newInstance(); if (systemDelegate == null) {
systemDelegate = tryLoadDelegate("com.jme3.system.android.JmeAndroidSystem");
if (systemDelegate == null) {
// None of the system delegates were found ..
Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE,
"Failed to find a JmeSystem delegate!"
+ "Ensure either desktop or android jME3 jar is in the classpath.");
}
}
} catch (InstantiationException ex) { } catch (InstantiationException ex) {
Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex); Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "Failed to create JmeSystem delegate:\n{0}", ex);
} catch (IllegalAccessException ex) { } catch (IllegalAccessException ex) {
Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex); Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "Failed to create JmeSystem delegate:\n{0}", ex);
} catch (ClassNotFoundException ex) {
Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex);
} }
} }
} }

Loading…
Cancel
Save