From a6dba1278e1c669a846cbea293a27a744b1ce9f3 Mon Sep 17 00:00:00 2001 From: pelya Date: Fri, 15 Oct 2010 19:41:13 +0300 Subject: [PATCH] Fixed accelerometer joystick, added on-screen keyboard DPAD acting as a joystick --- .../src/video/android/SDL_androidinput.c | 94 ++++++++------ .../src/video/android/SDL_androidinput.h | 2 - .../src/video/android/SDL_androidvideo.h | 8 +- .../video/android/SDL_touchscreenkeyboard.c | 122 ++++++++++++------ project/res/values/strings.xml | 5 + project/src/Accelerometer.java | 22 ++-- project/src/Globals.java | 1 + project/src/Settings.java | 41 +++++- project/src/Video.java | 4 +- 9 files changed, 197 insertions(+), 102 deletions(-) diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c index 6b55844f0..404259045 100644 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c @@ -46,9 +46,9 @@ SDLKey SDL_android_keymap[KEYCODE_LAST+1]; static int isTrackballUsed = 0; static int isMouseUsed = 0; -static int isJoystickUsed = 0; +int SDL_ANDROID_isJoystickUsed = 0; static int isMultitouchUsed = 0; -static SDL_Joystick *CurrentJoysticks[MAX_MULTITOUCH_POINTERS+1] = {NULL}; +SDL_Joystick *SDL_ANDROID_CurrentJoysticks[MAX_MULTITOUCH_POINTERS+1] = {NULL}; static int TrackballDampening = 0; // in milliseconds static int lastTrackballAction = 0; @@ -90,16 +90,16 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouse) ( JNIEnv* env, jobject thiz, j SDL_SendFingerDown(0, pointerId, action == MOUSE_DOWN ? 1 : 0, x, y, force*radius / 16); #endif - if( CurrentJoysticks[pointerId] ) + if( SDL_ANDROID_CurrentJoysticks[pointerId] ) { - SDL_PrivateJoystickAxis(CurrentJoysticks[pointerId+1], 0, x); - SDL_PrivateJoystickAxis(CurrentJoysticks[pointerId+1], 1, y); - SDL_PrivateJoystickAxis(CurrentJoysticks[pointerId+1], 2, force); - SDL_PrivateJoystickAxis(CurrentJoysticks[pointerId+1], 3, radius); + SDL_PrivateJoystickAxis(SDL_ANDROID_CurrentJoysticks[pointerId+1], 0, x); + SDL_PrivateJoystickAxis(SDL_ANDROID_CurrentJoysticks[pointerId+1], 1, y); + SDL_PrivateJoystickAxis(SDL_ANDROID_CurrentJoysticks[pointerId+1], 2, force); + SDL_PrivateJoystickAxis(SDL_ANDROID_CurrentJoysticks[pointerId+1], 3, radius); if( action == MOUSE_DOWN ) - SDL_PrivateJoystickButton(CurrentJoysticks[pointerId+1], 0, SDL_PRESSED); + SDL_PrivateJoystickButton(SDL_ANDROID_CurrentJoysticks[pointerId+1], 0, SDL_PRESSED); if( action == MOUSE_UP ) - SDL_PrivateJoystickButton(CurrentJoysticks[pointerId+1], 0, SDL_RELEASED); + SDL_PrivateJoystickButton(SDL_ANDROID_CurrentJoysticks[pointerId+1], 0, SDL_RELEASED); } } if( !isMouseUsed && !SDL_ANDROID_isTouchscreenKeyboardUsed ) @@ -152,9 +152,11 @@ JAVA_EXPORT_NAME(AccelerometerReader_nativeAccelerometer) ( JNIEnv* env, jobjec // Calculate two angles from three coordinates - TODO: this is faulty! //float accX = atan2f(-accPosX, sqrtf(accPosY*accPosY+accPosZ*accPosZ) * ( accPosY > 0 ? 1.0f : -1.0f ) ) * M_1_PI * 180.0f; //float accY = atan2f(accPosZ, accPosY) * M_1_PI; + float normal = sqrt(accPosX*accPosX+accPosY*accPosY+accPosZ*accPosZ); if(normal <= 0.0000001f) - normal = 1.0f; + normal = 0.00001f; + updateOrientation (accPosX/normal, accPosY/normal, 0.0f); } @@ -163,7 +165,7 @@ JAVA_EXPORT_NAME(AccelerometerReader_nativeAccelerometer) ( JNIEnv* env, jobjec JNIEXPORT void JNICALL JAVA_EXPORT_NAME(AccelerometerReader_nativeOrientation) ( JNIEnv* env, jobject thiz, jfloat accX, jfloat accY, jfloat accZ ) { - updateOrientation (accX, accY, accZ); + updateOrientation (accX, accY, accZ); // TODO: make values in range 0.0:1.0 } JNIEXPORT void JNICALL @@ -181,7 +183,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) ( JNIEnv* env, jobject thiz) JNIEXPORT void JNICALL JAVA_EXPORT_NAME(Settings_nativeSetJoystickUsed) ( JNIEnv* env, jobject thiz) { - isJoystickUsed = 1; + SDL_ANDROID_isJoystickUsed = 1; } JNIEXPORT void JNICALL @@ -342,20 +344,23 @@ void ANDROID_InitOSKeymap() } -static float dx = 0.04, dy = 0.1, dz = 0.1; // For accelerometer +static float dx = 0.04, dy = 0.1, dz = 0.1, joystickSensitivity = 400.0f; // For accelerometer +enum { ACCELEROMETER_CENTER_FLOATING, ACCELEROMETER_CENTER_FIXED_START, ACCELEROMETER_CENTER_FIXED_HORIZ }; +static int accelerometerCenterPos = ACCELEROMETER_CENTER_FLOATING; JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetAccelerometerSensitivity) ( JNIEnv* env, jobject thiz, jint value) +JAVA_EXPORT_NAME(Settings_nativeSetAccelerometerSettings) ( JNIEnv* env, jobject thiz, jint sensitivity, jint centerPos) { - dx = 0.04; dy = 0.08; dz = 0.08; // Fast sensitivity - if( value == 1 ) // Medium sensitivity + dx = 0.04; dy = 0.08; dz = 0.08; joystickSensitivity = 32767.0f * 3.0f; // Fast sensitivity + if( sensitivity == 1 ) { - dx = 0.1; dy = 0.15; dz = 0.15; + dx = 0.1; dy = 0.15; dz = 0.15; joystickSensitivity = 32767.0f * 2.0f; // Medium sensitivity } - if( value == 2 ) // Slow sensitivity + if( sensitivity == 2 ) { - dx = 0.2; dy = 0.25; dz = 0.25; + dx = 0.2; dy = 0.25; dz = 0.25; joystickSensitivity = 32767.0f; // Slow sensitivity } + accelerometerCenterPos = centerPos; } JNIEXPORT void JNICALL @@ -372,30 +377,41 @@ void updateOrientation ( float accX, float accY, float accZ ) static float midX = 0, midY = 0, midZ = 0; static int pressLeft = 0, pressRight = 0, pressUp = 0, pressDown = 0, pressR = 0, pressL = 0; - midX = 0.0f; // Do not remember old value for phone tilt, it feels weird - - if( isJoystickUsed && CurrentJoysticks[0] ) // TODO: mutex for that stuff? + if( accelerometerCenterPos == ACCELEROMETER_CENTER_FIXED_START ) { - SDL_PrivateJoystickAxis(CurrentJoysticks[0], 0, (Sint16)(fmin(32767, fmax(-32768, (accX - midX) * 400.0)))); - SDL_PrivateJoystickAxis(CurrentJoysticks[0], 1, (Sint16)(fmin(32767, fmax(-32768, (accY - midY) * 400.0)))); - SDL_PrivateJoystickAxis(CurrentJoysticks[0], 2, (Sint16)(fmin(32767, fmax(-32768, (accZ - midZ) * 400.0)))); + accelerometerCenterPos = ACCELEROMETER_CENTER_FIXED_HORIZ; + midX = accX; + midY = accY; + midZ = accZ; + } + + // midX = 0.0f; // Do not remember old value for phone tilt, it feels weird - // TODO: option for fixed/floating center pos - if( accY < midY - dy*2 ) - midY = accY + dy*2; - if( accY > midY + dy*2 ) - midY = accY - dy*2; - if( accZ < midZ - dz*2 ) - midZ = accZ + dz*2; - if( accZ > midZ + dz*2 ) - midZ = accZ - dz*2; + __android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): %f %f %f", accX, accY, accZ); + + if( SDL_ANDROID_isJoystickUsed && SDL_ANDROID_CurrentJoysticks[0] ) // TODO: mutex for that stuff? + { + __android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): sending joystick event"); + SDL_PrivateJoystickAxis(SDL_ANDROID_CurrentJoysticks[0], 0, (Sint16)(fminf(32767.0f, fmax(-32767.0f, (accX - midX) * joystickSensitivity)))); + SDL_PrivateJoystickAxis(SDL_ANDROID_CurrentJoysticks[0], 1, (Sint16)(fminf(32767.0f, fmax(-32767.0f, (accY - midY) * joystickSensitivity)))); + SDL_PrivateJoystickAxis(SDL_ANDROID_CurrentJoysticks[0], 2, (Sint16)(fminf(32767.0f, fmax(-32767.0f, (accZ - midZ) * joystickSensitivity)))); + if( accelerometerCenterPos == ACCELEROMETER_CENTER_FLOATING ) + { + if( accY < midY - dy*2 ) + midY = accY + dy*2; + if( accY > midY + dy*2 ) + midY = accY - dy*2; + if( accZ < midZ - dz*2 ) + midZ = accZ + dz*2; + if( accZ > midZ + dz*2 ) + midZ = accZ - dz*2; + } } - if(isJoystickUsed) + if(SDL_ANDROID_isJoystickUsed) return; - if( accX < midX - dx ) { if( !pressLeft ) @@ -674,7 +690,7 @@ int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) joystick->naxes = 4; joystick->nbuttons = 1; } - CurrentJoysticks[joystick->index] = joystick; + SDL_ANDROID_CurrentJoysticks[joystick->index] = joystick; return(0); } @@ -691,7 +707,7 @@ void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) /* Function to close a joystick after use */ void SDL_SYS_JoystickClose(SDL_Joystick *joystick) { - CurrentJoysticks[joystick->index] = NULL; + SDL_ANDROID_CurrentJoysticks[joystick->index] = NULL; return; } @@ -700,6 +716,6 @@ void SDL_SYS_JoystickQuit(void) { int i; for(i=0; iSlow Accelerometer sensitivity + Floating + Fixed when application starts + Fixed to table desk orientation + Accelerometer center position + Very small (fast devices, less lag) Small Medium diff --git a/project/src/Accelerometer.java b/project/src/Accelerometer.java index b84f9dc0c..df1fa3a58 100644 --- a/project/src/Accelerometer.java +++ b/project/src/Accelerometer.java @@ -22,21 +22,17 @@ class AccelerometerReader implements SensorEventListener { private SensorManager _manager = null; public AccelerometerReader(Activity context) { - _manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); - if( _manager != null ) + System.out.println("libSDL: accelerometer start required: " + String.valueOf(Globals.UseAccelerometerAsArrowKeys)); + if( Globals.UseAccelerometerAsArrowKeys ) { - if( Globals.UseAccelerometerAsArrowKeys ) + _manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); + if( _manager != null ) { + System.out.println("libSDL: starting accelerometer"); + // TODO: orientation allows for 3rd axis - azimuth, but it will be way too hard to the user + // if( ! _manager.registerListener(this, _manager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME) ) _manager.registerListener(this, _manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME); } - else - { - if( Globals.AppUsesJoystick ) - { - if( ! _manager.registerListener(this, _manager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME) ) - _manager.registerListener(this, _manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME); - } - } } } @@ -55,9 +51,9 @@ class AccelerometerReader implements SensorEventListener { // TODO: it feels better for me to use tilt as X value instead of intuitive horizontal phone orientation // because then I can hold device comfortably, we need another user-configurable option for that // nativeOrientation(event.values[1], -event.values[2], event.values[0]); // Comfortable setting - nativeAccelerometer(event.values[1], -event.values[0], event.values[2]); // Intuitive setting + nativeAccelerometer(-event.values[1], -event.values[0], event.values[2]); // Intuitive setting else - nativeAccelerometer(event.values[0], event.values[1], event.values[2]); + nativeAccelerometer(event.values[0], event.values[1], event.values[2]); // TODO: not tested! } else { diff --git a/project/src/Globals.java b/project/src/Globals.java index 1165619ed..f752c25b8 100644 --- a/project/src/Globals.java +++ b/project/src/Globals.java @@ -47,6 +47,7 @@ class Globals { public static int TouchscreenKeyboardSize = 0; public static int TouchscreenKeyboardTheme = 0; public static int AccelerometerSensitivity = 0; + public static int AccelerometerCenterPos = 0; public static int TrackballDampening = 0; public static int AudioBufferConfig = 0; public static boolean OptionalDataDownload[] = null; diff --git a/project/src/Settings.java b/project/src/Settings.java index 1e662672a..0ac83c458 100644 --- a/project/src/Settings.java +++ b/project/src/Settings.java @@ -297,7 +297,7 @@ class Settings static void showAdditionalInputConfig(final MainActivity p) { - if( ! Globals.AppNeedsArrowKeys ) + if( ! Globals.AppNeedsArrowKeys && ! Globals.AppUsesJoystick ) { showAccelerometerConfig(p); return; @@ -341,7 +341,7 @@ class Settings Globals.AccelerometerSensitivity = 0; if( ! Globals.UseAccelerometerAsArrowKeys ) { - showScreenKeyboardConfig(p); + showAccelerometerCenterConfig(p); return; } @@ -357,6 +357,36 @@ class Settings { Globals.AccelerometerSensitivity = item; + dialog.dismiss(); + showAccelerometerCenterConfig(p); + } + }); + AlertDialog alert = builder.create(); + alert.setOwnerActivity(p); + alert.show(); + } + + static void showAccelerometerCenterConfig(final MainActivity p) + { + Globals.AccelerometerSensitivity = 0; + if( ! Globals.UseAccelerometerAsArrowKeys ) + { + showScreenKeyboardConfig(p); + return; + } + + final CharSequence[] items = { p.getResources().getString(R.string.accel_floating), + p.getResources().getString(R.string.accel_fixed_start), + p.getResources().getString(R.string.accel_fixed_horiz) }; + + AlertDialog.Builder builder = new AlertDialog.Builder(p); + builder.setTitle(R.string.accel_question_center); + builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() + { + public void onClick(DialogInterface dialog, int item) + { + Globals.AccelerometerCenterPos = item; + dialog.dismiss(); showScreenKeyboardConfig(p); } @@ -366,6 +396,7 @@ class Settings alert.show(); } + static void showScreenKeyboardConfig(final MainActivity p) { Globals.TouchscreenKeyboardSize = 0; @@ -463,11 +494,11 @@ class Settings nativeSetTrackballUsed(); if( Globals.AppUsesMouse ) nativeSetMouseUsed(); - if( Globals.AppUsesJoystick && !Globals.UseAccelerometerAsArrowKeys ) + if( Globals.AppUsesJoystick ) nativeSetJoystickUsed(); if( Globals.AppUsesMultitouch ) nativeSetMultitouchUsed(); - nativeSetAccelerometerSensitivity(Globals.AccelerometerSensitivity); + nativeSetAccelerometerSettings(Globals.AccelerometerSensitivity, Globals.AccelerometerCenterPos); nativeSetTrackballDampening(Globals.TrackballDampening); if( Globals.UseTouchscreenKeyboard ) { @@ -534,7 +565,7 @@ class Settings private static native void nativeIsSdcardUsed(int flag); private static native void nativeSetTrackballUsed(); private static native void nativeSetTrackballDampening(int value); - private static native void nativeSetAccelerometerSensitivity(int value); + private static native void nativeSetAccelerometerSettings(int sensitivity, int centerPos); private static native void nativeSetMouseUsed(); private static native void nativeSetJoystickUsed(); private static native void nativeSetMultitouchUsed(); diff --git a/project/src/Video.java b/project/src/Video.java index 29a2789bb..cf7463d6e 100644 --- a/project/src/Video.java +++ b/project/src/Video.java @@ -192,6 +192,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { System.loadLibrary("application"); System.loadLibrary("sdl_main"); Settings.Apply(context); + accelerometer = new AccelerometerReader(context); // Tweak video thread priority, if user selected big audio buffer if(Globals.AudioBufferConfig >= 2) Thread.currentThread().setPriority( (Thread.NORM_PRIORITY + Thread.MIN_PRIORITY) / 2 ); // Lower than normal @@ -225,6 +226,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { public native void nativeGlContextRecreated(); private Activity context = null; + private AccelerometerReader accelerometer = null; private EGL10 mEgl = null; private EGLDisplay mEglDisplay = null; @@ -242,7 +244,6 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL { mParent = context; touchInput = DifferentTouchInput.getInstance(); setEGLConfigChooser(Globals.NeedDepthBuffer); - accelerometer = new AccelerometerReader(context); mRenderer = new DemoRenderer(context); setRenderer(mRenderer); } @@ -292,7 +293,6 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL { DemoRenderer mRenderer; Activity mParent; - AccelerometerReader accelerometer = null; DifferentTouchInput touchInput = null; public static native void nativeMouse( int x, int y, int action, int pointerId, int pressure, int radius );