diff --git a/project/jni/application/openarena/engine b/project/jni/application/openarena/engine index 17010dd99..8ecd56f77 160000 --- a/project/jni/application/openarena/engine +++ b/project/jni/application/openarena/engine @@ -1 +1 @@ -Subproject commit 17010dd99f78801fc5028ca2d85023707f9c7463 +Subproject commit 8ecd56f77389ad637d1e1f1727a437f7826cefa3 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 new file mode 100644 index 000000000..ed70a91a7 --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput-queue-compat.c @@ -0,0 +1,587 @@ +/* + 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" + + +#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 + +enum { MAX_BUFFERED_EVENTS = 64 }; +static SDL_Event BufferedEvents[MAX_BUFFERED_EVENTS]; +static int BufferedEventsStart = 0, BufferedEventsEnd = 0; +static SDL_mutex * BufferedEventsMutex = NULL; + +/* We need our own event queue, because Free Heroes 2 game uses + * SDL_SetEventFilter(), and it calls SDL_Flip() from inside + * it's custom filter function, and SDL_Flip() does not work + * when it's not called from the main() thread. + * So we, like, push the events into our own queue, + * read each event from that queue inside SDL_ANDROID_PumpEvents(), + * unlock the mutex, and push the event to SDL queue, + * which is then immediately read by SDL from the same thread, + * and then SDL invokes event filter function from FHeroes2. + * FHeroes2 call SDL_Flip() from inside that event filter function, + * and it works, because it is called from the main() thread. + */ +extern void SDL_ANDROID_PumpEvents() +{ + static int oldMouseButtons = 0; + SDL_Event ev; + SDL_ANDROID_processAndroidTrackballDampening(); + SDL_ANDROID_processMoveMouseWithKeyboard(); +#if SDL_VERSION_ATLEAST(1,3,0) + SDL_Window * window = SDL_GetFocusWindow(); + if( !window ) + return; +#endif + + if( !BufferedEventsMutex ) + BufferedEventsMutex = SDL_CreateMutex(); + + SDL_mutexP(BufferedEventsMutex); + while( BufferedEventsStart != BufferedEventsEnd ) + { + ev = BufferedEvents[BufferedEventsStart]; + BufferedEvents[BufferedEventsStart].type = 0; + BufferedEventsStart++; + if( BufferedEventsStart >= MAX_BUFFERED_EVENTS ) + BufferedEventsStart = 0; + SDL_mutexV(BufferedEventsMutex); + + switch( ev.type ) + { + case SDL_MOUSEMOTION: + SDL_SendMouseMotion( ANDROID_CurrentWindow, 0, ev.motion.x, ev.motion.y ); + break; + case SDL_MOUSEBUTTONDOWN: + if( ((oldMouseButtons & SDL_BUTTON(ev.button.button)) != 0) != ev.button.state ) + { + oldMouseButtons = (oldMouseButtons & ~SDL_BUTTON(ev.button.button)) | (ev.button.state ? SDL_BUTTON(ev.button.button) : 0); + SDL_SendMouseButton( ANDROID_CurrentWindow, ev.button.state, ev.button.button ); + } + break; + case SDL_KEYDOWN: + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_KEYDOWN: %i %i", ev->key.keysym.sym, ev->key.state); + SDL_SendKeyboardKey( ev.key.state, &ev.key.keysym ); + break; + case SDL_JOYAXISMOTION: + if( ev.jaxis.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jaxis.which] ) + SDL_PrivateJoystickAxis( SDL_ANDROID_CurrentJoysticks[ev.jaxis.which], ev.jaxis.axis, ev.jaxis.value ); + break; + case SDL_JOYBUTTONDOWN: + if( ev.jbutton.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jbutton.which] ) + SDL_PrivateJoystickButton( SDL_ANDROID_CurrentJoysticks[ev.jbutton.which], ev.jbutton.button, ev.jbutton.state ); + break; + case SDL_JOYBALLMOTION: + if( ev.jball.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jbutton.which] ) + SDL_PrivateJoystickBall( SDL_ANDROID_CurrentJoysticks[ev.jball.which], ev.jball.ball, ev.jball.xrel, ev.jball.yrel ); + break; +#if SDL_VERSION_ATLEAST(1,3,0) + //if( ANDROID_CurrentWindow ) + // SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); +#else + case SDL_ACTIVEEVENT: + SDL_PrivateAppActive(ev.active.gain, ev.active.state); + break; +#endif +#if SDL_VERSION_ATLEAST(1,3,0) + case SDL_FINGERMOTION: + SDL_SendTouchMotion(0, ev.tfinger.fingerId, 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure); + break; + case SDL_FINGERDOWN: + SDL_SendFingerDown(0, ev.tfinger.fingerId, ev.tfinger.state ? 1 : 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure); + break; + case SDL_TEXTINPUT: + SDL_SendKeyboardText(ev.text.text); + break; + case SDL_MOUSEWHEEL: + SDL_SendMouseWheel( ANDROID_CurrentWindow, ev.wheel.x, ev.wheel.y ); + break; +#endif + } + + SDL_mutexP(BufferedEventsMutex); + } + SDL_mutexV(BufferedEventsMutex); +}; +// Queue events to main thread +static int getNextEventAndLock() +{ + int nextEvent; + if( !BufferedEventsMutex ) + return -1; + SDL_mutexP(BufferedEventsMutex); + nextEvent = BufferedEventsEnd; + nextEvent++; + if( nextEvent >= MAX_BUFFERED_EVENTS ) + nextEvent = 0; + while( nextEvent == BufferedEventsStart ) + { + SDL_mutexV(BufferedEventsMutex); + if( SDL_ANDROID_InsideVideoThread() ) + SDL_ANDROID_PumpEvents(); + else + SDL_Delay(100); + SDL_mutexP(BufferedEventsMutex); + nextEvent = BufferedEventsEnd; + nextEvent++; + if( nextEvent >= MAX_BUFFERED_EVENTS ) + nextEvent = 0; + } + return nextEvent; +} + +static int getPrevEventNoLock() +{ + int prevEvent; + if(BufferedEventsStart == BufferedEventsEnd) + return -1; + prevEvent = BufferedEventsEnd; + prevEvent--; + if( prevEvent < 0 ) + prevEvent = MAX_BUFFERED_EVENTS - 1; + return prevEvent; +} + +extern void SDL_ANDROID_MainThreadPushMouseMotion(int x, int y) +{ + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + int prevEvent = getPrevEventNoLock(); + if( prevEvent > 0 && BufferedEvents[prevEvent].type == SDL_MOUSEMOTION ) + { + // Reuse previous mouse motion event, to prevent mouse movement lag + BufferedEvents[prevEvent].motion.x = x; + BufferedEvents[prevEvent].motion.y = y; + } + else + { + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + ev->type = SDL_MOUSEMOTION; + ev->motion.x = x; + ev->motion.y = y; + } + SDL_ANDROID_currentMouseX = x; + SDL_ANDROID_currentMouseY = y; + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +}; +extern void SDL_ANDROID_MainThreadPushMouseButton(int pressed, int button) +{ + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + ev->type = SDL_MOUSEBUTTONDOWN; + ev->button.state = pressed; + ev->button.button = button; + + if(pressed) + SDL_ANDROID_currentMouseButtons |= SDL_BUTTON(button); + else + SDL_ANDROID_currentMouseButtons &= ~(SDL_BUTTON(button)); + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +}; + +extern void SDL_ANDROID_MainThreadPushKeyboardKey(int pressed, SDL_scancode key) +{ + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + 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_mutexV(BufferedEventsMutex); + + SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY); + return; + } + + ev->type = SDL_KEYDOWN; + ev->key.state = pressed; + ev->key.keysym.scancode = key; + ev->key.keysym.sym = key; + ev->key.keysym.mod = KMOD_NONE; + ev->key.keysym.unicode = 0; +#if SDL_VERSION_ATLEAST(1,3,0) +#else + if ( SDL_TranslateUNICODE ) +#endif + ev->key.keysym.unicode = key; + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +}; + +extern void SDL_ANDROID_MainThreadPushJoystickAxis(int joy, int axis, int value) +{ + if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) + return; + + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + ev->type = SDL_JOYAXISMOTION; + ev->jaxis.which = joy; + ev->jaxis.axis = axis; + ev->jaxis.value = MAX( -32768, MIN( 32767, value ) ); + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +}; +extern void SDL_ANDROID_MainThreadPushJoystickButton(int joy, int button, int pressed) +{ + if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) + return; + + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + ev->type = SDL_JOYBUTTONDOWN; + ev->jbutton.which = joy; + ev->jbutton.button = button; + ev->jbutton.state = pressed; + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +}; +extern void SDL_ANDROID_MainThreadPushJoystickBall(int joy, int ball, int x, int y) +{ + if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) + return; + + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + ev->type = SDL_JOYBALLMOTION; + ev->jball.which = joy; + ev->jball.ball = ball; + ev->jball.xrel = x; + ev->jball.yrel = y; + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +} +extern void SDL_ANDROID_MainThreadPushMultitouchButton(int id, int pressed, int x, int y, int force) +{ +#if SDL_VERSION_ATLEAST(1,3,0) + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + ev->type = SDL_FINGERDOWN; + ev->tfinger.fingerId = id; + ev->tfinger.state = pressed; + ev->tfinger.x = x; + ev->tfinger.y = y; + ev->tfinger.pressure = force; + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +#endif +}; +extern void SDL_ANDROID_MainThreadPushMultitouchMotion(int id, int x, int y, int force) +{ +#if SDL_VERSION_ATLEAST(1,3,0) + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + ev->type = SDL_FINGERMOTION; + ev->tfinger.fingerId = id; + ev->tfinger.x = x; + ev->tfinger.y = y; + ev->tfinger.pressure = force; + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +#endif +}; + +extern void SDL_ANDROID_MainThreadPushMouseWheel(int x, int y) +{ +#if SDL_VERSION_ATLEAST(1,3,0) + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + ev->type = SDL_MOUSEWHEEL; + ev->wheel.x = x; + ev->wheel.y = y; + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +#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 + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + ev->type = SDL_ACTIVEEVENT; + ev->active.gain = active; + ev->active.state = SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS; + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +#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 ) + { + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + { + SDL_mutexV(deferredTextMutex); + return; + } + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + + deferredTextIdx1++; + if( deferredTextIdx1 >= DEFERRED_TEXT_COUNT ) + deferredTextIdx1 = 0; + + ev->type = SDL_KEYDOWN; + ev->key.state = deferredText[deferredTextIdx1].down; + ev->key.keysym = asciiToKeysym( deferredText[deferredTextIdx1].scancode, deferredText[deferredTextIdx1].unicode ); + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); + 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; + + int nextEvent = getNextEventAndLock(); + if( nextEvent == -1 ) + return; + + SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; + +#if SDL_VERSION_ATLEAST(1,3,0) + + ev->type = SDL_TEXTINPUT; + UnicodeToUtf8(unicode, ev->text.text); + +#endif + + if( !deferredTextMutex ) + deferredTextMutex = SDL_CreateMutex(); + + SDL_mutexP(deferredTextMutex); + + ev->type = 0; + + 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); + + BufferedEventsEnd = nextEvent; + SDL_mutexV(BufferedEventsMutex); +}; + diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c index c0a98cfb9..fcc42842e 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c @@ -42,12 +42,10 @@ #include "SDL_androidinput.h" #include "SDL_screenkeyboard.h" #include "jniwrapperstuff.h" +#include "unicodestuff.h" #include "atan2i.h" -#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) -#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) - -static SDLKey SDL_android_keymap[KEYCODE_LAST+1]; +SDLKey SDL_android_keymap[KEYCODE_LAST+1]; static inline SDL_scancode TranslateKey(int scancode) { @@ -57,7 +55,7 @@ static inline SDL_scancode TranslateKey(int scancode) } static int isTrackballUsed = 0; -static int isMouseUsed = 0; +int SDL_ANDROID_isMouseUsed = 0; #define NORMALIZE_FLOAT_32767(X) (fminf(32767.0f, fmax(-32767.0f, (X) * 32767.0f))) @@ -72,20 +70,20 @@ static int leftClickKey = KEYCODE_DPAD_CENTER; static int rightClickKey = KEYCODE_MENU; int SDL_ANDROID_ShowScreenUnderFinger = ZOOM_NONE; SDL_Rect SDL_ANDROID_ShowScreenUnderFingerRect = {0, 0, 0, 0}, SDL_ANDROID_ShowScreenUnderFingerRectSrc = {0, 0, 0, 0}; -static int moveMouseWithArrowKeys = 0; static int clickMouseWithDpadCenter = 0; -static int moveMouseWithKbSpeed = 0; -static int moveMouseWithKbAccel = 0; -static int moveMouseWithKbX = -1, moveMouseWithKbY = -1; -static int moveMouseWithKbSpeedX = 0, moveMouseWithKbSpeedY = 0; -static int moveMouseWithKbAccelX = 0, moveMouseWithKbAccelY = 0; -static int moveMouseWithKbAccelUpdateNeeded = 0; +int SDL_ANDROID_moveMouseWithArrowKeys = 0; +int SDL_ANDROID_moveMouseWithKbSpeed = 0; +int SDL_ANDROID_moveMouseWithKbAccel = 0; +int SDL_ANDROID_moveMouseWithKbX = -1, SDL_ANDROID_moveMouseWithKbY = -1; +int SDL_ANDROID_moveMouseWithKbSpeedX = 0, SDL_ANDROID_moveMouseWithKbSpeedY = 0; +int SDL_ANDROID_moveMouseWithKbAccelX = 0, SDL_ANDROID_moveMouseWithKbAccelY = 0; +int SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded = 0; static int maxForce = 0; static int maxRadius = 0; int SDL_ANDROID_isJoystickUsed = 0; static int SDL_ANDROID_isAccelerometerUsed = 0; static int isMultitouchUsed = 0; -SDL_Joystick *SDL_ANDROID_CurrentJoysticks[MAX_MULTITOUCH_POINTERS+1] = {NULL}; +SDL_Joystick *SDL_ANDROID_CurrentJoysticks[MAX_MULTITOUCH_POINTERS+1]; static int TrackballDampening = 0; // in milliseconds static Uint32 lastTrackballAction = 0; enum { TOUCH_PTR_UP = 0, TOUCH_PTR_MOUSE = 1, TOUCH_PTR_SCREENKB = 2 }; @@ -120,45 +118,13 @@ static int relativeMovementAccel = 0; static int relativeMovementX = 0; static int relativeMovementY = 0; static unsigned int relativeMovementTime = 0; -static int currentMouseX = 0; -static int currentMouseY = 0; -static int currentMouseButtons = 0; +int SDL_ANDROID_currentMouseX = 0; +int SDL_ANDROID_currentMouseY = 0; +int SDL_ANDROID_currentMouseButtons = 0; static int hardwareMouseDetected = 0; enum { MOUSE_HW_BUTTON_LEFT = 1, MOUSE_HW_BUTTON_RIGHT = 2, MOUSE_HW_BUTTON_MIDDLE = 4, MOUSE_HW_BUTTON_BACK = 8, MOUSE_HW_BUTTON_FORWARD = 16, MOUSE_HW_BUTTON_MAX = MOUSE_HW_BUTTON_FORWARD }; -static int UnicodeToUtf8(int src, char * dest) -{ - int len = 0; - if ( src <= 0x007f) { - *dest++ = (char)src; - len = 1; - } else if (src <= 0x07ff) { - *dest++ = (char)0xc0 | (src >> 6); - *dest++ = (char)0x80 | (src & 0x003f); - len = 2; - } else if (src == 0xFEFF) { - // nop -- zap the BOM - } else if (src >= 0xD800 && src <= 0xDFFF) { - // surrogates not supported - } else if (src <= 0xffff) { - *dest++ = (char)0xe0 | (src >> 12); - *dest++ = (char)0x80 | ((src >> 6) & 0x003f); - *dest++ = (char)0x80 | (src & 0x003f); - len = 3; - } else if (src <= 0xffff) { - *dest++ = (char)0xf0 | (src >> 18); - *dest++ = (char)0x80 | ((src >> 12) & 0x3f); - *dest++ = (char)0x80 | ((src >> 6) & 0x3f); - *dest++ = (char)0x80 | (src & 0x3f); - len = 4; - } else { - // out of Unicode range - } - *dest = 0; - return len; -} - static inline int InsideRect(const SDL_Rect * r, int x, int y) { return ( x >= r->x && x <= r->x + r->w ) && ( y >= r->y && y <= r->y + r->h ); @@ -397,7 +363,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t if( multitouchGestureDist - dist > distMaxDiff ) { multitouchGestureKeyPressed[1] = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[1] ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[1] ); } else if( multitouchGestureKeyPressed[1] ) @@ -456,7 +422,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t if( action == MOUSE_UP ) SDL_ANDROID_MainThreadPushJoystickButton(JOY_TOUCHSCREEN, pointerId, SDL_RELEASED); } - if( !isMouseUsed && !SDL_ANDROID_isTouchscreenKeyboardUsed ) + if( !SDL_ANDROID_isMouseUsed && !SDL_ANDROID_isTouchscreenKeyboardUsed ) { SDL_keysym keysym; if( action != MOUSE_MOVE ) @@ -464,7 +430,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t return; } - if( !isMouseUsed ) + if( !SDL_ANDROID_isMouseUsed ) return; if( pointerId == firstMousePointerId ) @@ -473,14 +439,14 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t { if( action == MOUSE_DOWN ) { - relativeMovementX = currentMouseX - x; - relativeMovementY = currentMouseY - y; + relativeMovementX = SDL_ANDROID_currentMouseX - x; + relativeMovementY = SDL_ANDROID_currentMouseY - y; } x += relativeMovementX; y += relativeMovementY; - int diffX = x - currentMouseX; - int diffY = y - currentMouseY; + int diffX = x - SDL_ANDROID_currentMouseX; + int diffY = y - SDL_ANDROID_currentMouseY; int coeff = relativeMovementSpeed + 2; if( relativeMovementSpeed > 2 ) coeff += relativeMovementSpeed - 2; @@ -496,8 +462,8 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t } relativeMovementTime = newTime; } - diffX -= x - currentMouseX; - diffY -= y - currentMouseY; + diffX -= x - SDL_ANDROID_currentMouseX; + diffY -= y - SDL_ANDROID_currentMouseY; x += diffX; y += diffY; relativeMovementX += diffX; @@ -544,33 +510,33 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER ) { // Move mouse by 1 pixel so it will force screen update and mouse-under-finger window will be removed - if( moveMouseWithKbX >= 0 ) - SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX > 0 ? moveMouseWithKbX-1 : 0, moveMouseWithKbY); + if( SDL_ANDROID_moveMouseWithKbX >= 0 ) + SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX > 0 ? SDL_ANDROID_moveMouseWithKbX-1 : 0, SDL_ANDROID_moveMouseWithKbY); else SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y); } - moveMouseWithKbX = -1; - moveMouseWithKbY = -1; - moveMouseWithKbSpeedX = 0; - moveMouseWithKbSpeedY = 0; + SDL_ANDROID_moveMouseWithKbX = -1; + SDL_ANDROID_moveMouseWithKbY = -1; + SDL_ANDROID_moveMouseWithKbSpeedX = 0; + SDL_ANDROID_moveMouseWithKbSpeedY = 0; } if( action == MOUSE_DOWN ) { - if( (moveMouseWithKbX >= 0 || leftClickMethod == LEFT_CLICK_NEAR_CURSOR) && - abs(currentMouseX - x) < SDL_ANDROID_sFakeWindowWidth / 10 && abs(currentMouseY - y) < SDL_ANDROID_sFakeWindowHeight / 10 ) + if( (SDL_ANDROID_moveMouseWithKbX >= 0 || leftClickMethod == LEFT_CLICK_NEAR_CURSOR) && + abs(SDL_ANDROID_currentMouseX - x) < SDL_ANDROID_sFakeWindowWidth / 10 && abs(SDL_ANDROID_currentMouseY - y) < SDL_ANDROID_sFakeWindowHeight / 10 ) { SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); - moveMouseWithKbX = currentMouseX; - moveMouseWithKbY = currentMouseY; - moveMouseWithKbSpeedX = 0; - moveMouseWithKbSpeedY = 0; + SDL_ANDROID_moveMouseWithKbX = SDL_ANDROID_currentMouseX; + SDL_ANDROID_moveMouseWithKbY = SDL_ANDROID_currentMouseY; + SDL_ANDROID_moveMouseWithKbSpeedX = 0; + SDL_ANDROID_moveMouseWithKbSpeedY = 0; action = MOUSE_MOVE; } else if( leftClickMethod == LEFT_CLICK_NORMAL ) { SDL_ANDROID_MainThreadPushMouseMotion(x, y); - if( !hardwareMouseDetected || currentMouseButtons == 0 ) + if( !hardwareMouseDetected || SDL_ANDROID_currentMouseButtons == 0 ) SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); } else @@ -585,7 +551,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t } if( action == MOUSE_MOVE ) { - if( moveMouseWithKbX >= 0 ) + if( SDL_ANDROID_moveMouseWithKbX >= 0 ) { // Mouse lazily follows magnifying glass, not very intuitive for drag&drop /* @@ -602,17 +568,17 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject t moveMouseWithKbY += moveMouseWithKbSpeedY; */ // Mouse follows touch instantly, when it's out of the snapping distance from mouse cursor - if( abs(moveMouseWithKbX - x) >= SDL_ANDROID_sFakeWindowWidth / 10 || - abs(moveMouseWithKbY - y) >= SDL_ANDROID_sFakeWindowHeight / 10 ) + if( abs(SDL_ANDROID_moveMouseWithKbX - x) >= SDL_ANDROID_sFakeWindowWidth / 10 || + abs(SDL_ANDROID_moveMouseWithKbY - y) >= SDL_ANDROID_sFakeWindowHeight / 10 ) { - moveMouseWithKbX = -1; - moveMouseWithKbY = -1; - moveMouseWithKbSpeedX = 0; - moveMouseWithKbSpeedY = 0; + SDL_ANDROID_moveMouseWithKbX = -1; + SDL_ANDROID_moveMouseWithKbY = -1; + SDL_ANDROID_moveMouseWithKbSpeedX = 0; + SDL_ANDROID_moveMouseWithKbSpeedY = 0; SDL_ANDROID_MainThreadPushMouseMotion(x, y); } else - SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); + SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY); } else { @@ -714,42 +680,42 @@ void ProcessDeferredMouseTap() #define SDL_ANDROID_sFakeWindowWidth window->w #define SDL_ANDROID_sFakeWindowHeight window->h #endif - if( currentMouseX + 1 < SDL_ANDROID_sFakeWindowWidth ) - SDL_ANDROID_MainThreadPushMouseMotion(currentMouseX + 1, currentMouseY); + if( SDL_ANDROID_currentMouseX + 1 < SDL_ANDROID_sFakeWindowWidth ) + SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_currentMouseX + 1, SDL_ANDROID_currentMouseY); SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT ); } - else if( currentMouseX > 0 ) // Force application to redraw, and call SDL_Flip() - SDL_ANDROID_MainThreadPushMouseMotion(currentMouseX - 1, currentMouseY); + else if( SDL_ANDROID_currentMouseX > 0 ) // Force application to redraw, and call SDL_Flip() + SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_currentMouseX - 1, SDL_ANDROID_currentMouseY); } } JNIEXPORT void JNICALL JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeTouchpad) ( JNIEnv* env, jobject thiz, jint x, jint y, jint down, jint multitouch) { - if( !isMouseUsed ) + if( !SDL_ANDROID_isMouseUsed ) return; if( ! down ) { SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_RIGHT ); SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT ); - moveMouseWithKbX = -1; - moveMouseWithKbY = -1; - moveMouseWithKbAccelUpdateNeeded = 0; + SDL_ANDROID_moveMouseWithKbX = -1; + SDL_ANDROID_moveMouseWithKbY = -1; + SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded = 0; } else { // x and y from 0 to 65535 - if( moveMouseWithKbX < 0 ) + if( SDL_ANDROID_moveMouseWithKbX < 0 ) { - moveMouseWithKbX = currentMouseX; - moveMouseWithKbY = currentMouseY; + SDL_ANDROID_moveMouseWithKbX = SDL_ANDROID_currentMouseX; + SDL_ANDROID_moveMouseWithKbY = SDL_ANDROID_currentMouseY; } - moveMouseWithKbSpeedX = (x - 32767) / 8192; - moveMouseWithKbSpeedY = (y - 32767) / 8192; + SDL_ANDROID_moveMouseWithKbSpeedX = (x - 32767) / 8192; + SDL_ANDROID_moveMouseWithKbSpeedY = (y - 32767) / 8192; //moveMouseWithKbX += moveMouseWithKbSpeedX; //moveMouseWithKbY += moveMouseWithKbSpeedY; - SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); - moveMouseWithKbAccelUpdateNeeded = 1; + SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY); + SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded = 1; if( multitouch ) SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_RIGHT ); @@ -767,9 +733,9 @@ void SDL_ANDROID_WarpMouse(int x, int y) } else { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_WarpMouse(): %dx%d rel %dx%d old %dx%d", x, y, relativeMovementX, relativeMovementY, currentMouseX, currentMouseY); - relativeMovementX -= currentMouseX-x; - relativeMovementY -= currentMouseY-y; + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_WarpMouse(): %dx%d rel %dx%d old %dx%d", x, y, relativeMovementX, relativeMovementY, SDL_ANDROID_currentMouseX, SDL_ANDROID_currentMouseY); + relativeMovementX -= SDL_ANDROID_currentMouseX-x; + relativeMovementY -= SDL_ANDROID_currentMouseY-y; SDL_ANDROID_MainThreadPushMouseMotion(x, y); } }; @@ -922,16 +888,16 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz, jint RelativeMovement, jint RelativeMovementSpeed, jint RelativeMovementAccel, jint ShowMouseCursor) { - isMouseUsed = 1; + SDL_ANDROID_isMouseUsed = 1; rightClickMethod = RightClickMethod; SDL_ANDROID_ShowScreenUnderFinger = ShowScreenUnderFinger; - moveMouseWithArrowKeys = MoveMouseWithJoystick; + SDL_ANDROID_moveMouseWithArrowKeys = MoveMouseWithJoystick; clickMouseWithDpadCenter = ClickMouseWithDpad; leftClickMethod = LeftClickMethod; maxForce = MaxForce; maxRadius = MaxRadius; - moveMouseWithKbSpeed = MoveMouseWithJoystickSpeed + 1; - moveMouseWithKbAccel = MoveMouseWithJoystickAccel; + SDL_ANDROID_moveMouseWithKbSpeed = MoveMouseWithJoystickSpeed + 1; + SDL_ANDROID_moveMouseWithKbAccel = MoveMouseWithJoystickAccel; leftClickKey = LeftClickKeycode; rightClickKey = RightClickKeycode; leftClickTimeout = getClickTimeout(LeftClickTimeout); @@ -946,7 +912,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz, JNIEXPORT void JNICALL JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected) { - if( !isMouseUsed ) + if( !SDL_ANDROID_isMouseUsed ) return; static struct { @@ -989,7 +955,7 @@ JNIEXPORT void JNICALL JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseButtonsPressed) (JNIEnv* env, jobject thiz, jint buttonId, jint pressedState) { int btn = SDL_BUTTON_LEFT; - if( !isMouseUsed ) + if( !SDL_ANDROID_isMouseUsed ) return; switch(buttonId) @@ -1032,7 +998,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseWheel) (JNIEnv* env, jobject thiz, } for( ; scrollY > 0; scrollY-- ) { - if(!isMouseUsed) + if(!SDL_ANDROID_isMouseUsed) { SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_UP) ); SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) ); @@ -1045,7 +1011,7 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseWheel) (JNIEnv* env, jobject thiz, } for( ; scrollY < 0; scrollY++ ) { - if(!isMouseUsed) + if(!SDL_ANDROID_isMouseUsed) { SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_DOWN) ); SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) ); @@ -1484,601 +1450,11 @@ void SDL_SYS_JoystickQuit(void) return; } - -enum { MAX_BUFFERED_EVENTS = 64 }; -static SDL_Event BufferedEvents[MAX_BUFFERED_EVENTS]; -static int BufferedEventsStart = 0, BufferedEventsEnd = 0; -static SDL_mutex * BufferedEventsMutex = NULL; - -#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 - -/* We need our own event queue, because Free Heroes 2 game uses - * SDL_SetEventFilter(), and it calls SDL_Flip() from inside - * it's custom filter function, and SDL_Flip() does not work - * when it's not called from the main() thread. - * So we, like, push the events into our own queue, - * read each event from that queue inside SDL_ANDROID_PumpEvents(), - * unlock the mutex, and push the event to SDL queue, - * which is then immediately read by SDL from the same thread, - * and then SDL invokes event filter function from FHeroes2. - * FHeroes2 call SDL_Flip() from inside that event filter function, - * and it works, because it is called from the main() thread. - */ -extern void SDL_ANDROID_PumpEvents() -{ - static int oldMouseButtons = 0; - SDL_Event ev; - SDL_ANDROID_processAndroidTrackballDampening(); - SDL_ANDROID_processMoveMouseWithKeyboard(); -#if SDL_VERSION_ATLEAST(1,3,0) - SDL_Window * window = SDL_GetFocusWindow(); - if( !window ) - return; -#endif - - if( !BufferedEventsMutex ) - BufferedEventsMutex = SDL_CreateMutex(); - - SDL_mutexP(BufferedEventsMutex); - while( BufferedEventsStart != BufferedEventsEnd ) - { - ev = BufferedEvents[BufferedEventsStart]; - BufferedEvents[BufferedEventsStart].type = 0; - BufferedEventsStart++; - if( BufferedEventsStart >= MAX_BUFFERED_EVENTS ) - BufferedEventsStart = 0; - SDL_mutexV(BufferedEventsMutex); - - switch( ev.type ) - { - case SDL_MOUSEMOTION: - SDL_SendMouseMotion( ANDROID_CurrentWindow, 0, ev.motion.x, ev.motion.y ); - break; - case SDL_MOUSEBUTTONDOWN: - if( ((oldMouseButtons & SDL_BUTTON(ev.button.button)) != 0) != ev.button.state ) - { - oldMouseButtons = (oldMouseButtons & ~SDL_BUTTON(ev.button.button)) | (ev.button.state ? SDL_BUTTON(ev.button.button) : 0); - SDL_SendMouseButton( ANDROID_CurrentWindow, ev.button.state, ev.button.button ); - } - break; - case SDL_KEYDOWN: - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_KEYDOWN: %i %i", ev->key.keysym.sym, ev->key.state); - SDL_SendKeyboardKey( ev.key.state, &ev.key.keysym ); - break; - case SDL_JOYAXISMOTION: - if( ev.jaxis.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jaxis.which] ) - SDL_PrivateJoystickAxis( SDL_ANDROID_CurrentJoysticks[ev.jaxis.which], ev.jaxis.axis, ev.jaxis.value ); - break; - case SDL_JOYBUTTONDOWN: - if( ev.jbutton.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jbutton.which] ) - SDL_PrivateJoystickButton( SDL_ANDROID_CurrentJoysticks[ev.jbutton.which], ev.jbutton.button, ev.jbutton.state ); - break; - case SDL_JOYBALLMOTION: - if( ev.jball.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jbutton.which] ) - SDL_PrivateJoystickBall( SDL_ANDROID_CurrentJoysticks[ev.jball.which], ev.jball.ball, ev.jball.xrel, ev.jball.yrel ); - break; -#if SDL_VERSION_ATLEAST(1,3,0) - //if( ANDROID_CurrentWindow ) - // SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0); -#else - case SDL_ACTIVEEVENT: - SDL_PrivateAppActive(ev.active.gain, ev.active.state); - break; -#endif -#if SDL_VERSION_ATLEAST(1,3,0) - case SDL_FINGERMOTION: - SDL_SendTouchMotion(0, ev.tfinger.fingerId, 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure); - break; - case SDL_FINGERDOWN: - SDL_SendFingerDown(0, ev.tfinger.fingerId, ev.tfinger.state ? 1 : 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure); - break; - case SDL_TEXTINPUT: - SDL_SendKeyboardText(ev.text.text); - break; - case SDL_MOUSEWHEEL: - SDL_SendMouseWheel( ANDROID_CurrentWindow, ev.wheel.x, ev.wheel.y ); - break; -#endif - } - - SDL_mutexP(BufferedEventsMutex); - } - SDL_mutexV(BufferedEventsMutex); -}; -// Queue events to main thread -static int getNextEventAndLock() -{ - int nextEvent; - if( !BufferedEventsMutex ) - return -1; - SDL_mutexP(BufferedEventsMutex); - nextEvent = BufferedEventsEnd; - nextEvent++; - if( nextEvent >= MAX_BUFFERED_EVENTS ) - nextEvent = 0; - while( nextEvent == BufferedEventsStart ) - { - SDL_mutexV(BufferedEventsMutex); - if( SDL_ANDROID_InsideVideoThread() ) - SDL_ANDROID_PumpEvents(); - else - SDL_Delay(100); - SDL_mutexP(BufferedEventsMutex); - nextEvent = BufferedEventsEnd; - nextEvent++; - if( nextEvent >= MAX_BUFFERED_EVENTS ) - nextEvent = 0; - } - return nextEvent; -} - -static int getPrevEventNoLock() -{ - int prevEvent; - if(BufferedEventsStart == BufferedEventsEnd) - return -1; - prevEvent = BufferedEventsEnd; - prevEvent--; - if( prevEvent < 0 ) - prevEvent = MAX_BUFFERED_EVENTS - 1; - return prevEvent; -} - -extern void SDL_ANDROID_MainThreadPushMouseMotion(int x, int y) -{ - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - int prevEvent = getPrevEventNoLock(); - if( prevEvent > 0 && BufferedEvents[prevEvent].type == SDL_MOUSEMOTION ) - { - // Reuse previous mouse motion event, to prevent mouse movement lag - BufferedEvents[prevEvent].motion.x = x; - BufferedEvents[prevEvent].motion.y = y; - } - else - { - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - ev->type = SDL_MOUSEMOTION; - ev->motion.x = x; - ev->motion.y = y; - } - currentMouseX = x; - currentMouseY = y; - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -}; -extern void SDL_ANDROID_MainThreadPushMouseButton(int pressed, int button) -{ - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - ev->type = SDL_MOUSEBUTTONDOWN; - ev->button.state = pressed; - ev->button.button = button; - - if(pressed) - currentMouseButtons |= SDL_BUTTON(button); - else - currentMouseButtons &= ~(SDL_BUTTON(button)); - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -}; - -extern void SDL_ANDROID_MainThreadPushKeyboardKey(int pressed, SDL_scancode key) -{ - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - if( moveMouseWithArrowKeys && ( - key == SDL_KEY(UP) || key == SDL_KEY(DOWN) || - key == SDL_KEY(LEFT) || key == SDL_KEY(RIGHT) ) ) - { - if( moveMouseWithKbX < 0 ) - { - moveMouseWithKbX = currentMouseX; - moveMouseWithKbY = currentMouseY; - } - - if( pressed ) - { - if( key == SDL_KEY(LEFT) ) - { - if( moveMouseWithKbSpeedX > 0 ) - moveMouseWithKbSpeedX = 0; - moveMouseWithKbSpeedX -= moveMouseWithKbSpeed; - moveMouseWithKbAccelX = -moveMouseWithKbAccel; - moveMouseWithKbAccelUpdateNeeded |= 1; - } - else if( key == SDL_KEY(RIGHT) ) - { - if( moveMouseWithKbSpeedX < 0 ) - moveMouseWithKbSpeedX = 0; - moveMouseWithKbSpeedX += moveMouseWithKbSpeed; - moveMouseWithKbAccelX = moveMouseWithKbAccel; - moveMouseWithKbAccelUpdateNeeded |= 1; - } - - if( key == SDL_KEY(UP) ) - { - if( moveMouseWithKbSpeedY > 0 ) - moveMouseWithKbSpeedY = 0; - moveMouseWithKbSpeedY -= moveMouseWithKbSpeed; - moveMouseWithKbAccelY = -moveMouseWithKbAccel; - moveMouseWithKbAccelUpdateNeeded |= 2; - } - else if( key == SDL_KEY(DOWN) ) - { - if( moveMouseWithKbSpeedY < 0 ) - moveMouseWithKbSpeedY = 0; - moveMouseWithKbSpeedY += moveMouseWithKbSpeed; - moveMouseWithKbAccelY = moveMouseWithKbAccel; - moveMouseWithKbAccelUpdateNeeded |= 2; - } - } - else - { - if( key == SDL_KEY(LEFT) || key == SDL_KEY(RIGHT) ) - { - moveMouseWithKbSpeedX = 0; - moveMouseWithKbAccelX = 0; - moveMouseWithKbAccelUpdateNeeded &= ~1; - } - if( key == SDL_KEY(UP) || key == SDL_KEY(DOWN) ) - { - moveMouseWithKbSpeedY = 0; - moveMouseWithKbAccelY = 0; - moveMouseWithKbAccelUpdateNeeded &= ~2; - } - } - - moveMouseWithKbX += moveMouseWithKbSpeedX; - moveMouseWithKbY += moveMouseWithKbSpeedY; - - SDL_mutexV(BufferedEventsMutex); - - SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); - return; - } - - ev->type = SDL_KEYDOWN; - ev->key.state = pressed; - ev->key.keysym.scancode = key; - ev->key.keysym.sym = key; - ev->key.keysym.mod = KMOD_NONE; - ev->key.keysym.unicode = 0; -#if SDL_VERSION_ATLEAST(1,3,0) -#else - if ( SDL_TranslateUNICODE ) -#endif - ev->key.keysym.unicode = key; - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -}; - -extern void SDL_ANDROID_MainThreadPushJoystickAxis(int joy, int axis, int value) -{ - if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) - return; - - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - ev->type = SDL_JOYAXISMOTION; - ev->jaxis.which = joy; - ev->jaxis.axis = axis; - ev->jaxis.value = MAX( -32768, MIN( 32767, value ) ); - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -}; -extern void SDL_ANDROID_MainThreadPushJoystickButton(int joy, int button, int pressed) -{ - if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) - return; - - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - ev->type = SDL_JOYBUTTONDOWN; - ev->jbutton.which = joy; - ev->jbutton.button = button; - ev->jbutton.state = pressed; - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -}; -extern void SDL_ANDROID_MainThreadPushJoystickBall(int joy, int ball, int x, int y) -{ - if( ! ( joy < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[joy] ) ) - return; - - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - ev->type = SDL_JOYBALLMOTION; - ev->jball.which = joy; - ev->jball.ball = ball; - ev->jball.xrel = x; - ev->jball.yrel = y; - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -} -extern void SDL_ANDROID_MainThreadPushMultitouchButton(int id, int pressed, int x, int y, int force) -{ -#if SDL_VERSION_ATLEAST(1,3,0) - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - ev->type = SDL_FINGERDOWN; - ev->tfinger.fingerId = id; - ev->tfinger.state = pressed; - ev->tfinger.x = x; - ev->tfinger.y = y; - ev->tfinger.pressure = force; - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -#endif -}; -extern void SDL_ANDROID_MainThreadPushMultitouchMotion(int id, int x, int y, int force) -{ -#if SDL_VERSION_ATLEAST(1,3,0) - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - ev->type = SDL_FINGERMOTION; - ev->tfinger.fingerId = id; - ev->tfinger.x = x; - ev->tfinger.y = y; - ev->tfinger.pressure = force; - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -#endif -}; - -extern void SDL_ANDROID_MainThreadPushMouseWheel(int x, int y) -{ -#if SDL_VERSION_ATLEAST(1,3,0) - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - ev->type = SDL_MOUSEWHEEL; - ev->wheel.x = x; - ev->wheel.y = y; - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -#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 - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - ev->type = SDL_ACTIVEEVENT; - ev->active.gain = active; - ev->active.state = SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS; - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -#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; - -static SDL_keysym asciiToKeysym(int ascii, int unicode) -{ - SDL_keysym keysym; - keysym.scancode = ascii; - keysym.sym = ascii; - keysym.mod = KMOD_NONE; - keysym.unicode = 0; -#if SDL_VERSION_ATLEAST(1,3,0) - keysym.sym = SDL_GetScancodeFromKey(ascii); -#else - if ( SDL_TranslateUNICODE ) -#endif - keysym.unicode = unicode; - return keysym; -} - -static int checkShiftRequired( int * sym ) -{ - switch( *sym ) - { - case '!': *sym = '1'; return 1; - case '@': *sym = '2'; return 1; - case '#': *sym = '3'; return 1; - case '$': *sym = '4'; return 1; - case '%': *sym = '5'; return 1; - case '^': *sym = '6'; return 1; - case '&': *sym = '7'; return 1; - case '*': *sym = '8'; return 1; - case '(': *sym = '9'; return 1; - case ')': *sym = '0'; return 1; - case '_': *sym = '-'; return 1; - case '+': *sym = '='; return 1; - case '|': *sym = '\\';return 1; - case '<': *sym = ','; return 1; - case '>': *sym = '.'; return 1; - case '?': *sym = '/'; return 1; - case ':': *sym = ';'; return 1; - case '"': *sym = '\'';return 1; - case '{': *sym = '['; return 1; - case '}': *sym = ']'; return 1; - case '~': *sym = '`'; return 1; - default: if( *sym >= 'A' && *sym <= 'Z' ) { *sym += 'a' - 'A'; return 1; }; - } - return 0; -} - -void SDL_ANDROID_DeferredTextInput() -{ - if( !deferredTextMutex ) - deferredTextMutex = SDL_CreateMutex(); - - SDL_mutexP(deferredTextMutex); - - if( deferredTextIdx1 != deferredTextIdx2 ) - { - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - { - SDL_mutexV(deferredTextMutex); - return; - } - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - - deferredTextIdx1++; - if( deferredTextIdx1 >= DEFERRED_TEXT_COUNT ) - deferredTextIdx1 = 0; - - ev->type = SDL_KEYDOWN; - ev->key.state = deferredText[deferredTextIdx1].down; - ev->key.keysym = asciiToKeysym( deferredText[deferredTextIdx1].scancode, deferredText[deferredTextIdx1].unicode ); - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); - if( isMouseUsed ) - SDL_ANDROID_MainThreadPushMouseMotion(currentMouseX + (currentMouseX % 2 ? -1 : 1), 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; - - int nextEvent = getNextEventAndLock(); - if( nextEvent == -1 ) - return; - - SDL_Event * ev = &BufferedEvents[BufferedEventsEnd]; - -#if SDL_VERSION_ATLEAST(1,3,0) - - ev->type = SDL_TEXTINPUT; - UnicodeToUtf8(unicode, ev->text.text); - -#endif - - if( !deferredTextMutex ) - deferredTextMutex = SDL_CreateMutex(); - - SDL_mutexP(deferredTextMutex); - - ev->type = 0; - - 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); - - BufferedEventsEnd = nextEvent; - SDL_mutexV(BufferedEventsMutex); -}; - - Uint32 lastMoveMouseWithKeyboardUpdate = 0; void SDL_ANDROID_processMoveMouseWithKeyboard() { - if( ! moveMouseWithKbAccelUpdateNeeded ) + if( ! SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded ) return; Uint32 ticks = SDL_GetTicks(); @@ -2088,12 +1464,12 @@ void SDL_ANDROID_processMoveMouseWithKeyboard() lastMoveMouseWithKeyboardUpdate = ticks; - moveMouseWithKbSpeedX += moveMouseWithKbAccelX; - moveMouseWithKbSpeedY += moveMouseWithKbAccelY; + SDL_ANDROID_moveMouseWithKbSpeedX += SDL_ANDROID_moveMouseWithKbAccelX; + SDL_ANDROID_moveMouseWithKbSpeedY += SDL_ANDROID_moveMouseWithKbAccelY; - moveMouseWithKbX += moveMouseWithKbSpeedX; - moveMouseWithKbY += moveMouseWithKbSpeedY; - SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); + SDL_ANDROID_moveMouseWithKbX += SDL_ANDROID_moveMouseWithKbSpeedX; + SDL_ANDROID_moveMouseWithKbY += SDL_ANDROID_moveMouseWithKbSpeedY; + SDL_ANDROID_MainThreadPushMouseMotion(SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY); }; extern void SDL_ANDROID_ProcessDeferredEvents() diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h index 59caac53a..a04f0399c 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h @@ -203,4 +203,18 @@ extern void SDL_ANDROID_MainThreadPushText( int ascii, int unicode ); extern void SDL_android_init_keymap(SDLKey *SDL_android_keymap); extern void SDL_ANDROID_MainThreadPushMouseWheel( int x, int y ); // SDL 1.3 only extern void SDL_ANDROID_MainThreadPushAppActive(int active); + +// Internal input queue stuff +extern SDLKey SDL_android_keymap[]; +extern SDL_Joystick *SDL_ANDROID_CurrentJoysticks[]; +extern int SDL_ANDROID_isMouseUsed; +extern int SDL_ANDROID_currentMouseX, SDL_ANDROID_currentMouseY, SDL_ANDROID_currentMouseButtons; +extern int SDL_ANDROID_moveMouseWithArrowKeys; +extern int SDL_ANDROID_moveMouseWithKbSpeed; +extern int SDL_ANDROID_moveMouseWithKbAccel; +extern int SDL_ANDROID_moveMouseWithKbX, SDL_ANDROID_moveMouseWithKbY; +extern int SDL_ANDROID_moveMouseWithKbSpeedX, SDL_ANDROID_moveMouseWithKbSpeedY; +extern int SDL_ANDROID_moveMouseWithKbAccelX, SDL_ANDROID_moveMouseWithKbAccelY; +extern int SDL_ANDROID_moveMouseWithKbAccelUpdateNeeded; + #endif diff --git a/project/jni/sdl-1.2/src/video/android/atan2i.h b/project/jni/sdl-1.2/src/video/android/atan2i.h index e7111a618..59efd9d72 100644 --- a/project/jni/sdl-1.2/src/video/android/atan2i.h +++ b/project/jni/sdl-1.2/src/video/android/atan2i.h @@ -30,4 +30,7 @@ static inline int atan2i(int y, int x) return(angle); }; +#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) +#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) + #endif