diff --git a/engine/src/android/com/jme3/app/AndroidHarness.java b/engine/src/android/com/jme3/app/AndroidHarness.java index 0ae1cf84e..d7c2bfdf4 100644 --- a/engine/src/android/com/jme3/app/AndroidHarness.java +++ b/engine/src/android/com/jme3/app/AndroidHarness.java @@ -16,7 +16,6 @@ import android.widget.TextView; import com.jme3.audio.AudioRenderer; import com.jme3.audio.android.AndroidAudioRenderer; import com.jme3.input.TouchInput; -import com.jme3.input.android.AndroidInput; import com.jme3.input.controls.TouchListener; import com.jme3.input.controls.TouchTrigger; 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.JmeAndroidSystem; import com.jme3.system.android.OGLESContext; -import com.jme3.util.JmeFormatter; import java.io.PrintWriter; import java.io.StringWriter; -import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; @@ -43,52 +40,64 @@ import java.util.logging.Logger; public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener, SystemListener { protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName()); + /** * The application class to start */ protected String appClass = "jme3test.android.Test"; + /** * The jme3 application object */ protected Application app = null; + /** * ConfigType.FASTEST is RGB565, GLSurfaceView default ConfigType.BEST is * RGBA8888 or better if supported by the hardware */ protected ConfigType eglConfigType = ConfigType.FASTEST; + /** * If true all valid and not valid egl configs are logged */ protected boolean eglConfigVerboseLogging = false; + /** * If true MouseEvents are generated from TouchEvents */ protected boolean mouseEventsEnabled = true; + /** * Flip X axis */ protected boolean mouseEventsInvertX = true; + /** * Flip Y axis */ protected boolean mouseEventsInvertY = true; + /** * if true finish this activity when the jme app is stopped */ protected boolean finishOnAppStop = true; + /** * set to false if you don't want the harness to handle the exit hook */ protected boolean handleExitHook = true; + /** * Title of the exit dialog, default is "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 * 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 * 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. */ protected boolean screenFullScreen = true; + /** * if screenShowTitle is true while screenFullScreen is false, then the * title bar is also displayed under the notification bar */ protected boolean screenShowTitle = true; + /** * 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 = 0, then no splash screen will be displayed. */ protected int splashPicID = 0; + /** * Set the screen orientation, default is SENSOR * ActivityInfo.SCREEN_ORIENTATION_* constants package @@ -127,36 +139,11 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt final private String ESCAPE_EVENT = "TouchEscape"; private boolean firstDrawFrame = true; - static { - try { - System.loadLibrary("bulletjme"); - } catch (UnsatisfiedLinkError e) { - } - JmeSystem.setSystemDelegate(new JmeAndroidSystem()); - } - @Override public void onCreate(Bundle 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); - if (screenFullScreen) { requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, @@ -171,12 +158,8 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt // Create Settings AppSettings settings = new AppSettings(true); - - // Create the input class - AndroidInput input = new AndroidInput(this); - input.setMouseEventsInvertX(mouseEventsInvertX); - input.setMouseEventsInvertY(mouseEventsInvertY); - input.setMouseEventsEnabled(mouseEventsEnabled); + settings.setEmulateMouse(mouseEventsEnabled); + settings.setEmulateMouseFlipAxis(mouseEventsInvertX, mouseEventsInvertY); // Create application instance try { @@ -189,16 +172,15 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt app.setSettings(settings); app.start(); ctx = (OGLESContext) app.getContext(); - view = ctx.createView(input, eglConfigType, eglConfigVerboseLogging); + view = ctx.createView(eglConfigType, eglConfigVerboseLogging); // Set the screen reolution - WindowManager wind = this.getWindowManager(); - Display disp = wind.getDefaultDisplay(); - ctx.getSettings().setResolution(disp.getWidth(), disp.getHeight()); +// WindowManager wind = this.getWindowManager(); +// Display disp = wind.getDefaultDisplay(); +// 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(); - logger.log(Level.INFO, "Settings: Width {0} Height {1}", new Object[]{s.getWidth(), s.getHeight()}); - //setting the Harness as the system listener + // AndroidHarness wraps the app as a SystemListener. ctx.setSystemListener(this); layoutDisplay(); } catch (Exception ex) { @@ -271,7 +253,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt @Override protected void onStop() { super.onStop(); - logger.info("onStop"); } @@ -280,7 +261,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt if (app != null) { app.stop(!isGLThreadPaused); } - logger.info("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 * to the user and print the exception/error to the log. */ + @Override public void handleError(final String errorMsg, final Throwable t) { String stackTrace = ""; String title = "Error"; @@ -441,14 +422,6 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt app.requestClose(esc); } - public void gainFocus() { - app.gainFocus(); - } - - public void loseFocus() { - app.loseFocus(); - } - public void destroy() { if (app != null) { app.destroy(); @@ -457,4 +430,16 @@ public class AndroidHarness extends Activity implements TouchListener, DialogInt finish(); } } + + public void gainFocus() { + if (app != null) { + app.gainFocus(); + } + } + + public void loseFocus() { + if (app != null) { + app.loseFocus(); + } + } } diff --git a/engine/src/android/com/jme3/asset/plugins/AndroidLocator.java b/engine/src/android/com/jme3/asset/plugins/AndroidLocator.java index 225faf38d..16bf7c9c1 100644 --- a/engine/src/android/com/jme3/asset/plugins/AndroidLocator.java +++ b/engine/src/android/com/jme3/asset/plugins/AndroidLocator.java @@ -58,7 +58,7 @@ public class AndroidLocator implements AssetLocator { } public AndroidLocator() { - androidManager = JmeAndroidSystem.getResources().getAssets(); + androidManager = JmeAndroidSystem.getActivity().getAssets(); } public void setRootPath(String rootPath) { diff --git a/engine/src/android/com/jme3/input/android/AndroidInput.java b/engine/src/android/com/jme3/input/android/AndroidInput.java index 9bbbe4e50..b285dc50e 100644 --- a/engine/src/android/com/jme3/input/android/AndroidInput.java +++ b/engine/src/android/com/jme3/input/android/AndroidInput.java @@ -15,6 +15,7 @@ import com.jme3.input.event.MouseMotionEvent; import com.jme3.input.event.TouchEvent; import com.jme3.input.event.TouchEvent.Type; import com.jme3.math.Vector2f; +import com.jme3.system.AppSettings; import com.jme3.util.RingBuffer; import java.util.HashMap; import java.util.logging.Logger; @@ -244,11 +245,9 @@ public class AndroidInput extends GLSurfaceView implements bWasHandled = true; break; - case MotionEvent.ACTION_POINTER_UP: case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: - touch = getNextFreeTouchEvent(); touch.set(Type.UP, event.getX(pointerIndex), this.getHeight() - event.getY(pointerIndex), 0, 0); touch.setPointerId(pointerId); @@ -256,12 +255,9 @@ public class AndroidInput extends GLSurfaceView implements touch.setPressure(event.getPressure(pointerIndex)); processEvent(touch); - bWasHandled = true; break; case MotionEvent.ACTION_MOVE: - - // Convert all pointers into events for (int p = 0; p < event.getPointerCount(); p++) { Vector2f lastPos = lastPositions.get(pointerIndex); @@ -330,6 +326,12 @@ public class AndroidInput extends GLSurfaceView implements return true; } } + + public void loadSettings(AppSettings settings) { + mouseEventsEnabled = settings.isEmulateMouse(); + mouseEventsInvertX = settings.isEmulateMouseFlipX(); + mouseEventsInvertY = settings.isEmulateMouseFlipY(); + } // ----------------------------------------- // JME3 Input interface @@ -449,8 +451,6 @@ public class AndroidInput extends GLSurfaceView implements lastY = newY; break; } - - } } @@ -574,15 +574,6 @@ public class AndroidInput extends GLSurfaceView implements return true; } - @Override - public void setSimulateMouse(boolean simulate) { - mouseEventsEnabled = simulate; - } - @Override - public boolean getSimulateMouse() { - return mouseEventsEnabled; - } - @Override public void setSimulateKeyboard(boolean simulate) { keyboardEventsEnabled = simulate; @@ -593,11 +584,15 @@ public class AndroidInput extends GLSurfaceView implements this.dontSendHistory = dontSendHistory; } - // TODO: move to TouchInput + /** + * @deprecated Use {@link #getSimulateMouse()}; + */ + @Deprecated public boolean isMouseEventsEnabled() { return mouseEventsEnabled; } + @Deprecated public void setMouseEventsEnabled(boolean mouseEventsEnabled) { this.mouseEventsEnabled = mouseEventsEnabled; } @@ -617,4 +612,16 @@ public class AndroidInput extends GLSurfaceView implements public void setMouseEventsInvertX(boolean mouseEventsInvertX) { this.mouseEventsInvertX = mouseEventsInvertX; } + + public void setSimulateMouse(boolean simulate) { + mouseEventsEnabled = simulate; + } + + public boolean getSimulateMouse() { + return isSimulateMouse(); + } + + public boolean isSimulateMouse() { + return mouseEventsEnabled; + } } diff --git a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java index 56ed4159c..fe2bfb118 100644 --- a/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java +++ b/engine/src/android/com/jme3/system/android/AndroidConfigChooser.java @@ -31,10 +31,12 @@ public class AndroidConfigChooser implements EGLConfigChooser { * RGB565, 0 alpha, 16 depth, 0 stencil */ FASTEST, + /** * RGB???, 0 alpha, >=16 depth, 0 stencil */ BEST, + /** * Turn off config chooser and use hardcoded * 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 */ public boolean findConfig(EGL10 egl, EGLDisplay display) { - if (type == ConfigType.BEST) { ComponentSizeChooser compChooser = new ComponentSizeChooser(8, 8, 8, 8, 32, 0); choosenConfig = compChooser.chooseConfig(egl, display); - if (choosenConfig == null) { compChooser = new ComponentSizeChooser(8, 8, 8, 0, 32, 0); choosenConfig = compChooser.chooseConfig(egl, display); @@ -97,7 +97,7 @@ public class AndroidConfigChooser implements EGLConfigChooser { clientOpenGLESVersion = getOpenGLVersion(choosenConfig, display, egl); return true; } 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; pixelFormat = PixelFormat.UNKNOWN; return false; diff --git a/engine/src/android/com/jme3/system/android/JmeAndroidSystem.java b/engine/src/android/com/jme3/system/android/JmeAndroidSystem.java index 6550101af..e3409f11c 100644 --- a/engine/src/android/com/jme3/system/android/JmeAndroidSystem.java +++ b/engine/src/android/com/jme3/system/android/JmeAndroidSystem.java @@ -1,8 +1,8 @@ package com.jme3.system.android; import android.app.Activity; -import android.content.res.Resources; import android.os.Environment; +import android.util.Log; import com.jme3.asset.AndroidAssetManager; import com.jme3.asset.AssetManager; import com.jme3.audio.AudioRenderer; @@ -12,27 +12,33 @@ import com.jme3.system.JmeContext; import com.jme3.system.JmeContext.Type; import com.jme3.system.JmeSystemDelegate; import com.jme3.system.Platform; -import com.jme3.util.AndroidLogHandler; import com.jme3.util.JmeFormatter; import java.io.File; import java.net.URL; import java.util.logging.Handler; import java.util.logging.Level; +import java.util.logging.Logger; public class JmeAndroidSystem extends JmeSystemDelegate { - private static Resources res; private static Activity activity; + static { + try { + System.loadLibrary("bulletjme"); + } catch (UnsatisfiedLinkError e) { + } + } + @Override 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); } @Override public AssetManager newAssetManager() { - logger.log(Level.INFO, "newAssetManager()"); + logger.log(Level.INFO, "Creating asset manager with default config"); return new AndroidAssetManager(null); } @@ -60,10 +66,30 @@ public class JmeAndroidSystem extends JmeSystemDelegate { initialized = true; try { - JmeFormatter formatter = new JmeFormatter(); - - Handler consoleHandler = new AndroidLogHandler(); - consoleHandler.setFormatter(formatter); +// JmeFormatter formatter = new JmeFormatter(); +// Handler consoleHandler = new AndroidLogHandler(); +// 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) { 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/guide/topics/data/data-storage.html - boolean mExternalStorageWriteable = false; String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { - mExternalStorageWriteable = true; - } else { - mExternalStorageWriteable = false; - } - - if (mExternalStorageWriteable) { - //getExternalFilesDir automatically creates the directory if necessary. - //directory structure should be: /mnt/sdcard/Android/data//files - //when created this way, the directory is automatically removed by the Android - // system when the app is uninstalled + // getExternalFilesDir automatically creates the directory if necessary. + // directory structure should be: /mnt/sdcard/Android/data//files + // when created this way, the directory is automatically removed by the Android + // system when the app is uninstalled storageFolder = activity.getApplicationContext().getExternalFilesDir(null); 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) { JmeAndroidSystem.activity = activity; } diff --git a/engine/src/android/com/jme3/system/android/OGLESContext.java b/engine/src/android/com/jme3/system/android/OGLESContext.java index 4023300d7..359531af3 100644 --- a/engine/src/android/com/jme3/system/android/OGLESContext.java +++ b/engine/src/android/com/jme3/system/android/OGLESContext.java @@ -31,9 +31,7 @@ */ package com.jme3.system.android; -import android.app.Activity; import android.app.AlertDialog; -import android.content.Context; import android.content.DialogInterface; import android.opengl.GLSurfaceView; import android.text.InputType; @@ -42,24 +40,13 @@ import android.view.SurfaceHolder; import android.view.ViewGroup.LayoutParams; import android.widget.EditText; import android.widget.FrameLayout; -import com.jme3.app.AndroidHarness; -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.*; import com.jme3.input.android.AndroidInput; import com.jme3.input.controls.SoftTextDialogInputListener; -import com.jme3.input.controls.TouchTrigger; import com.jme3.input.dummy.DummyKeyInput; import com.jme3.input.dummy.DummyMouseInput; import com.jme3.renderer.android.OGLESShaderRenderer; -import com.jme3.system.AppSettings; -import com.jme3.system.JmeContext; -import com.jme3.system.JmeSystem; -import com.jme3.system.SystemListener; -import com.jme3.system.Timer; +import com.jme3.system.*; import com.jme3.system.android.AndroidConfigChooser.ConfigType; import java.util.concurrent.atomic.AtomicBoolean; import java.util.logging.Level; @@ -86,14 +73,12 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex protected SystemListener listener; protected boolean autoFlush = true; protected AndroidInput view; - //protected int minFrameDuration = 1000 / frameRate; // Set a max FPS of 33 protected int minFrameDuration = 0; // No FPS cap /** * EGL_RENDERABLE_TYPE: EGL_OPENGL_ES_BIT = OpenGL ES 1.0 | * EGL_OPENGL_ES2_BIT = OpenGL ES 2.0 */ protected int clientOpenGLESVersion = 1; - protected boolean verboseLogging = false; public OGLESContext() { } @@ -104,47 +89,28 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex } /** - * createView - * - * @param activity The Android activity which is parent for the - * GLSurfaceView - * @return GLSurfaceView The newly created view - */ - public GLSurfaceView createView(Activity activity) { - return createView(new AndroidInput(activity)); - } - - /** - * createView - * - * @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); - } - - /** - * createView initializes the GLSurfaceView - * - * @param view The Android input which will be used as the GLSurfaceView for - * this context + * createView creates the GLSurfaceView that the + * renderer will draw to. + *

+ * The result GLSurfaceView will receive input events and forward + * them to the Application. Any rendering will be done into + * the GLSurfaceView. Only one GLSurfaceView can be created at this time. + * The given configType specifies how to determine the display configuration. + * + * * @param configType ConfigType.FASTEST (Default) | ConfigType.LEGACY | * ConfigType.BEST * @param eglConfigVerboseLogging if true show all found configs * @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 - this.view = view; - verboseLogging = eglConfigVerboseLogging; - + this.view = new AndroidInput(JmeAndroidSystem.getActivity()); if (configType == ConfigType.LEGACY) { // Hardcoded egl setup clientOpenGLESVersion = 2; view.setEGLContextClientVersion(2); - //RGB565, Depth16 + // RGB565, Depth16 view.setEGLConfigChooser(5, 6, 5, 0, 16, 0); logger.info("ConfigType.LEGACY using RGB565"); } else { @@ -194,7 +160,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex // renderer:initialize @Override public void onSurfaceCreated(GL10 gl, EGLConfig cfg) { - if (created.get() && renderer != null) { renderer.resetGLObjects(); } else { @@ -211,13 +176,10 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex created.set(true); 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 - Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - public void uncaughtException(Thread thread, Throwable thrown) { listener.handleError("Exception thrown in " + thread.toString(), thrown); } @@ -230,13 +192,9 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex timer = new AndroidTimer(); renderer = new OGLESShaderRenderer(); - renderer.setUseVA(true); - renderer.setVerboseLogging(verboseLogging); - renderer.initialize(); listener.initialize(); - JmeSystem.setSoftTextDialogInput(this); needClose.set(false); @@ -263,21 +221,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex logger.info("Display destroyed."); 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 @Override 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); listener.reshape(width, height); - // androidListener.reshape(width, height); } // SystemListener:update @@ -365,8 +307,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex long milliStart = System.currentTimeMillis(); listener.update(); - - if (autoFlush) { renderer.onFrame(); } @@ -381,7 +321,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex } catch (InterruptedException e) { } } - } } @@ -435,7 +374,6 @@ public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTex new Object[]{title, initialValue}); JmeAndroidSystem.getActivity().runOnUiThread(new Runnable() { - @Override public void run() { diff --git a/engine/src/android/com/jme3/util/AndroidLogHandler.java b/engine/src/android/com/jme3/util/AndroidLogHandler.java index 1da12995e..496ab5c4c 100644 --- a/engine/src/android/com/jme3/util/AndroidLogHandler.java +++ b/engine/src/android/com/jme3/util/AndroidLogHandler.java @@ -24,8 +24,9 @@ public class AndroidLogHandler extends Handler { public void publish(LogRecord record) { Level level = record.getLevel(); String clsName = record.getSourceClassName(); - String msg = record.getMessage(); + String msg = String.format(record.getMessage(), record.getParameters()); Throwable t = record.getThrown(); + if (level == Level.INFO) { Log.i(clsName, msg, t); } else if (level == Level.SEVERE) { diff --git a/engine/src/core/com/jme3/input/TouchInput.java b/engine/src/core/com/jme3/input/TouchInput.java index e69c4b320..9b0ab5f58 100644 --- a/engine/src/core/com/jme3/input/TouchInput.java +++ b/engine/src/core/com/jme3/input/TouchInput.java @@ -76,9 +76,15 @@ public interface TouchInput extends Input { /** * Get if mouse events are generated - * + * @deprecated Use {@link #isSimulateMouse() }. */ + @Deprecated public boolean getSimulateMouse(); + + /** + * @return true if mouse event simulation is enabled, false otherwise. + */ + public boolean isSimulateMouse(); /** * Set if keyboard events should be generated diff --git a/engine/src/core/com/jme3/system/AppSettings.java b/engine/src/core/com/jme3/system/AppSettings.java index 7e8dbb32d..517549a55 100644 --- a/engine/src/core/com/jme3/system/AppSettings.java +++ b/engine/src/core/com/jme3/system/AppSettings.java @@ -34,7 +34,6 @@ package com.jme3.system; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import java.util.Properties; @@ -406,6 +405,47 @@ public final class AppSettings extends HashMap { public void putFloat(String key, float 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 diff --git a/engine/src/core/com/jme3/system/JmeSystem.java b/engine/src/core/com/jme3/system/JmeSystem.java index 2e2d79a47..1639562b5 100644 --- a/engine/src/core/com/jme3/system/JmeSystem.java +++ b/engine/src/core/com/jme3/system/JmeSystem.java @@ -128,19 +128,32 @@ public class JmeSystem { 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") private static void checkDelegate() { if (systemDelegate == null) { - Class systemDelegateClass; try { - systemDelegateClass = (Class) Class.forName("com.jme3.system.JmeDesktopSystem"); - systemDelegate = systemDelegateClass.newInstance(); + systemDelegate = tryLoadDelegate("com.jme3.system.JmeDesktopSystem"); + 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) { - 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) { - Logger.getLogger(JmeSystem.class.getName()).log(Level.SEVERE, "No JmeSystemDelegate specified, cannot instantiate default JmeDesktopSystem:\n{0}", ex); - } catch (ClassNotFoundException 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); } } }