https://github.com/libsdl-org/Maelstrom/commit/5caae6565ad02cab995a66a6a7da3630887461ad
From 5caae6565ad02cab995a66a6a7da3630887461ad Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 3 Oct 2013 03:18:36 -0700
Subject: [PATCH] Updated to latest SDL build
---
.../src/org/libsdl/app/SDLActivity.java | 491 ++++++++----------
1 file changed, 228 insertions(+), 263 deletions(-)
diff --git a/android-project/src/org/libsdl/app/SDLActivity.java b/android-project/src/org/libsdl/app/SDLActivity.java
index 2556ca12..52e48e23 100644
--- a/android-project/src/org/libsdl/app/SDLActivity.java
+++ b/android-project/src/org/libsdl/app/SDLActivity.java
@@ -1,11 +1,5 @@
package org.libsdl.app;
-import javax.microedition.khronos.egl.EGL10;
-import javax.microedition.khronos.egl.EGLConfig;
-import javax.microedition.khronos.egl.EGLContext;
-import javax.microedition.khronos.opengles.GL10;
-import javax.microedition.khronos.egl.*;
-
import android.app.*;
import android.content.*;
import android.view.*;
@@ -17,53 +11,44 @@
import android.os.*;
import android.util.Log;
import android.graphics.*;
-import android.text.method.*;
-import android.text.*;
import android.media.*;
import android.hardware.*;
-import android.content.*;
-
-import java.lang.*;
/**
SDL Activity
*/
public class SDLActivity extends Activity {
+ private static final String TAG = "SDL";
// Keep track of the paused state
- public static boolean mIsPaused;
+ public static boolean mIsPaused = false, mIsSurfaceReady = false, mHasFocus = true;
// Main components
- private static SDLActivity mSingleton;
- private static SDLSurface mSurface;
- private static View mTextEdit;
- private static ViewGroup mLayout;
+ protected static SDLActivity mSingleton;
+ protected static SDLSurface mSurface;
+ protected static View mTextEdit;
+ protected static ViewGroup mLayout;
// This is what SDL runs in. It invokes SDL_main(), eventually
- private static Thread mSDLThread;
+ protected static Thread mSDLThread;
// Audio
- private static Thread mAudioThread;
- private static AudioTrack mAudioTrack;
-
- // EGL private objects
- private static EGLContext mEGLContext;
- private static EGLSurface mEGLSurface;
- private static EGLDisplay mEGLDisplay;
- private static EGLConfig mEGLConfig;
- private static int mGLMajor, mGLMinor;
+ protected static Thread mAudioThread;
+ protected static AudioTrack mAudioTrack;
// Load the .so
static {
System.loadLibrary("SDL2");
- System.loadLibrary("SDL2_image");
- System.loadLibrary("SDL2_net");
- System.loadLibrary("SDL2_ttf");
+ //System.loadLibrary("SDL2_image");
+ //System.loadLibrary("SDL2_mixer");
+ //System.loadLibrary("SDL2_net");
+ //System.loadLibrary("SDL2_ttf");
System.loadLibrary("main");
}
// Setup
+ @Override
protected void onCreate(Bundle savedInstanceState) {
//Log.v("SDL", "onCreate()");
super.onCreate(savedInstanceState);
@@ -71,9 +56,6 @@ protected void onCreate(Bundle savedInstanceState) {
// So we can call stuff from static callbacks
mSingleton = this;
- // Keep track of the paused state
- mIsPaused = false;
-
// Set up the surface
mSurface = new SDLSurface(getApplication());
@@ -81,23 +63,43 @@ protected void onCreate(Bundle savedInstanceState) {
mLayout.addView(mSurface);
setContentView(mLayout);
-
- SurfaceHolder holder = mSurface.getHolder();
}
// Events
- /*protected void onPause() {
+ @Override
+ protected void onPause() {
Log.v("SDL", "onPause()");
super.onPause();
- // Don't call SDLActivity.nativePause(); here, it will be called by SDLSurface::surfaceDestroyed
+ SDLActivity.handlePause();
}
+ @Override
protected void onResume() {
Log.v("SDL", "onResume()");
super.onResume();
- // Don't call SDLActivity.nativeResume(); here, it will be called via SDLSurface::surfaceChanged->SDLActivity::startApp
- }*/
+ SDLActivity.handleResume();
+ }
+
+
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ Log.v("SDL", "onWindowFocusChanged(): " + hasFocus);
+
+ SDLActivity.mHasFocus = hasFocus;
+ if (hasFocus) {
+ SDLActivity.handleResume();
+ }
+ }
+
+ @Override
+ public void onLowMemory() {
+ Log.v("SDL", "onLowMemory()");
+ super.onLowMemory();
+ SDLActivity.nativeLowMemory();
+ }
+ @Override
protected void onDestroy() {
super.onDestroy();
Log.v("SDL", "onDestroy()");
@@ -117,96 +119,150 @@ protected void onDestroy() {
}
}
+ @Override
+ public boolean dispatchKeyEvent(KeyEvent event) {
+ int keyCode = event.getKeyCode();
+ // Ignore certain special keys so they're handled by Android
+ if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
+ keyCode == KeyEvent.KEYCODE_VOLUME_UP ||
+ keyCode == KeyEvent.KEYCODE_CAMERA ||
+ keyCode == 168 || /* API 11: KeyEvent.KEYCODE_ZOOM_IN */
+ keyCode == 169 /* API 11: KeyEvent.KEYCODE_ZOOM_OUT */
+ ) {
+ return false;
+ }
+ return super.dispatchKeyEvent(event);
+ }
+
+ /** Called by onPause or surfaceDestroyed. Even if surfaceDestroyed
+ * is the first to be called, mIsSurfaceReady should still be set
+ * to 'true' during the call to onPause (in a usual scenario).
+ */
+ public static void handlePause() {
+ if (!SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady) {
+ SDLActivity.mIsPaused = true;
+ SDLActivity.nativePause();
+ mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, false);
+ }
+ }
+
+ /** Called by onResume or surfaceCreated. An actual resume should be done only when the surface is ready.
+ * Note: Some Android variants may send multiple surfaceChanged events, so we don't need to resume
+ * every time we get one of those events, only if it comes after surfaceDestroyed
+ */
+ public static void handleResume() {
+ if (SDLActivity.mIsPaused && SDLActivity.mIsSurfaceReady && SDLActivity.mHasFocus) {
+ SDLActivity.mIsPaused = false;
+ SDLActivity.nativeResume();
+ mSurface.enableSensor(Sensor.TYPE_ACCELEROMETER, true);
+ }
+ }
+
+
// Messages from the SDLMain thread
static final int COMMAND_CHANGE_TITLE = 1;
static final int COMMAND_UNUSED = 2;
static final int COMMAND_TEXTEDIT_HIDE = 3;
- // Handler for the messages
- Handler commandHandler = new Handler() {
+ protected static final int COMMAND_USER = 0x8000;
+
+ /**
+ * This method is called by SDL if SDL did not handle a message itself.
+ * This happens if a received message contains an unsupported command.
+ * Method can be overwritten to handle Messages in a different class.
+ * @param command the command of the message.
+ * @param param the parameter of the message. May be null.
+ * @return if the message was handled in overridden method.
+ */
+ protected boolean onUnhandledMessage(int command, Object param) {
+ return false;
+ }
+
+ /**
+ * A Handler class for Messages from native SDL applications.
+ * It uses current Activities as target (e.g. for the title).
+ * static to prevent implicit references to enclosing object.
+ */
+ protected static class SDLCommandHandler extends Handler {
@Override
public void handleMessage(Message msg) {
+ Context context = getContext();
+ if (context == null) {
+ Log.e(TAG, "error handling message, getContext() returned null");
+ return;
+ }
switch (msg.arg1) {
case COMMAND_CHANGE_TITLE:
- setTitle((String)msg.obj);
+ if (context instanceof Activity) {
+ ((Activity) context).setTitle((String)msg.obj);
+ } else {
+ Log.e(TAG, "error handling message, getContext() returned no Activity");
+ }
break;
case COMMAND_TEXTEDIT_HIDE:
if (mTextEdit != null) {
mTextEdit.setVisibility(View.GONE);
- InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+ InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mTextEdit.getWindowToken(), 0);
}
break;
+
+ default:
+ if ((context instanceof SDLActivity) && !((SDLActivity) context).onUnhandledMessage(msg.arg1, msg.obj)) {
+ Log.e(TAG, "error handling message, command is " + msg.arg1);
+ }
}
}
- };
+ }
+
+ // Handler for the messages
+ Handler commandHandler = new SDLCommandHandler();
// Send a message from the SDLMain thread
- void sendCommand(int command, Object data) {
+ boolean sendCommand(int command, Object data) {
Message msg = commandHandler.obtainMessage();
msg.arg1 = command;
msg.obj = data;
- commandHandler.sendMessage(msg);
+ return commandHandler.sendMessage(msg);
}
// C functions we call
public static native void nativeInit();
+ public static native void nativeLowMemory();
public static native void nativeQuit();
public static native void nativePause();
public static native void nativeResume();
public static native void onNativeResize(int x, int y, int format);
public static native void onNativeKeyDown(int keycode);
public static native void onNativeKeyUp(int keycode);
+ public static native void onNativeKeyboardFocusLost();
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
int action, float x,
float y, float p);
public static native void onNativeAccel(float x, float y, float z);
- public static native void nativeRunAudioThread();
-
-
- // Java functions called from C
-
- public static boolean createGLContext(int majorVersion, int minorVersion) {
- return initEGL(majorVersion, minorVersion);
- }
+ public static native void onNativeSurfaceChanged();
+ public static native void onNativeSurfaceDestroyed();
+ public static native void nativeFlipBuffers();
public static void flipBuffers() {
- flipEGL();
+ SDLActivity.nativeFlipBuffers();
}
- public static void setActivityTitle(String title) {
+ public static boolean setActivityTitle(String title) {
// Called from SDLMain() thread and can't directly affect the view
- mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
+ return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
}
- public static void sendMessage(int command, int param) {
- mSingleton.sendCommand(command, Integer.valueOf(param));
+ public static boolean sendMessage(int command, int param) {
+ return mSingleton.sendCommand(command, Integer.valueOf(param));
}
public static Context getContext() {
return mSingleton;
}
- public static void startApp() {
- // Start up the C app thread
- if (mSDLThread == null) {
- mSDLThread = new Thread(new SDLMain(), "SDLThread");
- mSDLThread.start();
- }
- else {
- /*
- * Some Android variants may send multiple surfaceChanged events, so we don't need to resume every time
- * every time we get one of those events, only if it comes after surfaceDestroyed
- */
- if (mIsPaused) {
- SDLActivity.nativeResume();
- SDLActivity.mIsPaused = false;
- }
- }
- }
-
- static class ShowTextInputHandler implements Runnable {
+ static class ShowTextInputTask implements Runnable {
/*
* This is used to regulate the pan&scan method to have some offset from
* the bottom edge of the input region and the top edge of an input
@@ -216,13 +272,14 @@ static class ShowTextInputHandler implements Runnable {
public int x, y, w, h;
- public ShowTextInputHandler(int x, int y, int w, int h) {
+ public ShowTextInputTask(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
+ @Override
public void run() {
AbsoluteLayout.LayoutParams params = new AbsoluteLayout.LayoutParams(
w, h + HEIGHT_PADDING, x, y);
@@ -241,171 +298,50 @@ public void run() {
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(mTextEdit, 0);
}
-
}
- public static void showTextInput(int x, int y, int w, int h) {
+ public static boolean showTextInput(int x, int y, int w, int h) {
// Transfer the task to the main thread as a Runnable
- mSingleton.commandHandler.post(new ShowTextInputHandler(x, y, w, h));
- }
-
-
- // EGL functions
- public static boolean initEGL(int majorVersion, int minorVersion) {
- try {
- if (SDLActivity.mEGLDisplay == null) {
- Log.v("SDL", "Starting up OpenGL ES " + majorVersion + "." + minorVersion);
-
- EGL10 egl = (EGL10)EGLContext.getEGL();
-
- EGLDisplay dpy = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
-
- int[] version = new int[2];
- egl.eglInitialize(dpy, version);
-
- int EGL_OPENGL_ES_BIT = 1;
- int EGL_OPENGL_ES2_BIT = 4;
- int renderableType = 0;
- if (majorVersion == 2) {
- renderableType = EGL_OPENGL_ES2_BIT;
- } else if (majorVersion == 1) {
- renderableType = EGL_OPENGL_ES_BIT;
- }
- int[] configSpec = {
- //EGL10.EGL_DEPTH_SIZE, 16,
- EGL10.EGL_RENDERABLE_TYPE, renderableType,
- EGL10.EGL_NONE
- };
- EGLConfig[] configs = new EGLConfig[1];
- int[] num_config = new int[1];
- if (!egl.eglChooseConfig(dpy, configSpec, configs, 1, num_config) || num_config[0] == 0) {
- Log.e("SDL", "No EGL config available");
- return false;
- }
- EGLConfig config = configs[0];
-
- SDLActivity.mEGLDisplay = dpy;
- SDLActivity.mEGLConfig = config;
- SDLActivity.mGLMajor = majorVersion;
- SDLActivity.mGLMinor = minorVersion;
- }
- return SDLActivity.createEGLSurface();
-
- } catch(Exception e) {
- Log.v("SDL", e + "");
- for (StackTraceElement s : e.getStackTrace()) {
- Log.v("SDL", s.toString());
- }
- return false;
- }
+ return mSingleton.commandHandler.post(new ShowTextInputTask(x, y, w, h));
}
-
- public static boolean createEGLContext() {
- EGL10 egl = (EGL10)EGLContext.getEGL();
- int EGL_CONTEXT_CLIENT_VERSION=0x3098;
- int contextAttrs[] = new int[] { EGL_CONTEXT_CLIENT_VERSION, SDLActivity.mGLMajor, EGL10.EGL_NONE };
- SDLActivity.mEGLContext = egl.eglCreateContext(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, EGL10.EGL_NO_CONTEXT, contextAttrs);
- if (SDLActivity.mEGLContext == EGL10.EGL_NO_CONTEXT) {
- Log.e("SDL", "Couldn't create context");
- return false;
- }
- return true;
- }
-
- public static boolean createEGLSurface() {
- if (SDLActivity.mEGLDisplay != null && SDLActivity.mEGLConfig != null) {
- EGL10 egl = (EGL10)EGLContext.getEGL();
- if (SDLActivity.mEGLContext == null) createEGLContext();
-
- Log.v("SDL", "Creating new EGL Surface");
- EGLSurface surface = egl.eglCreateWindowSurface(SDLActivity.mEGLDisplay, SDLActivity.mEGLConfig, SDLActivity.mSurface, null);
- if (surface == EGL10.EGL_NO_SURFACE) {
- Log.e("SDL", "Couldn't create surface");
- return false;
- }
-
- if (egl.eglGetCurrentContext() != SDLActivity.mEGLContext) {
- if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
- Log.e("SDL", "Old EGL Context doesnt work, trying with a new one");
- // TODO: Notify the user via a message that the old context could not be restored, and that textures need to be manually restored.
- createEGLContext();
- if (!egl.eglMakeCurrent(SDLActivity.mEGLDisplay, surface, surface, SDLActivity.mEGLContext)) {
- Log.e("SDL", "Failed making EGL Context current");
- return false;
- }
- }
- }
- SDLActivity.mEGLSurface = surface;
- return true;
- } else {
- Log.e("SDL", "Surface creation failed, display = " + SDLActivity.mEGLDisplay + ", config = " + SDLActivity.mEGLConfig);
- return false;
- }
- }
-
- // EGL buffer flip
- public static void flipEGL() {
- try {
- EGL10 egl = (EGL10)EGLContext.getEGL();
-
- egl.eglWaitNative(EGL10.EGL_CORE_NATIVE_ENGINE, null);
-
- // drawing here
-
- egl.eglWaitGL();
-
- egl.eglSwapBuffers(SDLActivity.mEGLDisplay, SDLActivity.mEGLSurface);
-
-
- } catch(Exception e) {
- Log.v("SDL", "flipEGL(): " + e);
- for (StackTraceElement s : e.getStackTrace()) {
- Log.v("SDL", s.toString());
- }
- }
+
+ public static Surface getNativeSurface() {
+ return SDLActivity.mSurface.getNativeSurface();
}
// Audio
- private static Object buf;
-
- public static Object audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
+ public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
- Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + ((float)sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
+ Log.v("SDL", "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
// Let the user pick a larger buffer if they really want -- but ye
// gods they probably shouldn't, the minimums are horrifyingly high
// latency already
desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
- mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
- channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
-
- audioStartThread();
-
- Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + ((float)mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
-
- if (is16Bit) {
- buf = new short[desiredFrames * (isStereo ? 2 : 1)];
- } else {
- buf = new byte[desiredFrames * (isStereo ? 2 : 1)];
- }
- return buf;
- }
-
- public static void audioStartThread() {
- mAudioThread = new Thread(new Runnable() {
- public void run() {
- mAudioTrack.play();
- nativeRunAudioThread();
+ if (mAudioTrack == null) {
+ mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
+ channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
+
+ // Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
+ // Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
+ // Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
+
+ if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
+ Log.e("SDL", "Failed during initialization of Audio Track");
+ mAudioTrack = null;
+ return -1;
}
- });
+
+ mAudioTrack.play();
+ }
+
+ Log.v("SDL", "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
- // I'd take REALTIME if I could get it!
- mAudioThread.setPriority(Thread.MAX_PRIORITY);
- mAudioThread.start();
+ return 0;
}
public static void audioWriteShortBuffer(short[] buffer) {
@@ -438,24 +374,13 @@ public static void audioWriteByteBuffer(byte[] buffer) {
// Nom nom
}
} else {
- Log.w("SDL", "SDL audio: error return from write(short)");
+ Log.w("SDL", "SDL audio: error return from write(byte)");
return;
}
}
}
public static void audioQuit() {
- if (mAudioThread != null) {
- try {
- mAudioThread.join();
- } catch(Exception e) {
- Log.v("SDL", "Problem stopping audio thread: " + e);
- }
- mAudioThread = null;
-
- //Log.v("SDL", "Finished waiting for audio thread");
- }
-
if (mAudioTrack != null) {
mAudioTrack.stop();
mAudioTrack = null;
@@ -467,6 +392,7 @@ public static void audioQuit() {
Simple nativeInit() runnable
*/
class SDLMain implements Runnable {
+ @Override
public void run() {
// Runs SDL_main()
SDLActivity.nativeInit();
@@ -486,10 +412,10 @@ class SDLSurface extends SurfaceView implements SurfaceHolder.Callback,
View.OnKeyListener, View.OnTouchListener, SensorEventListener {
// Sensors
- private static SensorManager mSensorManager;
+ protected static SensorManager mSensorManager;
// Keep track of the surface size to normalize touch events
- private static float mWidth, mHeight;
+ protected static float mWidth, mHeight;
// Startup
public SDLSurface(Context context) {
@@ -502,36 +428,41 @@ public SDLSurface(Context context) {
setOnKeyListener(this);
setOnTouchListener(this);
- mSensorManager = (SensorManager)context.getSystemService("sensor");
+ mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
// Some arbitrary defaults to avoid a potential division by zero
mWidth = 1.0f;
mHeight = 1.0f;
}
+
+ public Surface getNativeSurface() {
+ return getHolder().getSurface();
+ }
// Called when we have a valid drawing surface
+ @Override
public void surfaceCreated(SurfaceHolder holder) {
Log.v("SDL", "surfaceCreated()");
holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
- enableSensor(Sensor.TYPE_ACCELEROMETER, true);
}
// Called when we lose the surface
+ @Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.v("SDL", "surfaceDestroyed()");
- if (!SDLActivity.mIsPaused) {
- SDLActivity.mIsPaused = true;
- SDLActivity.nativePause();
- }
- enableSensor(Sensor.TYPE_ACCELEROMETER, false);
+ // Call this *before* setting mIsSurfaceReady to 'false'
+ SDLActivity.handlePause();
+ SDLActivity.mIsSurfaceReady = false;
+ SDLActivity.onNativeSurfaceDestroyed();
}
// Called when the surface is resized
+ @Override
public void surfaceChanged(SurfaceHolder holder,
int format, int width, int height) {
Log.v("SDL", "surfaceChanged()");
- int sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565 by default
+ int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
switch (format) {
case PixelFormat.A_8:
Log.v("SDL", "pixel format A_8");
@@ -544,55 +475,67 @@ public void surfaceChanged(SurfaceHolder holder,
break;
case PixelFormat.RGBA_4444:
Log.v("SDL", "pixel format RGBA_4444");
- sdlFormat = 0x85421002; // SDL_PIXELFORMAT_RGBA4444
+ sdlFormat = 0x15421002; // SDL_PIXELFORMAT_RGBA4444
break;
case PixelFormat.RGBA_5551:
Log.v("SDL", "pixel format RGBA_5551");
- sdlFormat = 0x85441002; // SDL_PIXELFORMAT_RGBA5551
+ sdlFormat = 0x15441002; // SDL_PIXELFORMAT_RGBA5551
break;
case PixelFormat.RGBA_8888:
Log.v("SDL", "pixel format RGBA_8888");
- sdlFormat = 0x86462004; // SDL_PIXELFORMAT_RGBA8888
+ sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888
break;
case PixelFormat.RGBX_8888:
Log.v("SDL", "pixel format RGBX_8888");
- sdlFormat = 0x86262004; // SDL_PIXELFORMAT_RGBX8888
+ sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888
break;
case PixelFormat.RGB_332:
Log.v("SDL", "pixel format RGB_332");
- sdlFormat = 0x84110801; // SDL_PIXELFORMAT_RGB332
+ sdlFormat = 0x14110801; // SDL_PIXELFORMAT_RGB332
break;
case PixelFormat.RGB_565:
Log.v("SDL", "pixel format RGB_565");
- sdlFormat = 0x85151002; // SDL_PIXELFORMAT_RGB565
+ sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565
break;
case PixelFormat.RGB_888:
Log.v("SDL", "pixel format RGB_888");
// Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
- sdlFormat = 0x86161804; // SDL_PIXELFORMAT_RGB888
+ sdlFormat = 0x16161804; // SDL_PIXELFORMAT_RGB888
break;
default:
Log.v("SDL", "pixel format unknown " + format);
break;
}
- mWidth = (float) width;
- mHeight = (float) height;
+ mWidth = width;
+ mHeight = height;
SDLActivity.onNativeResize(width, height, sdlFormat);
Log.v("SDL", "Window size:" + width + "x"+height);
- SDLActivity.startApp();
+ // Set mIsSurfaceReady to 'true' *before* making a call to handleResume
+ SDLActivity.mIsSurfaceReady = true;
+ SDLActivity.onNativeSurfaceChanged();
+
+
+ if (SDLActivity.mSDLThread == null) {
+ // This is the entry point to the C app.
+ // Start up the C app thread and enable sensor input for the first time
+
+ SDLActivity.mSDLThread = new Thread(new SDLMain(), "SDLThread");
+ enableSensor(Sensor.TYPE_ACCELEROMETER, true);
+ SDLActivity.mSDLThread.start();
+ }
}
// unused
+ @Override
public void onDraw(Canvas canvas) {}
-
-
// Key events
+ @Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
-
+
if (event.getAction() == KeyEvent.ACTION_DOWN) {
//Log.v("SDL", "key down: " + keyCode);
SDLActivity.onNativeKeyDown(keyCode);
@@ -608,12 +551,12 @@ else if (event.getAction() == KeyEvent.ACTION_UP) {
}
// Touch events
+ @Override
public boolean onTouch(View v, MotionEvent event) {
- {
final int touchDevId = event.getDeviceId();
final int pointerCount = event.getPointerCount();
// touchId, pointerId, action, x, y, pressure
- int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent. ACTION_POINTER_ID_SHIFT; /* API 8: event.getActionIndex(); */
+ int actionPointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT; /* API 8: event.getActionIndex(); */
int pointerFingerId = event.getPointerId(actionPointerIndex);
int action = (event.getAction() & MotionEvent.ACTION_MASK); /* API 8: event.getActionMasked(); */
@@ -634,7 +577,6 @@ public boolean onTouch(View v, MotionEvent event) {
} else {
SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
}
- }
return true;
}
@@ -651,10 +593,12 @@ public void enableSensor(int sensortype, boolean enabled) {
}
}
+ @Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO
}
+ @Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
SDLActivity.onNativeAccel(event.values[0] / SensorManager.GRAVITY_EARTH,
@@ -683,6 +627,7 @@ public boolean onCheckIsTextEditor() {
return true;
}
+ @Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// This handles the hardware keyboard input
@@ -703,6 +648,23 @@ public boolean onKey(View v, int keyCode, KeyEvent event) {
return false;
}
+
+ //
+ @Override
+ public boolean onKeyPreIme (int keyCode, KeyEvent event) {
+ // As seen on StackOverflow: http://stackoverflow.com/questions/7634346/keyboard-hide-event
+ // FIXME: Discussion at http://bugzilla.libsdl.org/show_bug.cgi?id=1639
+ // FIXME: This is not a 100% effective solution to the problem of detecting if the keyboard is showing or not
+ // FIXME: A more effective solution would be to change our Layout from AbsoluteLayout to Relative or Linear
+ // FIXME: And determine the keyboard presence doing this: http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android
+ // FIXME: An even more effective way would be if Android provided this out of the box, but where would the fun be in that :)
+ if (event.getAction()==KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
+ if (SDLActivity.mTextEdit != null && SDLActivity.mTextEdit.getVisibility() == View.VISIBLE) {
+
(Patch may be truncated, please check the link at the top of this post.)