diff --git a/changeAppSettings.sh b/changeAppSettings.sh index e20904d5f..34b71f878 100755 --- a/changeAppSettings.sh +++ b/changeAppSettings.sh @@ -182,6 +182,17 @@ if [ -n "$var" ] ; then fi fi +if [ -z "$CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState" -o -z "$AUTO" ]; then +echo +echo "Touchscreen keyboard will save and restore OpenGL state before drawing itself -" +echo -n "this works reliably only on Android 4.X devices, many Andorid 2.X devices do not support glGet() (y)/(n) ($CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState): " +read var +if [ -n "$var" ] ; then + CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState="$var" + CHANGED=1 +fi +fi + fi if [ -z "$SdlVideoResize" -o -z "$AUTO" ]; then @@ -295,6 +306,17 @@ if [ -n "$var" ] ; then fi fi +if [ -z "$CompatibilityHacksSlowCompatibleEventQueue" -o -z "$AUTO" ]; then +echo +echo "Hack for Free Heroes 2, which redraws the screen inside SDL_PumpEvents(): slow and compatible SDL event queue -" +echo -n "do not use it with accelerometer/gyroscope, or your app may freeze at random (y)/(n) ($CompatibilityHacksSlowCompatibleEventQueue): " +read var +if [ -n "$var" ] ; then + CompatibilityHacksSlowCompatibleEventQueue="$var" + CHANGED=1 +fi +fi + if [ -z "$AppUsesJoystick" -o -z "$AUTO" ]; then echo echo "Application uses joystick (y) or (n), the on-screen DPAD will be used" @@ -673,6 +695,8 @@ echo CompatibilityHacksTextInputEmulatesHwKeyboard=$CompatibilityHacksTextInputE echo CompatibilityHacksPreventAudioChopping=$CompatibilityHacksPreventAudioChopping >> AndroidAppSettings.cfg echo CompatibilityHacksAppIgnoresAudioBufferSize=$CompatibilityHacksAppIgnoresAudioBufferSize >> AndroidAppSettings.cfg echo CompatibilityHacksAdditionalPreloadedSharedLibraries=\"$CompatibilityHacksAdditionalPreloadedSharedLibraries\" >> AndroidAppSettings.cfg +echo CompatibilityHacksSlowCompatibleEventQueue=$CompatibilityHacksSlowCompatibleEventQueue >> AndroidAppSettings.cfg +echo CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=$CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState >> AndroidAppSettings.cfg echo AppUsesMouse=$AppUsesMouse >> AndroidAppSettings.cfg echo AppNeedsTwoButtonMouse=$AppNeedsTwoButtonMouse >> AndroidAppSettings.cfg echo ShowMouseCursor=$ShowMouseCursor >> AndroidAppSettings.cfg @@ -803,6 +827,18 @@ else CompatibilityHacksAppIgnoresAudioBufferSize= fi +if [ "$CompatibilityHacksSlowCompatibleEventQueue" = "y" ]; then + CompatibilityHacksSlowCompatibleEventQueue=-DSDL_COMPATIBILITY_HACKS_SLOW_COMPATIBLE_EVENT_QUEUE=1 +else + CompatibilityHacksSlowCompatibleEventQueue= +fi + +if [ "$CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState" = "y" ]; then + CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=-DSDL_TOUCHSCREEN_KEYBOARD_SAVE_RESTORE_OPENGL_STATE=1 +else + CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState= +fi + if [ "$AppUsesMouse" = "y" ] ; then AppUsesMouse=true else @@ -1022,7 +1058,7 @@ cat project/jni/SettingsTemplate.mk | \ sed "s^APPLICATION_ADDITIONAL_CFLAGS :=.*^APPLICATION_ADDITIONAL_CFLAGS := $AppCflags^" | \ sed "s^APPLICATION_ADDITIONAL_LDFLAGS :=.*^APPLICATION_ADDITIONAL_LDFLAGS := $AppLdflags^" | \ sed "s^APPLICATION_OVERLAPS_SYSTEM_HEADERS :=.*^APPLICATION_OVERLAPS_SYSTEM_HEADERS := $AppOverlapsSystemHeaders^" | \ - sed "s^SDL_ADDITIONAL_CFLAGS :=.*^SDL_ADDITIONAL_CFLAGS := $RedefinedKeycodes $RedefinedKeycodesScreenKb $CompatibilityHacksPreventAudioChopping $CompatibilityHacksAppIgnoresAudioBufferSize^" | \ + sed "s^SDL_ADDITIONAL_CFLAGS :=.*^SDL_ADDITIONAL_CFLAGS := $RedefinedKeycodes $RedefinedKeycodesScreenKb $CompatibilityHacksPreventAudioChopping $CompatibilityHacksAppIgnoresAudioBufferSize $CompatibilityHacksSlowCompatibleEventQueue $CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState^" | \ sed "s^APPLICATION_SUBDIRS_BUILD :=.*^APPLICATION_SUBDIRS_BUILD := $AppSubdirsBuild^" | \ sed "s^APPLICATION_BUILD_EXCLUDE :=.*^APPLICATION_BUILD_EXCLUDE := $AppBuildExclude^" | \ sed "s^APPLICATION_CUSTOM_BUILD_SCRIPT :=.*^APPLICATION_CUSTOM_BUILD_SCRIPT := $CustomBuildScript^" | \ diff --git a/project/jni/application/openarena/AndroidAppSettings.cfg b/project/jni/application/openarena/AndroidAppSettings.cfg index a12dfef0c..90feaff5e 100644 --- a/project/jni/application/openarena/AndroidAppSettings.cfg +++ b/project/jni/application/openarena/AndroidAppSettings.cfg @@ -19,6 +19,8 @@ CompatibilityHacksTextInputEmulatesHwKeyboard=n CompatibilityHacksPreventAudioChopping=n CompatibilityHacksAppIgnoresAudioBufferSize=n CompatibilityHacksAdditionalPreloadedSharedLibraries="" +CompatibilityHacksSlowCompatibleEventQueue=n +CompatibilityHacksTouchscreenKeyboardSaveRestoreOpenGLState=n AppUsesMouse=n AppNeedsTwoButtonMouse=n ShowMouseCursor=n diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidinput-queue-compat.c b/project/jni/sdl-1.2/src/video/android/SDL_androidinput-queue-compat.c index ed70a91a7..3e7a9f3c5 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidinput-queue-compat.c +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput-queue-compat.c @@ -44,6 +44,10 @@ #include "atan2i.h" +#ifdef SDL_COMPATIBILITY_HACKS_SLOW_COMPATIBLE_EVENT_QUEUE + +// This code is left here to rot - it's bad, complicated and needed by only one applicaiton + #if SDL_VERSION_ATLEAST(1,3,0) #define SDL_SendKeyboardKey(state, keysym) SDL_SendKeyboardKey(state, (keysym)->sym) @@ -585,3 +589,4 @@ extern void SDL_ANDROID_MainThreadPushText( int ascii, int unicode ) SDL_mutexV(BufferedEventsMutex); }; +#endif diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidinput-queue-fast.c b/project/jni/sdl-1.2/src/video/android/SDL_androidinput-queue-fast.c new file mode 100644 index 000000000..4e80f5eee --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput-queue-fast.c @@ -0,0 +1,342 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2009 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include +#include +#include +#include +#include +#include +#include // for memset() + +#include "SDL_config.h" + +#include "SDL_version.h" +#include "SDL_mutex.h" +#include "SDL_events.h" +#if SDL_VERSION_ATLEAST(1,3,0) +#include "SDL_touch.h" +#include "../../events/SDL_touch_c.h" +#endif + +#include "../SDL_sysvideo.h" +#include "SDL_androidvideo.h" +#include "SDL_androidinput.h" +#include "unicodestuff.h" +#include "atan2i.h" + +#ifndef SDL_COMPATIBILITY_HACKS_SLOW_COMPATIBLE_EVENT_QUEUE + +#if SDL_VERSION_ATLEAST(1,3,0) + +#define SDL_SendKeyboardKey(state, keysym) SDL_SendKeyboardKey(state, (keysym)->sym) +extern SDL_Window * ANDROID_CurrentWindow; + +#else + +#define SDL_SendMouseMotion(A,B,X,Y) SDL_PrivateMouseMotion(0, 0, X, Y) +#define SDL_SendMouseButton(N, A, B) SDL_PrivateMouseButton( A, B, 0, 0 ) +#define SDL_SendKeyboardKey(state, keysym) SDL_PrivateKeyboard(state, keysym) + +#endif + +static volatile int joystickEventsCount; +static int oldMouseButtons = 0; + +extern void SDL_ANDROID_PumpEvents() +{ + joystickEventsCount = 0; + + SDL_ANDROID_processAndroidTrackballDampening(); + SDL_ANDROID_processMoveMouseWithKeyboard(); +}; + +extern void SDL_ANDROID_MainThreadPushMouseMotion(int x, int y) +{ + SDL_SendMouseMotion( ANDROID_CurrentWindow, 0, x, y ); + + SDL_ANDROID_currentMouseX = x; + SDL_ANDROID_currentMouseY = y; +} + +extern void SDL_ANDROID_MainThreadPushMouseButton(int pressed, int button) +{ + if( ((oldMouseButtons & SDL_BUTTON(button)) != 0) != pressed ) + { + oldMouseButtons = (oldMouseButtons & ~SDL_BUTTON(button)) | (pressed ? SDL_BUTTON(button) : 0); + SDL_SendMouseButton( ANDROID_CurrentWindow, pressed, button ); + } + + if(pressed) + SDL_ANDROID_currentMouseButtons |= SDL_BUTTON(button); + else + SDL_ANDROID_currentMouseButtons &= ~(SDL_BUTTON(button)); +} + +extern void SDL_ANDROID_MainThreadPushKeyboardKey(int pressed, SDL_scancode key) +{ + SDL_keysym keysym; + + if( SDL_ANDROID_moveMouseWithArrowKeys && ( + key == SDL_KEY(UP) || key == SDL_KEY(DOWN) || + key == SDL_KEY(LEFT) || key == SDL_KEY(RIGHT) ) ) + { + if( SDL_ANDROID_moveMouseWithKbX < 0 ) + { + SDL_ANDROID_moveMouseWithKbX = SDL_ANDROID_currentMouseX; + SDL_ANDROID_moveMouseWithKbY = SDL_ANDROID_currentMouseY; + } + + if( pressed ) + { + if( key == SDL_KEY(LEFT) ) + { + if( SDL_ANDROID_moveMouseWithKbSpeedX > 0 ) + SDL_ANDROID_moveMouseWithKbSpeedX = 0; + SDL_ANDROID_moveMouseWithKbSpeedX -= SDL_ANDROID_moveMouseWithKbSpeed; + SDL_ANDROID_moveMouseWithKbAccelX = -SDL_ANDROID_moveMouseWithKbAccel; + SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded |= 1; + } + else if( key == SDL_KEY(RIGHT) ) + { + if( SDL_ANDROID_moveMouseWithKbSpeedX < 0 ) + SDL_ANDROID_moveMouseWithKbSpeedX = 0; + SDL_ANDROID_moveMouseWithKbSpeedX += SDL_ANDROID_moveMouseWithKbSpeed; + SDL_ANDROID_moveMouseWithKbAccelX = SDL_ANDROID_moveMouseWithKbAccel; + SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded |= 1; + } + + if( key == SDL_KEY(UP) ) + { + if( SDL_ANDROID_moveMouseWithKbSpeedY > 0 ) + SDL_ANDROID_moveMouseWithKbSpeedY = 0; + SDL_ANDROID_moveMouseWithKbSpeedY -= SDL_ANDROID_moveMouseWithKbSpeed; + SDL_ANDROID_moveMouseWithKbAccelY = -SDL_ANDROID_moveMouseWithKbAccel; + SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded |= 2; + } + else if( key == SDL_KEY(DOWN) ) + { + if( SDL_ANDROID_moveMouseWithKbSpeedY < 0 ) + SDL_ANDROID_moveMouseWithKbSpeedY = 0; + SDL_ANDROID_moveMouseWithKbSpeedY += SDL_ANDROID_moveMouseWithKbSpeed; + SDL_ANDROID_moveMouseWithKbAccelY = SDL_ANDROID_moveMouseWithKbAccel; + SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded |= 2; + } + } + else + { + if( key == SDL_KEY(LEFT) || key == SDL_KEY(RIGHT) ) + { + SDL_ANDROID_moveMouseWithKbSpeedX = 0; + SDL_ANDROID_moveMouseWithKbAccelX = 0; + SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded &= ~1; + } + if( key == SDL_KEY(UP) || key == SDL_KEY(DOWN) ) + { + SDL_ANDROID_moveMouseWithKbSpeedY = 0; + SDL_ANDROID_moveMouseWithKbAccelY = 0; + SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded &= ~2; + } + } + + SDL_ANDROID_moveMouseWithKbX += SDL_ANDROID_moveMouseWithKbSpeedX; + SDL_ANDROID_moveMouseWithKbY += SDL_ANDROID_moveMouseWithKbSpeedY; + + SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY); + return; + } + + keysym.scancode = key; + keysym.sym = key; + keysym.mod = KMOD_NONE; + keysym.unicode = 0; +#if SDL_VERSION_ATLEAST(1,3,0) +#else + if ( SDL_TranslateUNICODE ) +#endif + keysym.unicode = key; + + if( pressed == SDL_RELEASED ) + keysym.unicode = 0; + + SDL_SendKeyboardKey( pressed, &keysym ); +} + +extern void SDL_ANDROID_MainThreadPushJoystickAxis(int joy, int axis, int value) +{ + if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) + return; + + if( joystickEventsCount > 64 ) + { + __android_log_print(ANDROID_LOG_INFO, "libSDL", "Too many joystick events in the queue - dropping some events"); + return; + } + + joystickEventsCount++; + + SDL_PrivateJoystickAxis( SDL_ANDROID_CurrentJoysticks[joy], axis, MAX( -32768, MIN( 32767, value ) ) ); +} + +extern void SDL_ANDROID_MainThreadPushJoystickButton(int joy, int button, int pressed) +{ + if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) + return; + + SDL_PrivateJoystickButton( SDL_ANDROID_CurrentJoysticks[joy], button, pressed ); +} + +extern void SDL_ANDROID_MainThreadPushJoystickBall(int joy, int ball, int x, int y) +{ + if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) + return; + + SDL_PrivateJoystickBall( SDL_ANDROID_CurrentJoysticks[joy], ball, x, y ); +} + +extern void SDL_ANDROID_MainThreadPushMultitouchButton(int id, int pressed, int x, int y, int force) +{ +#if SDL_VERSION_ATLEAST(1,3,0) + SDL_SendFingerDown(0, id, pressed ? 1 : 0, (float)x / (float)window->w, (float)y / (float)window->h, force); +#endif +} + +extern void SDL_ANDROID_MainThreadPushMultitouchMotion(int id, int x, int y, int force) +{ +#if SDL_VERSION_ATLEAST(1,3,0) + SDL_SendTouchMotion(0, id, 0, (float)x / (float)window->w, (float)y / (float)window->h, force); +#endif +} + +extern void SDL_ANDROID_MainThreadPushMouseWheel(int x, int y) +{ +#if SDL_VERSION_ATLEAST(1,3,0) + SDL_SendMouseWheel( ANDROID_CurrentWindow, x, y ); +#endif +} + +extern void SDL_ANDROID_MainThreadPushAppActive(int active) +{ +#if SDL_VERSION_ATLEAST(1,3,0) + //if( ANDROID_CurrentWindow ) + // SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); +#else + SDL_PrivateAppActive(active, SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); +#endif +} + +enum { DEFERRED_TEXT_COUNT = 256 }; +static struct { int scancode; int unicode; int down; } deferredText[DEFERRED_TEXT_COUNT]; +static int deferredTextIdx1 = 0; +static int deferredTextIdx2 = 0; +static SDL_mutex * deferredTextMutex = NULL; + +void SDL_ANDROID_DeferredTextInput() +{ + if( !deferredTextMutex ) + deferredTextMutex = SDL_CreateMutex(); + + SDL_mutexP(deferredTextMutex); + + if( deferredTextIdx1 != deferredTextIdx2 ) + { + SDL_keysym keysym; + + deferredTextIdx1++; + if( deferredTextIdx1 >= DEFERRED_TEXT_COUNT ) + deferredTextIdx1 = 0; + + keysym = asciiToKeysym( deferredText[deferredTextIdx1].scancode, deferredText[deferredTextIdx1].unicode ); + if( deferredText[deferredTextIdx1].down == SDL_RELEASED ) + keysym.unicode = 0; + + SDL_SendKeyboardKey( deferredText[deferredTextIdx1].down, &keysym ); + + if( SDL_ANDROID_isMouseUsed ) + SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_currentMouseX + (SDL_ANDROID_currentMouseX % 2 ? -1 : 1), SDL_ANDROID_currentMouseY); // Force screen redraw + } + else + { + if( SDL_ANDROID_TextInputFinished ) + { + SDL_ANDROID_TextInputFinished = 0; + SDL_ANDROID_IsScreenKeyboardShownFlag = 0; + } + } + + SDL_mutexV(deferredTextMutex); +} + +extern void SDL_ANDROID_MainThreadPushText( int ascii, int unicode ) +{ + int shiftRequired; + +#if SDL_VERSION_ATLEAST(1,3,0) + { + char text[32]; + UnicodeToUtf8(unicode, text); + SDL_SendKeyboardText(text); + } +#endif + + if( !deferredTextMutex ) + deferredTextMutex = SDL_CreateMutex(); + + SDL_mutexP(deferredTextMutex); + + shiftRequired = checkShiftRequired(&ascii); + + if( shiftRequired ) + { + deferredTextIdx2++; + if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT ) + deferredTextIdx2 = 0; + deferredText[deferredTextIdx2].down = SDL_PRESSED; + deferredText[deferredTextIdx2].scancode = SDLK_LSHIFT; + deferredText[deferredTextIdx2].unicode = 0; + } + deferredTextIdx2++; + if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT ) + deferredTextIdx2 = 0; + deferredText[deferredTextIdx2].down = SDL_PRESSED; + deferredText[deferredTextIdx2].scancode = ascii; + deferredText[deferredTextIdx2].unicode = unicode; + + deferredTextIdx2++; + if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT ) + deferredTextIdx2 = 0; + deferredText[deferredTextIdx2].down = SDL_RELEASED; + deferredText[deferredTextIdx2].scancode = ascii; + deferredText[deferredTextIdx2].unicode = 0; + if( shiftRequired ) + { + deferredTextIdx2++; + if( deferredTextIdx2 >= DEFERRED_TEXT_COUNT ) + deferredTextIdx2 = 0; + deferredText[deferredTextIdx2].down = SDL_RELEASED; + deferredText[deferredTextIdx2].scancode = SDLK_LSHIFT; + deferredText[deferredTextIdx2].unicode = 0; + } + + SDL_mutexV(deferredTextMutex); +} + +#endif diff --git a/todo.txt b/todo.txt index 4a8d602e1..274323d01 100644 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,6 @@ Requested features (see also bugs.txt) ====================================== -- Fast event queue and joystick event trottling in SDL - remove mutex from SDL_ANDROID_PumpEvents(), - and add another compatibility hack option, because queue got bloated and my phone rebooted. - -- Gyroscope calibration dialog. - - Option for default on-screen key theme in AndroidAppSettings.cfg. - Select between normal mouse input and magnifying glass/relative input automatically, based on screen size. @@ -25,3 +20,5 @@ Requested features (see also bugs.txt) - Support of libjnigraphics (it will disable on-screen keyboard, only SW SDL screen surface supported). This is not relevant already, as every device around is fast enough with GL. + +- Second joystick, to be used in TeeWorlds. \ No newline at end of file