Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import android.annotation.TargetApi;
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.PixelFormat;
- import android.hardware.Sensor;
- import android.hardware.SensorEvent;
- import android.hardware.SensorEventListener;
- import android.hardware.SensorManager;
- import android.media.AudioFormat;
- import android.media.AudioManager;
- import android.media.AudioTrack;
- import android.os.Build;
- import android.os.Handler;
- import android.os.Message;
- import android.service.wallpaper.WallpaperService;
- import android.util.Log;
- import android.view.Display;
- import android.view.InputDevice;
- import android.view.KeyEvent;
- import android.view.MotionEvent;
- import android.view.Surface;
- import android.view.SurfaceHolder;
- import android.view.SurfaceView;
- import android.view.View;
- import android.view.View.OnGenericMotionListener;
- import android.view.Window;
- import android.view.WindowManager;
- import android.view.inputmethod.BaseInputConnection;
- import android.view.inputmethod.EditorInfo;
- import android.view.inputmethod.InputConnection;
- import java.io.IOException;
- import java.io.InputStream;
- import java.lang.reflect.Method;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.List;
- public class SDLActivity extends WallpaperService
- {
- private String TAG = "bb ----------- SDL Wallpaper Activity --------------";
- // Keep track of the paused state
- public static boolean mIsPaused, mIsSurfaceReady, mHasFocus;
- public static boolean mExitCalledFromJava;
- /** If shared libraries (e.g. SDL or the native application) could not be loaded. */
- public static boolean mBrokenLibraries;
- // If we want to separate mouse and touch events.
- // This is only toggled in native code when a hint is set!
- public static boolean mSeparateMouseAndTouch;
- // Main components
- protected static SDLActivity mSingleton;
- protected static SDLSurface mSurface;
- protected static SDLJoystickHandler mJoystickHandler;
- // This is what SDL runs in. It invokes SDL_main(), eventually
- protected static Thread mSDLThread;
- // Audio
- protected static AudioTrack mAudioTrack;
- protected String[] getLibraries()
- {
- return new String[] {
- "SDL2",
- // "SDL2_image",
- // "SDL2_mixer",
- // "SDL2_net",
- // "SDL2_ttf",
- "main"
- };
- }
- // Load the .so
- public void loadLibraries()
- {
- for (String lib : getLibraries())
- {
- System.loadLibrary(lib);
- }
- }
- /**
- * This method is called by SDL before starting the native application thread.
- * It can be overridden to provide the arguments after the application name.
- * The default implementation returns an empty array. It never returns null.
- * @return arguments for the native application.
- */
- protected String[] getArguments()
- {
- //
- //
- return new String[0];
- }
- public static void initialize()
- {
- // The static nature of the singleton and Android quirkyness force us to initialize everything here
- // Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values
- mSingleton = null;
- mSurface = null;
- mJoystickHandler = null;
- mSDLThread = null;
- mAudioTrack = null;
- mExitCalledFromJava = false;
- mBrokenLibraries = false;
- mIsPaused = false;
- mIsSurfaceReady = false;
- mHasFocus = true;
- }
- @Override
- public void onCreate()
- {
- //
- Log.d(TAG, "-----------SDLEngine onCreate----------");
- super.onCreate();
- create();
- }
- // Setup
- public void create()
- {
- Log.v(TAG, "Device: " + android.os.Build.DEVICE);
- Log.v(TAG, "Model: " + android.os.Build.MODEL);
- Log.v(TAG, "1st onCreate(): " + mSingleton);
- SDLActivity.initialize();
- // So we can call stuff from static callbacks
- mSingleton = this;
- Log.v(TAG, "2nd onCreate(): " + mSingleton);
- // Load shared libraries
- String errorMsgBrokenLib = "";
- try {
- loadLibraries();
- } catch(UnsatisfiedLinkError e) {
- System.err.println(e.getMessage());
- mBrokenLibraries = true;
- errorMsgBrokenLib = e.getMessage();
- } catch(Exception e) {
- System.err.println(e.getMessage());
- mBrokenLibraries = true;
- errorMsgBrokenLib = e.getMessage();
- }
- if (mBrokenLibraries)
- {
- Log.e(TAG, "failed to load .so " + errorMsgBrokenLib);
- return;
- }
- // Set up the surface
- mSurface = new SDLSurface(getApplication());
- if(Build.VERSION.SDK_INT >= 12) {
- mJoystickHandler = new SDLJoystickHandler_API12();
- }
- else {
- mJoystickHandler = new SDLJoystickHandler();
- }
- }
- // //---------------------------- beginina
- //
- // public class SDLActivityqa extends Activity
- // {
- //
- // @Override
- // public boolean dispatchKeyEvent(KeyEvent event)
- // {
- //
- // if (SDLActivity.mBrokenLibraries) {
- // return false;
- // }
- //
- // 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);
- // }
- //
- //
- // }
- //
- // //---------------------------- begininb
- /** 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.handleResume();
- }
- }
- /* The native thread has finished */
- public static void handleNativeExit()
- {
- //
- SDLActivity.mSDLThread = null;
- //mSingleton.finish();
- }
- // 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;
- static final int COMMAND_SET_KEEP_SCREEN_ON = 5;
- 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
- {
- private String TAG = "bb ---- SDLCommandHandler ----";
- //
- @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:
- if (context instanceof Activity) {
- ((Activity) context).setTitle((String)msg.obj);
- } else {
- Log.e(TAG, "error handling message, getContext() returned no Activity");
- }
- break;
- case COMMAND_SET_KEEP_SCREEN_ON:
- {
- Window window = ((Activity) context).getWindow();
- if (window != null) {
- if ((msg.obj instanceof Integer) && (((Integer) msg.obj).intValue() != 0)) {
- window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- } else {
- window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- }
- }
- 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
- boolean sendCommand(int command, Object data)
- {
- Message msg = commandHandler.obtainMessage();
- msg.arg1 = command;
- msg.obj = data;
- return commandHandler.sendMessage(msg);
- }
- // C functions we call
- public static native int nativeInit(Object arguments);
- public static native void nativeLowMemory();
- public static native void nativeQuit();
- public static native void nativePause();
- public static native void nativeResume();
- public static native void onNativeDropFile(String filename);
- public static native void onNativeResize(int x, int y, int format, float rate);
- public static native int onNativePadDown(int device_id, int keycode);
- public static native int onNativePadUp(int device_id, int keycode);
- public static native void onNativeJoy(int device_id, int axis, float value);
- public static native void onNativeHat(int device_id, int hat_id, int x, int y);
- public static native void onNativeKeyDown(int keycode);
- public static native void onNativeKeyUp(int keycode);
- public static native void onNativeKeyboardFocusLost();
- public static native void onNativeMouse(int button, int action, float x, float y);
- 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 onNativeSurfaceChanged();
- public static native void onNativeSurfaceDestroyed();
- public static native void nativeFlipBuffers();
- public static native int nativeAddJoystick(int device_id, String name, int is_accelerometer, int nbuttons, int naxes, int nhats, int nballs);
- public static native int nativeRemoveJoystick(int device_id);
- public static native String nativeGetHint(String name);
- /**
- * This method is called by SDL using JNI.
- */
- public static void flipBuffers()
- {
- //
- //
- SDLActivity.nativeFlipBuffers();
- }
- /**
- * This method is called by SDL using JNI.
- */
- public static boolean setActivityTitle(String title)
- {
- //
- // Called from SDLMain() thread and can't directly affect the view
- return mSingleton.sendCommand(COMMAND_CHANGE_TITLE, title);
- }
- /**
- * This method is called by SDL using JNI.
- */
- public static boolean sendMessage(int command, int param)
- {
- //
- //
- return mSingleton.sendCommand(command, Integer.valueOf(param));
- }
- /**
- * This method is called by SDL using JNI.
- */
- public static Context getContext()
- {
- //
- //
- return mSingleton;
- }
- /**
- * This method is called by SDL using JNI.
- * @return result of getSystemService(name) but executed on UI thread.
- */
- public Object getSystemServiceFromUiThread(final String name)
- {
- //
- return getSystemService(name);
- }
- /**
- * This method is called by SDL using JNI.
- */
- public static Surface getNativeSurface()
- {
- //
- //
- return SDLActivity.mSurface.getNativeSurface();
- }
- // Audio
- /**
- * This method is called by SDL using JNI.
- */
- public static int audioInit(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames)
- {
- String TAG = "bb ---- audioInit ----";
- 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(TAG, "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);
- 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(TAG, "Failed during initialization of Audio Track");
- mAudioTrack = null;
- return -1;
- }
- mAudioTrack.play();
- }
- Log.v(TAG, "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");
- return 0;
- }
- /**
- * This method is called by SDL using JNI.
- */
- public static void audioWriteShortBuffer(short[] buffer)
- {
- String TAG = "bb ---- audioWriteShortBuffer ----";
- for (int i = 0; i < buffer.length; ) {
- int result = mAudioTrack.write(buffer, i, buffer.length - i);
- if (result > 0) {
- i += result;
- } else if (result == 0) {
- try {
- Thread.sleep(1);
- } catch(InterruptedException e) {
- // Nom nom
- }
- } else {
- Log.w(TAG, "SDL audio: error return from write(short)");
- return;
- }
- }
- }
- /**
- * This method is called by SDL using JNI.
- */
- public static void audioWriteByteBuffer(byte[] buffer)
- {
- String TAG = "bb ---- audioWriteByteBuffer ----";
- for (int i = 0; i < buffer.length; ) {
- int result = mAudioTrack.write(buffer, i, buffer.length - i);
- if (result > 0) {
- i += result;
- } else if (result == 0) {
- try {
- Thread.sleep(1);
- } catch(InterruptedException e) {
- // Nom nom
- }
- } else {
- Log.w(TAG, "SDL audio: error return from write(byte)");
- return;
- }
- }
- }
- /**
- * This method is called by SDL using JNI.
- */
- public static void audioQuit()
- {
- if (mAudioTrack != null) {
- mAudioTrack.stop();
- mAudioTrack = null;
- }
- }
- // Input
- /**
- * This method is called by SDL using JNI.
- * @return an array which may be empty but is never null.
- */
- public static int[] inputGetInputDeviceIds(int sources)
- {
- int[] ids = InputDevice.getDeviceIds();
- int[] filtered = new int[ids.length];
- int used = 0;
- for (int i = 0; i < ids.length; ++i) {
- InputDevice device = InputDevice.getDevice(ids[i]);
- if ((device != null) && ((device.getSources() & sources) != 0)) {
- filtered[used++] = device.getId();
- }
- }
- return Arrays.copyOf(filtered, used);
- }
- // Joystick glue code, just a series of stubs that redirect to the SDLJoystickHandler instance
- public static boolean handleJoystickMotionEvent(MotionEvent event)
- {
- //
- return mJoystickHandler.handleMotionEvent(event);
- }
- /**
- * This method is called by SDL using JNI.
- */
- public static void pollInputDevices()
- {
- if (SDLActivity.mSDLThread != null)
- {
- mJoystickHandler.pollInputDevices();
- }
- }
- // APK extension files support
- /** com.android.vending.expansion.zipfile.ZipResourceFile object or null. */
- private Object expansionFile;
- /** com.android.vending.expansion.zipfile.ZipResourceFile's getInputStream() or null. */
- private Method expansionFileMethod;
- /**
- * This method is called by SDL using JNI.
- */
- public InputStream openAPKExtensionInputStream(String fileName) throws IOException
- {
- // Get a ZipResourceFile representing a merger of both the main and patch files
- if (expansionFile == null) {
- Integer mainVersion = Integer.valueOf(nativeGetHint("SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION"));
- Integer patchVersion = Integer.valueOf(nativeGetHint("SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION"));
- try {
- // To avoid direct dependency on Google APK extension library that is
- // not a part of Android SDK we access it using reflection
- expansionFile = Class.forName("com.android.vending.expansion.zipfile.APKExpansionSupport")
- .getMethod("getAPKExpansionZipFile", Context.class, int.class, int.class)
- .invoke(null, this, mainVersion, patchVersion);
- expansionFileMethod = expansionFile.getClass()
- .getMethod("getInputStream", String.class);
- } catch (Exception ex) {
- ex.printStackTrace();
- expansionFile = null;
- expansionFileMethod = null;
- }
- }
- // Get an input stream for a known file inside the expansion file ZIPs
- InputStream fileStream;
- try {
- fileStream = (InputStream)expansionFileMethod.invoke(expansionFile, fileName);
- } catch (Exception ex) {
- ex.printStackTrace();
- fileStream = null;
- }
- if (fileStream == null) {
- throw new IOException();
- }
- return fileStream;
- }
- @Override
- public void onDestroy()
- {
- //
- Log.d(TAG, "onDestroy()");
- super.onDestroy();
- }
- @Override
- public Engine onCreateEngine()
- {
- //
- Log.d(TAG, "onCreateEngine()");
- SDLEngine mEngine;
- //return new SDLEngine(this, getApplicationContext());
- if (mSurface != null)
- {
- Log.v(TAG, "Waiting for SDL thread");
- if (SDLActivity.mSDLThread != null)
- {
- SDLActivity.nativeQuit();
- try
- {
- SDLActivity.mSDLThread.join();
- }
- catch(Exception e)
- {
- Log.v(TAG, "Problem stopping thread: " + e);
- }
- }
- Log.v(TAG, "SDL thread finished");
- }
- Log.v(TAG, "Creating SDL Engine");
- mEngine = new SDLEngine(this, getApplicationContext());
- return mEngine;
- }
- class SDLEngine extends Engine
- {
- private String TAG = "bb ----- SDLEngine -----";
- public SDLEngine(SDLActivity atv, Context ctx)
- {
- //
- Log.d(TAG, "constructor");
- }
- @Override
- public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height)
- {
- //
- Log.d(TAG, "pre onSurfaceChanged()");
- mSurface.surfaceChanged(holder, format, width, height);
- Log.d(TAG, "post onSurfaceChanged()");
- }
- @Override
- public void onVisibilityChanged(boolean visible)
- {
- //
- Log.d(TAG, "onVisibilityChanged()" + visible);
- if (visible)
- {
- //resume
- Log.v(TAG, "onPause()");
- if (SDLActivity.mBrokenLibraries)
- {
- return;
- }
- SDLActivity.handleResume();
- }
- else
- {
- //pause
- Log.v(TAG, "onPause()");
- if (SDLActivity.mBrokenLibraries)
- {
- return;
- }
- SDLActivity.handlePause();
- }
- }
- @Override
- public void onDestroy()
- {
- Log.v(TAG, "onDestroy()");
- if (SDLActivity.mBrokenLibraries)
- {
- super.onDestroy();
- // Reset everything in case the user re opens the app
- SDLActivity.initialize();
- return;
- }
- // Send a quit message to the application
- SDLActivity.mExitCalledFromJava = true;
- SDLActivity.nativeQuit();
- // Now wait for the SDL thread to quit
- if (SDLActivity.mSDLThread != null)
- {
- try
- {
- SDLActivity.mSDLThread.join();
- }
- catch(Exception e)
- {
- Log.v(TAG, "Problem stopping thread: " + e);
- }
- SDLActivity.mSDLThread = null;
- Log.v(TAG, "Finished waiting for SDL thread");
- }
- super.onDestroy();
- Log.v(TAG, "Reset everything in case the user re opens the app");
- SDLActivity.initialize();
- }
- }
- }
- /* This is a fake invisible editor view that receives the input and defines the
- * pan&scan region
- */
- class SDLSurface extends SurfaceView implements SurfaceHolder.Callback, View.OnKeyListener, View.OnTouchListener, SensorEventListener
- {
- String TAG = "bb ---- SDLSurface ----";
- // Sensors
- protected static SensorManager mSensorManager;
- protected static Display mDisplay;
- // Keep track of the surface size to normalize touch events
- protected static float mWidth, mHeight;
- // Startup
- public SDLSurface(Context context) {
- super(context);
- getHolder().addCallback(this);
- setFocusable(true);
- setFocusableInTouchMode(true);
- requestFocus();
- setOnKeyListener(this);
- setOnTouchListener(this);
- mDisplay = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
- mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
- if(Build.VERSION.SDK_INT >= 12) {
- setOnGenericMotionListener(new SDLGenericMotionListener_API12());
- }
- // Some arbitrary defaults to avoid a potential division by zero
- mWidth = 1.0f;
- mHeight = 1.0f;
- }
- public void handleResume() {
- setFocusable(true);
- setFocusableInTouchMode(true);
- requestFocus();
- setOnKeyListener(this);
- setOnTouchListener(this);
- enableSensor(Sensor.TYPE_ACCELEROMETER, true);
- }
- public Surface getNativeSurface() {
- return getHolder().getSurface();
- }
- // Called when we have a valid drawing surface
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- Log.v(TAG, "surfaceCreated()");
- holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
- }
- // Called when we lose the surface
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- Log.v(TAG, "surfaceDestroyed()");
- // 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(TAG, "surfaceChanged()");
- int sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565 by default
- switch (format) {
- case PixelFormat.A_8:
- Log.v(TAG, "pixel format A_8");
- break;
- case PixelFormat.LA_88:
- Log.v(TAG, "pixel format LA_88");
- break;
- case PixelFormat.L_8:
- Log.v(TAG, "pixel format L_8");
- break;
- case PixelFormat.RGBA_4444:
- Log.v(TAG, "pixel format RGBA_4444");
- sdlFormat = 0x15421002; // SDL_PIXELFORMAT_RGBA4444
- break;
- case PixelFormat.RGBA_5551:
- Log.v(TAG, "pixel format RGBA_5551");
- sdlFormat = 0x15441002; // SDL_PIXELFORMAT_RGBA5551
- break;
- case PixelFormat.RGBA_8888:
- Log.v(TAG, "pixel format RGBA_8888");
- sdlFormat = 0x16462004; // SDL_PIXELFORMAT_RGBA8888
- break;
- case PixelFormat.RGBX_8888:
- Log.v(TAG, "pixel format RGBX_8888");
- sdlFormat = 0x16261804; // SDL_PIXELFORMAT_RGBX8888
- break;
- case PixelFormat.RGB_332:
- Log.v(TAG, "pixel format RGB_332");
- sdlFormat = 0x14110801; // SDL_PIXELFORMAT_RGB332
- break;
- case PixelFormat.RGB_565:
- Log.v(TAG, "pixel format RGB_565");
- sdlFormat = 0x15151002; // SDL_PIXELFORMAT_RGB565
- break;
- case PixelFormat.RGB_888:
- Log.v(TAG, "pixel format RGB_888");
- // Not sure this is right, maybe SDL_PIXELFORMAT_RGB24 instead?
- sdlFormat = 0x16161804; // SDL_PIXELFORMAT_RGB888
- break;
- default:
- Log.v(TAG, "pixel format unknown " + format);
- break;
- }
- mWidth = width;
- mHeight = height;
- SDLActivity.onNativeResize(width, height, sdlFormat, mDisplay.getRefreshRate());
- Log.v(TAG, "Window size: " + width + "x" + height);
- // Set mIsSurfaceReady to 'true' *before* making a call to handleResume
- SDLActivity.mIsSurfaceReady = true;
- SDLActivity.onNativeSurfaceChanged();
- Log.v(TAG, "SDLActivity.mIsSurfaceReady: " + SDLActivity.mIsSurfaceReady);
- if (SDLActivity.mSDLThread == null)
- {
- Log.v(TAG, "This is the entry point to the C app. mDSLThread is null");
- // This is the entry point to the C app.
- // Start up the C app thread and enable sensor input for the first time
- final Thread sdlThread = new Thread(new SDLMain(), "SDLThread");
- enableSensor(Sensor.TYPE_ACCELEROMETER, true);
- sdlThread.start();
- // Set up a listener thread to catch when the native thread ends
- SDLActivity.mSDLThread = new Thread(new Runnable(){
- @Override
- public void run()
- {
- try
- {
- Log.v(TAG, "mSDLThread run try block");
- sdlThread.join();
- }
- catch(Exception e)
- {
- Log.v(TAG, " SDL thread exception: "+e.getMessage());
- }
- finally
- {
- // Native thread has finished
- Log.v(TAG, "Native thread has finished");
- if (!SDLActivity.mExitCalledFromJava)
- {
- Log.v(TAG, "handle native exit? " + !SDLActivity.mExitCalledFromJava);
- SDLActivity.handleNativeExit();
- }
- }
- }
- }, "SDLThreadListener");
- Log.v(TAG, "pre thread start");
- SDLActivity.mSDLThread.start();
- Log.v(TAG, "post thread start");
- }
- if (SDLActivity.mHasFocus)
- {
- Log.v(TAG, "SDLActivity mHasFocus " + SDLActivity.mHasFocus);
- SDLActivity.handleResume();
- }
- }
- // unused
- @Override
- public void onDraw(Canvas canvas) {}
- // Key events
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- // Dispatch the different events depending on where they come from
- // Some SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
- // So, we try to process them as DPAD or GAMEPAD events first, if that fails we try them as KEYBOARD
- if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) != 0 ||
- (event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) {
- return true;
- }
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- if (SDLActivity.onNativePadUp(event.getDeviceId(), keyCode) == 0) {
- return true;
- }
- }
- }
- if( (event.getSource() & InputDevice.SOURCE_KEYBOARD) != 0) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- //Log.v(TAG, "key down: " + keyCode);
- SDLActivity.onNativeKeyDown(keyCode);
- return true;
- }
- else if (event.getAction() == KeyEvent.ACTION_UP) {
- //Log.v(TAG, "key up: " + keyCode);
- SDLActivity.onNativeKeyUp(keyCode);
- return true;
- }
- }
- return false;
- }
- // Touch events
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- /* Ref: http://developer.android.com/training/gestures/multi.html */
- final int touchDevId = event.getDeviceId();
- final int pointerCount = event.getPointerCount();
- int action = event.getActionMasked();
- int pointerFingerId;
- int mouseButton;
- int i = -1;
- float x,y,p;
- // !!! FIXME: dump this SDK check after 2.0.4 ships and require API14.
- if (event.getSource() == InputDevice.SOURCE_MOUSE && SDLActivity.mSeparateMouseAndTouch) {
- if (Build.VERSION.SDK_INT < 14) {
- mouseButton = 1; // For Android==12 all mouse buttons are the left button
- } else {
- try {
- mouseButton = (Integer) event.getClass().getMethod("getButtonState").invoke(event);
- } catch(Exception e) {
- mouseButton = 1; // oh well.
- }
- }
- SDLActivity.onNativeMouse(mouseButton, action, event.getX(0), event.getY(0));
- } else {
- switch(action) {
- case MotionEvent.ACTION_MOVE:
- for (i = 0; i < pointerCount; i++) {
- pointerFingerId = event.getPointerId(i);
- x = event.getX(i) / mWidth;
- y = event.getY(i) / mHeight;
- p = event.getPressure(i);
- if (p > 1.0f) {
- // may be larger than 1.0f on some devices
- // see the documentation of getPressure(i)
- p = 1.0f;
- }
- SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
- }
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_DOWN:
- // Primary pointer up/down, the index is always zero
- i = 0;
- case MotionEvent.ACTION_POINTER_UP:
- case MotionEvent.ACTION_POINTER_DOWN:
- // Non primary pointer up/down
- if (i == -1) {
- i = event.getActionIndex();
- }
- pointerFingerId = event.getPointerId(i);
- x = event.getX(i) / mWidth;
- y = event.getY(i) / mHeight;
- p = event.getPressure(i);
- if (p > 1.0f) {
- // may be larger than 1.0f on some devices
- // see the documentation of getPressure(i)
- p = 1.0f;
- }
- SDLActivity.onNativeTouch(touchDevId, pointerFingerId, action, x, y, p);
- break;
- case MotionEvent.ACTION_CANCEL:
- for (i = 0; i < pointerCount; i++) {
- pointerFingerId = event.getPointerId(i);
- x = event.getX(i) / mWidth;
- y = event.getY(i) / mHeight;
- p = event.getPressure(i);
- if (p > 1.0f) {
- // may be larger than 1.0f on some devices
- // see the documentation of getPressure(i)
- p = 1.0f;
- }
- SDLActivity.onNativeTouch(touchDevId, pointerFingerId, MotionEvent.ACTION_UP, x, y, p);
- }
- break;
- default:
- break;
- }
- }
- return true;
- }
- // Sensor events
- public void enableSensor(int sensortype, boolean enabled) {
- // TODO: This uses getDefaultSensor - what if we have >1 accels?
- if (enabled) {
- mSensorManager.registerListener(this,
- mSensorManager.getDefaultSensor(sensortype),
- SensorManager.SENSOR_DELAY_GAME, null);
- } else {
- mSensorManager.unregisterListener(this,
- mSensorManager.getDefaultSensor(sensortype));
- }
- }
- @Override
- public void onAccuracyChanged(Sensor sensor, int accuracy) {
- // TODO
- }
- @Override
- public void onSensorChanged(SensorEvent event) {
- if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
- float x, y;
- switch (mDisplay.getRotation()) {
- case Surface.ROTATION_90:
- x = -event.values[1];
- y = event.values[0];
- break;
- case Surface.ROTATION_270:
- x = event.values[1];
- y = -event.values[0];
- break;
- case Surface.ROTATION_180:
- x = -event.values[1];
- y = -event.values[0];
- break;
- default:
- x = event.values[0];
- y = event.values[1];
- break;
- }
- SDLActivity.onNativeAccel(-x / SensorManager.GRAVITY_EARTH,
- y / SensorManager.GRAVITY_EARTH,
- event.values[2] / SensorManager.GRAVITY_EARTH - 1);
- }
- }
- }
- /* This is a fake invisible editor view that receives the input and defines the
- * pan&scan region
- */
- class DummyEdit extends View implements View.OnKeyListener
- {
- InputConnection ic;
- public DummyEdit(Context context) {
- super(context);
- setFocusableInTouchMode(true);
- setFocusable(true);
- setOnKeyListener(this);
- }
- @Override
- public boolean onCheckIsTextEditor() {
- return true;
- }
- @Override
- public boolean onKey(View v, int keyCode, KeyEvent event) {
- // This handles the hardware keyboard input
- if (event.isPrintingKey()) {
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- ic.commitText(String.valueOf((char) event.getUnicodeChar()), 1);
- }
- return true;
- }
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- SDLActivity.onNativeKeyDown(keyCode);
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- SDLActivity.onNativeKeyUp(keyCode);
- return true;
- }
- return false;
- }
- @Override
- public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
- ic = new SDLInputConnection(this, true);
- outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
- | 33554432 /* API 11: EditorInfo.IME_FLAG_NO_FULLSCREEN */;
- return ic;
- }
- }
- class SDLInputConnection extends BaseInputConnection
- {
- public SDLInputConnection(View targetView, boolean fullEditor) {
- super(targetView, fullEditor);
- }
- @Override
- public boolean sendKeyEvent(KeyEvent event) {
- /*
- * This handles the keycodes from soft keyboard (and IME-translated
- * input from hardkeyboard)
- */
- int keyCode = event.getKeyCode();
- if (event.getAction() == KeyEvent.ACTION_DOWN) {
- if (event.isPrintingKey()) {
- commitText(String.valueOf((char) event.getUnicodeChar()), 1);
- }
- SDLActivity.onNativeKeyDown(keyCode);
- return true;
- } else if (event.getAction() == KeyEvent.ACTION_UP) {
- SDLActivity.onNativeKeyUp(keyCode);
- return true;
- }
- return super.sendKeyEvent(event);
- }
- @Override
- public boolean commitText(CharSequence text, int newCursorPosition) {
- nativeCommitText(text.toString(), newCursorPosition);
- return super.commitText(text, newCursorPosition);
- }
- @Override
- public boolean setComposingText(CharSequence text, int newCursorPosition) {
- nativeSetComposingText(text.toString(), newCursorPosition);
- return super.setComposingText(text, newCursorPosition);
- }
- public native void nativeCommitText(String text, int newCursorPosition);
- public native void nativeSetComposingText(String text, int newCursorPosition);
- @Override
- public boolean deleteSurroundingText(int beforeLength, int afterLength) {
- // Workaround to capture backspace key. Ref: http://stackoverflow.com/questions/14560344/android-backspace-in-webview-baseinputconnection
- if (beforeLength == 1 && afterLength == 0) {
- // backspace
- return super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL))
- && super.sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_DEL));
- }
- return super.deleteSurroundingText(beforeLength, afterLength);
- }
- }
- /* A null joystick handler for API level < 12 devices (the accelerometer is handled separately) */
- class SDLJoystickHandler
- {
- /**
- * Handles given MotionEvent.
- * @param event the event to be handled.
- * @return if given event was processed.
- */
- public boolean handleMotionEvent(MotionEvent event) {
- return false;
- }
- /**
- * Handles adding and removing of input devices.
- */
- public void pollInputDevices() {
- }
- }
- /* Actual joystick functionality available for API >= 12 devices */
- class SDLJoystickHandler_API12 extends SDLJoystickHandler
- {
- static class SDLJoystick {
- public int device_id;
- public String name;
- public ArrayList<InputDevice.MotionRange> axes;
- public ArrayList<InputDevice.MotionRange> hats;
- }
- static class RangeComparator implements Comparator<InputDevice.MotionRange> {
- @Override
- public int compare(InputDevice.MotionRange arg0, InputDevice.MotionRange arg1) {
- return arg0.getAxis() - arg1.getAxis();
- }
- }
- private ArrayList<SDLJoystick> mJoysticks;
- public SDLJoystickHandler_API12() {
- mJoysticks = new ArrayList<SDLJoystick>();
- }
- @Override
- public void pollInputDevices() {
- int[] deviceIds = InputDevice.getDeviceIds();
- // It helps processing the device ids in reverse order
- // For example, in the case of the XBox 360 wireless dongle,
- // so the first controller seen by SDL matches what the receiver
- // considers to be the first controller
- for(int i=deviceIds.length-1; i>-1; i--) {
- SDLJoystick joystick = getJoystick(deviceIds[i]);
- if (joystick == null) {
- joystick = new SDLJoystick();
- InputDevice joystickDevice = InputDevice.getDevice(deviceIds[i]);
- if (
- (joystickDevice.getSources() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0
- ||
- (joystickDevice.getSources() & InputDevice.SOURCE_CLASS_BUTTON) != 0
- )
- {
- joystick.device_id = deviceIds[i];
- joystick.name = joystickDevice.getName();
- joystick.axes = new ArrayList<InputDevice.MotionRange>();
- joystick.hats = new ArrayList<InputDevice.MotionRange>();
- List<InputDevice.MotionRange> ranges = joystickDevice.getMotionRanges();
- Collections.sort(ranges, new RangeComparator());
- for (InputDevice.MotionRange range : ranges ) {
- if ((range.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) != 0 ) {
- if (range.getAxis() == MotionEvent.AXIS_HAT_X ||
- range.getAxis() == MotionEvent.AXIS_HAT_Y) {
- joystick.hats.add(range);
- }
- else {
- joystick.axes.add(range);
- }
- }
- }
- mJoysticks.add(joystick);
- SDLActivity.nativeAddJoystick(joystick.device_id, joystick.name, 0, -1,
- joystick.axes.size(), joystick.hats.size()/2, 0);
- }
- }
- }
- /* Check removed devices */
- ArrayList<Integer> removedDevices = new ArrayList<Integer>();
- for(int i=0; i < mJoysticks.size(); i++) {
- int device_id = mJoysticks.get(i).device_id;
- int j;
- for (j=0; j < deviceIds.length; j++) {
- if (device_id == deviceIds[j]) break;
- }
- if (j == deviceIds.length) {
- removedDevices.add(Integer.valueOf(device_id));
- }
- }
- for(int i=0; i < removedDevices.size(); i++) {
- int device_id = removedDevices.get(i).intValue();
- SDLActivity.nativeRemoveJoystick(device_id);
- for (int j=0; j < mJoysticks.size(); j++) {
- if (mJoysticks.get(j).device_id == device_id) {
- mJoysticks.remove(j);
- break;
- }
- }
- }
- }
- protected SDLJoystick getJoystick(int device_id) {
- for(int i=0; i < mJoysticks.size(); i++) {
- if (mJoysticks.get(i).device_id == device_id) {
- return mJoysticks.get(i);
- }
- }
- return null;
- }
- @Override
- public boolean handleMotionEvent(MotionEvent event) {
- if ( (event.getSource() & InputDevice.SOURCE_JOYSTICK) != 0) {
- int actionPointerIndex = event.getActionIndex();
- int action = event.getActionMasked();
- switch(action) {
- case MotionEvent.ACTION_MOVE:
- SDLJoystick joystick = getJoystick(event.getDeviceId());
- if ( joystick != null ) {
- for (int i = 0; i < joystick.axes.size(); i++) {
- InputDevice.MotionRange range = joystick.axes.get(i);
- /* Normalize the value to -1...1 */
- float value = ( event.getAxisValue( range.getAxis(), actionPointerIndex) - range.getMin() ) / range.getRange() * 2.0f - 1.0f;
- SDLActivity.onNativeJoy(joystick.device_id, i, value );
- }
- for (int i = 0; i < joystick.hats.size(); i+=2) {
- int hatX = Math.round(event.getAxisValue( joystick.hats.get(i).getAxis(), actionPointerIndex ) );
- int hatY = Math.round(event.getAxisValue( joystick.hats.get(i+1).getAxis(), actionPointerIndex ) );
- SDLActivity.onNativeHat(joystick.device_id, i/2, hatX, hatY );
- }
- }
- break;
- default:
- break;
- }
- }
- return true;
- }
- }
- @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
- class SDLGenericMotionListener_API12 implements OnGenericMotionListener
- {
- // Generic Motion (mouse hover, joystick...) events go here
- @Override
- public boolean onGenericMotion(View v, MotionEvent event) {
- float x, y;
- int mouseButton;
- int action;
- switch ( event.getSource() ) {
- case InputDevice.SOURCE_JOYSTICK:
- case InputDevice.SOURCE_GAMEPAD:
- case InputDevice.SOURCE_DPAD:
- SDLActivity.handleJoystickMotionEvent(event);
- return true;
- case InputDevice.SOURCE_MOUSE:
- action = event.getActionMasked();
- switch (action) {
- case MotionEvent.ACTION_SCROLL:
- x = event.getAxisValue(MotionEvent.AXIS_HSCROLL, 0);
- y = event.getAxisValue(MotionEvent.AXIS_VSCROLL, 0);
- SDLActivity.onNativeMouse(0, action, x, y);
- return true;
- case MotionEvent.ACTION_HOVER_MOVE:
- x = event.getX(0);
- y = event.getY(0);
- SDLActivity.onNativeMouse(0, action, x, y);
- return true;
- default:
- break;
- }
- default:
- break;
- }
- // Event was not managed
- return false;
- }
- }
- class SDLMain implements Runnable
- {
- @Override
- public void run()
- {
- Log.v("bb -----------SDL Main -----------", "pre SDL thread");
- SDLActivity.nativeInit(SDLActivity.mSingleton.getArguments());
- Log.v("bb -----------SDL Main -----------", "post SDL thread");
- }
- }
- ======================
- logcat output
- D/bb ----- SDLEngine -----(21706): constructor
- D/bb ----- SDLEngine -----(21706): pre onSurfaceChanged()
- V/bb ---- SDLSurface ----(21706): surfaceChanged()
- V/bb ---- SDLSurface ----(21706): pixel format RGBX_8888
- V/bb ---- SDLSurface ----(21706): Window size: 720x1280
- V/bb ---- SDLSurface ----(21706): SDLActivity.mIsSurfaceReady: true
- V/bb ---- SDLSurface ----(21706): This is the entry point to the C app. mDSLThread is null
- V/bb -----------SDL Main -----------(21706): pre SDL thread
- V/bb ---- SDLSurface ----(21706): pre thread start
- V/bb ---- SDLSurface ----(21706): post thread start
- V/bb ---- SDLSurface ----(21706): SDLActivity mHasFocus true
- D/bb ----- SDLEngine -----(21706): post onSurfaceChanged()
- D/bb ----- SDLEngine -----(21706): onVisibilityChanged()true
- V/bb ----- SDLEngine -----(21706): onPause()
- D/bb ----- SDLEngine -----(21706): onVisibilityChanged()false
- V/bb ----- SDLEngine -----(21706): onPause()
- V/bb ---- SDLSurface ----(21706): mSDLThread run try block
- D/bb ----- SDLEngine -----(21706): onVisibilityChanged()true
- V/bb ----- SDLEngine -----(21706): onPause()
- V/bb -----------SDL Main -----------(21706): post SDL thread
- V/bb ---- SDLSurface ----(21706): Native thread has finished
- V/bb ---- SDLSurface ----(21706): handle native exit? true
- D/bb ----------- SDL Wallpaper Activity --------------(21778): -----------SDLEngine onCreate----------
- D/bb ----------- SDL Wallpaper Activity --------------(21778): onCreateEngine()
- V/bb ----------- SDL Wallpaper Activity --------------(21778): Creating SDL Engine
- V/bb ----------- SDL Wallpaper Activity --------------(21778): Device: m0
- V/bb ----------- SDL Wallpaper Activity --------------(21778): Model: GT-I9300
- V/bb ----------- SDL Wallpaper Activity --------------(21778): 1st onCreate(): null
- V/bb ----------- SDL Wallpaper Activity --------------(21778): 2nd onCreate(): org.libsdl.app.SDLActivity@426b8a90
- D/bb ----- SDLEngine -----(21778): constructor
- D/bb ----- SDLEngine -----(21778): pre onSurfaceChanged()
- V/bb ---- SDLSurface ----(21778): surfaceChanged()
- V/bb ---- SDLSurface ----(21778): pixel format RGBX_8888
- V/bb ---- SDLSurface ----(21778): Window size: 720x1280
- V/bb ---- SDLSurface ----(21778): SDLActivity.mIsSurfaceReady: true
- V/bb ---- SDLSurface ----(21778): This is the entry point to the C app. mDSLThread is null
- V/bb -----------SDL Main -----------(21778): pre SDL thread
- V/bb ---- SDLSurface ----(21778): pre thread start
- V/bb ---- SDLSurface ----(21778): post thread start
- V/bb ---- SDLSurface ----(21778): mSDLThread run try block
- V/bb ---- SDLSurface ----(21778): SDLActivity mHasFocus true
- D/bb ----- SDLEngine -----(21778): post onSurfaceChanged()
- D/bb ----- SDLEngine -----(21778): onVisibilityChanged()true
- V/bb ----- SDLEngine -----(21778): onPause()
- D/bb ----- SDLEngine -----(21778): onVisibilityChanged()false
- V/bb ----- SDLEngine -----(21778): onPause()
- D/bb ----- SDLEngine -----(21778): onVisibilityChanged()true
- V/bb ----- SDLEngine -----(21778): onPause()
- V/bb -----------SDL Main -----------(21778): post SDL thread
- V/bb ---- SDLSurface ----(21778): Native thread has finished
- V/bb ---- SDLSurface ----(21778): handle native exit? true
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement