From 8297a9ee26bb2b53ba7b52eb0c37ac445671128a Mon Sep 17 00:00:00 2001 From: pelya Date: Fri, 19 Oct 2012 19:59:33 +0300 Subject: [PATCH] Moved some files around between SDL 1.2 and 1.3 --- .../teeworlds/AndroidAppSettings.cfg | 6 +- .../src/audio/android/SDL_androidaudio.c | 350 ++- .../src/audio/android/SDL_androidaudio.h | 33 +- .../src/video/android/SDL_androidinput.c | 2184 ++++++++++++++++- .../src/video/android/SDL_androidinput.h | 207 +- .../src/video/android/SDL_androidvideo.c | 403 ++- .../src/video/android/SDL_androidvideo.h | 87 +- .../video/android/SDL_touchscreenkeyboard.c | 1065 +++++++- .../jni/sdl-1.2/src/video/android/atan2i.h | 34 +- .../sdl-1.2/src/video/android/javakeycodes.h | 216 +- .../src/video/android/jniwrapperstuff.h | 14 +- .../jni/sdl-1.2/src/video/android/keymap.c | 243 +- .../src/video/android/touchscreenfont.h | 1 - .../src/audio/android/SDL_androidaudio.c | 350 +-- .../src/audio/android/SDL_androidaudio.h | 33 +- .../src/video/android/SDL_androidinput.c | 2184 +---------------- .../src/video/android/SDL_androidinput.h | 207 +- .../src/video/android/SDL_androidvideo.c | 403 +-- .../src/video/android/SDL_androidvideo.h | 87 +- .../video/android/SDL_touchscreenkeyboard.c | 1065 +------- .../jni/sdl-1.3/src/video/android/atan2i.h | 34 +- .../sdl-1.3/src/video/android/javakeycodes.h | 216 +- .../src/video/android/jniwrapperstuff.h | 14 +- .../jni/sdl-1.3/src/video/android/keymap.c | 243 +- .../src/video/android/touchscreenfont.h | 1 - 25 files changed, 4839 insertions(+), 4841 deletions(-) mode change 120000 => 100644 project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.c mode change 120000 => 100644 project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.h mode change 120000 => 100644 project/jni/sdl-1.2/src/video/android/SDL_androidinput.c mode change 120000 => 100644 project/jni/sdl-1.2/src/video/android/SDL_androidinput.h mode change 120000 => 100644 project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c mode change 120000 => 100644 project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h mode change 120000 => 100644 project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c mode change 120000 => 100644 project/jni/sdl-1.2/src/video/android/atan2i.h mode change 120000 => 100644 project/jni/sdl-1.2/src/video/android/javakeycodes.h mode change 120000 => 100644 project/jni/sdl-1.2/src/video/android/jniwrapperstuff.h mode change 120000 => 100644 project/jni/sdl-1.2/src/video/android/keymap.c delete mode 120000 project/jni/sdl-1.2/src/video/android/touchscreenfont.h mode change 100644 => 120000 project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.c mode change 100644 => 120000 project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.h mode change 100644 => 120000 project/jni/sdl-1.3/src/video/android/SDL_androidinput.c mode change 100644 => 120000 project/jni/sdl-1.3/src/video/android/SDL_androidinput.h mode change 100644 => 120000 project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c mode change 100644 => 120000 project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h mode change 100644 => 120000 project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c mode change 100644 => 120000 project/jni/sdl-1.3/src/video/android/atan2i.h mode change 100644 => 120000 project/jni/sdl-1.3/src/video/android/javakeycodes.h mode change 100644 => 120000 project/jni/sdl-1.3/src/video/android/jniwrapperstuff.h mode change 100644 => 120000 project/jni/sdl-1.3/src/video/android/keymap.c delete mode 120000 project/jni/sdl-1.3/src/video/android/touchscreenfont.h diff --git a/project/jni/application/teeworlds/AndroidAppSettings.cfg b/project/jni/application/teeworlds/AndroidAppSettings.cfg index 8df161745..d65bd2bb2 100644 --- a/project/jni/application/teeworlds/AndroidAppSettings.cfg +++ b/project/jni/application/teeworlds/AndroidAppSettings.cfg @@ -20,12 +20,12 @@ AppUsesMouse=y AppNeedsTwoButtonMouse=n ShowMouseCursor=n ForceRelativeMouseMode=n -AppNeedsArrowKeys=y +AppNeedsArrowKeys=n AppNeedsTextInput=n -AppUsesJoystick=n +AppUsesJoystick=y AppUsesAccelerometer=y AppUsesMultitouch=n -NonBlockingSwapBuffers=y +NonBlockingSwapBuffers=n RedefinedKeys="SPACE RETURN NO_REMAP NO_REMAP" AppTouchscreenKeyboardKeysAmount=4 AppTouchscreenKeyboardKeysAmountAutoFire=0 diff --git a/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.c b/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.c deleted file mode 120000 index 3b72c7bbb..000000000 --- a/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.c +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/audio/android/SDL_androidaudio.c \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.c b/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.c new file mode 100644 index 000000000..31dab93bd --- /dev/null +++ b/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.c @@ -0,0 +1,349 @@ +/* + 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 + + This file written by Ryan C. Gordon (icculus@icculus.org) +*/ +#include "SDL_config.h" +#include "SDL_version.h" + +#include "SDL_rwops.h" +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "../SDL_audiomem.h" +#include "../SDL_audio_c.h" +#include "../SDL_audiodev_c.h" +#include "SDL_androidaudio.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include +#include +#include // for memset() +#include + +#define _THIS SDL_AudioDevice *this + +/* Audio driver functions */ + +static void ANDROIDAUD_WaitAudio(_THIS); +static void ANDROIDAUD_PlayAudio(_THIS); +static Uint8 *ANDROIDAUD_GetAudioBuf(_THIS); +static void ANDROIDAUD_CloseAudio(_THIS); +static void ANDROIDAUD_ThreadInit(_THIS); +static void ANDROIDAUD_ThreadDeinit(_THIS); + +#if SDL_VERSION_ATLEAST(1,3,0) + +static int ANDROIDAUD_OpenAudio(_THIS, const char *devname, int iscapture); + +static void ANDROIDAUD_DeleteDevice() +{ +} + +static int ANDROIDAUD_CreateDevice(SDL_AudioDriverImpl * impl) +{ + + /* Set the function pointers */ + impl->OpenDevice = ANDROIDAUD_OpenAudio; + impl->WaitDevice = ANDROIDAUD_WaitAudio; + impl->PlayDevice = ANDROIDAUD_PlayAudio; + impl->GetDeviceBuf = ANDROIDAUD_GetAudioBuf; + impl->CloseDevice = ANDROIDAUD_CloseAudio; + impl->ThreadInit = ANDROIDAUD_ThreadInit; + impl->WaitDone = ANDROIDAUD_ThreadDeinit; + impl->Deinitialize = ANDROIDAUD_DeleteDevice; + impl->OnlyHasDefaultOutputDevice = 1; + + return 1; +} + +AudioBootStrap ANDROIDAUD_bootstrap = { + "android", "SDL Android audio driver", + ANDROIDAUD_CreateDevice, 0 +}; + +#else + +static int ANDROIDAUD_OpenAudio(_THIS, SDL_AudioSpec *spec); + +static int ANDROIDAUD_Available(void) +{ + return(1); +} + +static void ANDROIDAUD_DeleteDevice(SDL_AudioDevice *device) +{ + SDL_free(device); +} + +static SDL_AudioDevice *ANDROIDAUD_CreateDevice(int devindex) +{ + SDL_AudioDevice *this; + + /* Initialize all variables that we clean on shutdown */ + this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); + if ( this ) { + SDL_memset(this, 0, (sizeof *this)); + this->hidden = NULL; + } else { + SDL_OutOfMemory(); + return(0); + } + + /* Set the function pointers */ + this->OpenAudio = ANDROIDAUD_OpenAudio; + this->WaitAudio = ANDROIDAUD_WaitAudio; + this->PlayAudio = ANDROIDAUD_PlayAudio; + this->GetAudioBuf = ANDROIDAUD_GetAudioBuf; + this->CloseAudio = ANDROIDAUD_CloseAudio; + this->ThreadInit = ANDROIDAUD_ThreadInit; + this->WaitDone = ANDROIDAUD_ThreadDeinit; + this->free = ANDROIDAUD_DeleteDevice; + + return this; +} + +AudioBootStrap ANDROIDAUD_bootstrap = { + "android", "SDL Android audio driver", + ANDROIDAUD_Available, ANDROIDAUD_CreateDevice +}; + +#endif + + +static unsigned char * audioBuffer = NULL; +static size_t audioBufferSize = 0; + +// Extremely wicked JNI environment to call Java functions from C code +static jbyteArray audioBufferJNI = NULL; +static JavaVM *jniVM = NULL; +static jobject JavaAudioThread = NULL; +static jmethodID JavaInitAudio = NULL; +static jmethodID JavaDeinitAudio = NULL; +static jmethodID JavaPauseAudioPlayback = NULL; +static jmethodID JavaResumeAudioPlayback = NULL; + + +static Uint8 *ANDROIDAUD_GetAudioBuf(_THIS) +{ + return(audioBuffer); +} + + +#if SDL_VERSION_ATLEAST(1,3,0) +static int ANDROIDAUD_OpenAudio (_THIS, const char *devname, int iscapture) +{ + SDL_AudioSpec *audioFormat = &this->spec; + +#else +static int ANDROIDAUD_OpenAudio (_THIS, SDL_AudioSpec *spec) +{ + SDL_AudioSpec *audioFormat = spec; +#endif + + int bytesPerSample; + JNIEnv * jniEnv = NULL; + + this->hidden = NULL; + + if( ! (audioFormat->format == AUDIO_S8 || audioFormat->format == AUDIO_S16) ) + { + __android_log_print(ANDROID_LOG_ERROR, "libSDL", "Application requested unsupported audio format - only S8 and S16 are supported"); + return (-1); // TODO: enable format conversion? Don't know how to do that in SDL + } + + bytesPerSample = (audioFormat->format & 0xFF) / 8; + audioFormat->format = ( bytesPerSample == 2 ) ? AUDIO_S16 : AUDIO_S8; + + __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): app requested audio bytespersample %d freq %d channels %d samples %d", bytesPerSample, audioFormat->freq, (int)audioFormat->channels, (int)audioFormat->samples); + + if(audioFormat->samples <= 0) + audioFormat->samples = 128; // Some sane value + if( audioFormat->samples > 32768 ) // Why anyone need so huge audio buffer? + { + audioFormat->samples = 32768; + __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): limiting samples size to ", (int)audioFormat->samples); + } + + SDL_CalculateAudioSpec(audioFormat); + + + (*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL); + + if( !jniEnv ) + { + __android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_OpenAudio: Java VM AttachCurrentThread() failed"); + return (-1); // TODO: enable format conversion? Don't know how to do that in SDL + } + + // The returned audioBufferSize may be huge, up to 100 Kb for 44100 because user may have selected large audio buffer to get rid of choppy sound + audioBufferSize = (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaInitAudio, + (jint)audioFormat->freq, (jint)audioFormat->channels, + (jint)(( bytesPerSample == 2 ) ? 1 : 0), (jint)(audioFormat->size) ); + + if( audioBufferSize == 0 ) + { + __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): failed to get audio buffer from JNI"); + ANDROIDAUD_CloseAudio(this); + return(-1); + } + + /* We cannot call DetachCurrentThread() from main thread or we'll crash */ + /* (*jniVM)->DetachCurrentThread(jniVM); */ + + audioFormat->samples = audioBufferSize / bytesPerSample / audioFormat->channels; + audioFormat->size = audioBufferSize; + __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): app opened audio bytespersample %d freq %d channels %d bufsize %d", bytesPerSample, audioFormat->freq, (int)audioFormat->channels, audioBufferSize); + + SDL_CalculateAudioSpec(audioFormat); + +#if SDL_VERSION_ATLEAST(1,3,0) + return(1); +#else + return(0); +#endif +} + +static void ANDROIDAUD_CloseAudio(_THIS) +{ + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_CloseAudio()"); + JNIEnv * jniEnv = NULL; + (*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL); + + (*jniEnv)->DeleteGlobalRef(jniEnv, audioBufferJNI); + audioBufferJNI = NULL; + audioBuffer = NULL; + audioBufferSize = 0; + + (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaDeinitAudio ); + + /* We cannot call DetachCurrentThread() from main thread or we'll crash */ + /* (*jniVM)->DetachCurrentThread(jniVM); */ + +} + +/* This function waits until it is possible to write a full sound buffer */ +static void ANDROIDAUD_WaitAudio(_THIS) +{ + /* We will block in PlayAudio(), do nothing here */ +} + +static JNIEnv * jniEnvPlaying = NULL; +static jmethodID JavaFillBuffer = NULL; + +static void ANDROIDAUD_ThreadInit(_THIS) +{ + jclass JavaAudioThreadClass = NULL; + jmethodID JavaInitThread = NULL; + jmethodID JavaGetBuffer = NULL; + jboolean isCopy = JNI_TRUE; + + (*jniVM)->AttachCurrentThread(jniVM, &jniEnvPlaying, NULL); + + JavaAudioThreadClass = (*jniEnvPlaying)->GetObjectClass(jniEnvPlaying, JavaAudioThread); + JavaFillBuffer = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "fillBuffer", "()I"); + + /* HACK: raise our own thread priority to max to get rid of "W/AudioFlinger: write blocked for 54 msecs" errors */ + JavaInitThread = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "initAudioThread", "()I"); + (*jniEnvPlaying)->CallIntMethod( jniEnvPlaying, JavaAudioThread, JavaInitThread ); + + JavaGetBuffer = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "getBuffer", "()[B"); + audioBufferJNI = (*jniEnvPlaying)->CallObjectMethod( jniEnvPlaying, JavaAudioThread, JavaGetBuffer ); + audioBufferJNI = (*jniEnvPlaying)->NewGlobalRef(jniEnvPlaying, audioBufferJNI); + audioBuffer = (unsigned char *) (*jniEnvPlaying)->GetByteArrayElements(jniEnvPlaying, audioBufferJNI, &isCopy); + if( !audioBuffer ) + { + __android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_ThreadInit() JNI::GetByteArrayElements() failed! we will crash now"); + return; + } + if( isCopy == JNI_TRUE ) + __android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_ThreadInit(): JNI returns a copy of byte array - no audio will be played"); + + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_ThreadInit()"); + SDL_memset(audioBuffer, this->spec.silence, this->spec.size); +}; + +static void ANDROIDAUD_ThreadDeinit(_THIS) +{ + (*jniVM)->DetachCurrentThread(jniVM); +}; + +static void ANDROIDAUD_PlayAudio(_THIS) +{ + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio()"); + jboolean isCopy = JNI_TRUE; + + (*jniEnvPlaying)->ReleaseByteArrayElements(jniEnvPlaying, audioBufferJNI, (jbyte *)audioBuffer, 0); + audioBuffer = NULL; + + (*jniEnvPlaying)->CallIntMethod( jniEnvPlaying, JavaAudioThread, JavaFillBuffer ); + + audioBuffer = (unsigned char *) (*jniEnvPlaying)->GetByteArrayElements(jniEnvPlaying, audioBufferJNI, &isCopy); + if( !audioBuffer ) + __android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_PlayAudio() JNI::GetByteArrayElements() failed! we will crash now"); + + if( isCopy == JNI_TRUE ) + __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio() JNI returns a copy of byte array - that's slow"); +} + +int SDL_ANDROID_PauseAudioPlayback(void) +{ + JNIEnv * jniEnv = NULL; + (*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL); + return (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaPauseAudioPlayback ); +}; +int SDL_ANDROID_ResumeAudioPlayback(void) +{ + JNIEnv * jniEnv = NULL; + (*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL); + return (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaResumeAudioPlayback ); +}; + + +#ifndef SDL_JAVA_PACKAGE_PATH +#error You have to define SDL_JAVA_PACKAGE_PATH to your package path with dots replaced with underscores, for example "com_example_SanAngeles" +#endif +#define JAVA_EXPORT_NAME2(name,package) Java_##package##_##name +#define JAVA_EXPORT_NAME1(name,package) JAVA_EXPORT_NAME2(name,package) +#define JAVA_EXPORT_NAME(name) JAVA_EXPORT_NAME1(name,SDL_JAVA_PACKAGE_PATH) + +JNIEXPORT jint JNICALL JAVA_EXPORT_NAME(AudioThread_nativeAudioInitJavaCallbacks) (JNIEnv * jniEnv, jobject thiz) +{ + jclass JavaAudioThreadClass = NULL; + JavaAudioThread = (*jniEnv)->NewGlobalRef(jniEnv, thiz); + JavaAudioThreadClass = (*jniEnv)->GetObjectClass(jniEnv, JavaAudioThread); + JavaInitAudio = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "initAudio", "(IIII)I"); + JavaDeinitAudio = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "deinitAudio", "()I"); + JavaPauseAudioPlayback = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "pauseAudioPlayback", "()I"); + JavaResumeAudioPlayback = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "resumeAudioPlayback", "()I"); +} + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) +{ + jniVM = vm; + return JNI_VERSION_1_2; +}; + +JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) +{ + /* TODO: free JavaAudioThread */ + jniVM = vm; +}; + diff --git a/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.h b/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.h deleted file mode 120000 index 142f84591..000000000 --- a/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.h +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/audio/android/SDL_androidaudio.h \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.h b/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.h new file mode 100644 index 000000000..ae1e745d3 --- /dev/null +++ b/project/jni/sdl-1.2/src/audio/android/SDL_androidaudio.h @@ -0,0 +1,32 @@ +/* + 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 "SDL_config.h" + +#ifndef _SDL_androidaudio_h +#define _SDL_androidaudio_h + +#include "../SDL_sysaudio.h" + +struct SDL_PrivateAudioData { +}; + +#endif /* _SDL_androidaudio_h */ 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 deleted file mode 120000 index 891312739..000000000 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/video/android/SDL_androidinput.c \ No newline at end of file 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 new file mode 100644 index 000000000..03d3a55fb --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c @@ -0,0 +1,2183 @@ +/* + 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 "SDL_screenkeyboard.h" +#include "jniwrapperstuff.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]; + +static inline SDL_scancode TranslateKey(int scancode) +{ + if ( scancode >= SDL_arraysize(SDL_android_keymap) ) + scancode = KEYCODE_UNKNOWN; + return SDL_android_keymap[scancode]; +} + +static int isTrackballUsed = 0; +static int isMouseUsed = 0; + +enum { RIGHT_CLICK_NONE = 0, RIGHT_CLICK_WITH_MULTITOUCH = 1, RIGHT_CLICK_WITH_PRESSURE = 2, + RIGHT_CLICK_WITH_KEY = 3, RIGHT_CLICK_WITH_TIMEOUT = 4 }; +enum { LEFT_CLICK_NORMAL = 0, LEFT_CLICK_NEAR_CURSOR = 1, LEFT_CLICK_WITH_MULTITOUCH = 2, LEFT_CLICK_WITH_PRESSURE = 3, + LEFT_CLICK_WITH_KEY = 4, LEFT_CLICK_WITH_TIMEOUT = 5, LEFT_CLICK_WITH_TAP = 6, LEFT_CLICK_WITH_TAP_OR_TIMEOUT = 7 }; +static int leftClickMethod = LEFT_CLICK_NORMAL; +static int rightClickMethod = RIGHT_CLICK_NONE; +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; +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}; +static int TrackballDampening = 0; // in milliseconds +static Uint32 lastTrackballAction = 0; +enum { TOUCH_PTR_UP = 0, TOUCH_PTR_MOUSE = 1, TOUCH_PTR_SCREENKB = 2 }; +static int touchPointers[MAX_MULTITOUCH_POINTERS] = {0}; +static int firstMousePointerId = -1; +enum { MAX_MULTITOUCH_GESTURES = 4 }; +static int multitouchGestureKeycode[MAX_MULTITOUCH_GESTURES] = { +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_6)), +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_7)), +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_8)), +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_9)) +}; +static int multitouchGestureKeyPressed[MAX_MULTITOUCH_GESTURES] = { 0, 0, 0, 0 }; +static int multitouchGestureSensitivity = 0; +static int multitouchGestureDist = -1; +static int multitouchGestureAngle = 0; +static int multitouchGestureX = -1; +static int multitouchGestureY = -1; +int SDL_ANDROID_TouchscreenCalibrationWidth = 480; +int SDL_ANDROID_TouchscreenCalibrationHeight = 320; +int SDL_ANDROID_TouchscreenCalibrationX = 0; +int SDL_ANDROID_TouchscreenCalibrationY = 0; +static int leftClickTimeout = 0; +static int rightClickTimeout = 0; +static int mouseInitialX = -1; +static int mouseInitialY = -1; +static unsigned int mouseInitialTime = 0; +static volatile int deferredMouseTap = 0; +static int relativeMovement = 0; +static int relativeMovementSpeed = 2; +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; + +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 ); +} + +void UpdateScreenUnderFingerRect(int x, int y) +{ +#if SDL_VERSION_ATLEAST(1,3,0) + return; +#else + int screenX = SDL_ANDROID_sFakeWindowWidth, screenY = SDL_ANDROID_sFakeWindowHeight; + if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_NONE ) + return; + + if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER ) + { + SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = screenX / 4; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = screenY / 4; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = x - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w/2; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = y - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h/2; + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = 0; + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = 0; + + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x > screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w; + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y > screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h; + + SDL_ANDROID_ShowScreenUnderFingerRect.w = SDL_ANDROID_ShowScreenUnderFingerRectSrc.w * 3 / 2; + SDL_ANDROID_ShowScreenUnderFingerRect.h = SDL_ANDROID_ShowScreenUnderFingerRectSrc.h * 3 / 2; + SDL_ANDROID_ShowScreenUnderFingerRect.x = x + SDL_ANDROID_ShowScreenUnderFingerRect.w/10; + SDL_ANDROID_ShowScreenUnderFingerRect.y = y - SDL_ANDROID_ShowScreenUnderFingerRect.h*11/10; + if( SDL_ANDROID_ShowScreenUnderFingerRect.x < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRect.x = 0; + if( SDL_ANDROID_ShowScreenUnderFingerRect.y < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRect.y = 0; + if( SDL_ANDROID_ShowScreenUnderFingerRect.x + SDL_ANDROID_ShowScreenUnderFingerRect.w >= screenX ) + SDL_ANDROID_ShowScreenUnderFingerRect.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRect.w - 1; + if( SDL_ANDROID_ShowScreenUnderFingerRect.y + SDL_ANDROID_ShowScreenUnderFingerRect.h >= screenY ) + SDL_ANDROID_ShowScreenUnderFingerRect.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRect.h - 1; + if( InsideRect(&SDL_ANDROID_ShowScreenUnderFingerRect, x, y) ) + SDL_ANDROID_ShowScreenUnderFingerRect.x = x - SDL_ANDROID_ShowScreenUnderFingerRect.w*11/10 - 1; + } + if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_SCREEN_TRANSFORM ) + { + SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = screenX / 3; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = screenY / 3; + //SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = x - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w/2; + //SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = y - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h/2; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = x * (screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w) / screenX; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = y * (screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h) / screenY; + + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = 0; + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = 0; + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x > screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w; + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y > screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h; + + SDL_ANDROID_ShowScreenUnderFingerRect.w = screenX * 2 / 3; + SDL_ANDROID_ShowScreenUnderFingerRect.h = screenY * 2 / 3; + //SDL_ANDROID_ShowScreenUnderFingerRect.x = x - SDL_ANDROID_ShowScreenUnderFingerRect.w/2; + //SDL_ANDROID_ShowScreenUnderFingerRect.y = y - SDL_ANDROID_ShowScreenUnderFingerRect.h/2; + SDL_ANDROID_ShowScreenUnderFingerRect.x = x * (screenX - SDL_ANDROID_ShowScreenUnderFingerRect.w) / screenX; + SDL_ANDROID_ShowScreenUnderFingerRect.y = y * (screenY - SDL_ANDROID_ShowScreenUnderFingerRect.h) / screenY; + + + if( SDL_ANDROID_ShowScreenUnderFingerRect.x > SDL_ANDROID_ShowScreenUnderFingerRectSrc.x ) + SDL_ANDROID_ShowScreenUnderFingerRect.x = SDL_ANDROID_ShowScreenUnderFingerRectSrc.x; + if( SDL_ANDROID_ShowScreenUnderFingerRect.y > SDL_ANDROID_ShowScreenUnderFingerRectSrc.y ) + SDL_ANDROID_ShowScreenUnderFingerRect.y = SDL_ANDROID_ShowScreenUnderFingerRectSrc.y; + if( SDL_ANDROID_ShowScreenUnderFingerRect.x + SDL_ANDROID_ShowScreenUnderFingerRect.w < SDL_ANDROID_ShowScreenUnderFingerRectSrc.x + SDL_ANDROID_ShowScreenUnderFingerRectSrc.w ) + SDL_ANDROID_ShowScreenUnderFingerRect.x = SDL_ANDROID_ShowScreenUnderFingerRectSrc.x + SDL_ANDROID_ShowScreenUnderFingerRectSrc.w - SDL_ANDROID_ShowScreenUnderFingerRect.w; + if( SDL_ANDROID_ShowScreenUnderFingerRect.y + SDL_ANDROID_ShowScreenUnderFingerRect.h < SDL_ANDROID_ShowScreenUnderFingerRectSrc.y + SDL_ANDROID_ShowScreenUnderFingerRectSrc.h ) + SDL_ANDROID_ShowScreenUnderFingerRect.y = SDL_ANDROID_ShowScreenUnderFingerRectSrc.y + SDL_ANDROID_ShowScreenUnderFingerRectSrc.h - SDL_ANDROID_ShowScreenUnderFingerRect.h; + + if( SDL_ANDROID_ShowScreenUnderFingerRect.x < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRect.x = 0; + if( SDL_ANDROID_ShowScreenUnderFingerRect.y < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRect.y = 0; + if( SDL_ANDROID_ShowScreenUnderFingerRect.x > screenX - SDL_ANDROID_ShowScreenUnderFingerRect.w ) + SDL_ANDROID_ShowScreenUnderFingerRect.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRect.w; + if( SDL_ANDROID_ShowScreenUnderFingerRect.y > screenY - SDL_ANDROID_ShowScreenUnderFingerRect.h ) + SDL_ANDROID_ShowScreenUnderFingerRect.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRect.h; + } + if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_FULLSCREEN_MAGNIFIER ) + { + SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = screenX / 2; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = screenY / 2; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = x - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w/2; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = y - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h/2; + + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = 0; + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y < 0 ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = 0; + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x > screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w; + if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y > screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h ) + SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h; + + SDL_ANDROID_ShowScreenUnderFingerRect.x = 0; + SDL_ANDROID_ShowScreenUnderFingerRect.y = 0; + SDL_ANDROID_ShowScreenUnderFingerRect.w = screenX; + SDL_ANDROID_ShowScreenUnderFingerRect.h = screenY; + } +#endif +} + + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject thiz, jint x, jint y, jint action, jint pointerId, jint force, jint radius ) +{ + // TODO: this method is damn huge + int i; +#if SDL_VERSION_ATLEAST(1,3,0) + + SDL_Window * window = SDL_GetFocusWindow(); + if( !window ) + return; + +#define SDL_ANDROID_sFakeWindowWidth window->w +#define SDL_ANDROID_sFakeWindowHeight window->h + +#else + if( !SDL_CurrentVideoSurface ) + return; +#endif + if(pointerId < 0) + pointerId = 0; + if(pointerId > MAX_MULTITOUCH_POINTERS) + pointerId = MAX_MULTITOUCH_POINTERS; + + // The touch is passed either to on-screen keyboard or as mouse event for all duration of touch between down and up, + // even if the finger is not anymore above screen kb button it will not acr as mouse event, and if it's initially + // touches the screen outside of screen kb it won't trigger button keypress - + // I think it's more logical this way + if( SDL_ANDROID_isTouchscreenKeyboardUsed && ( action == MOUSE_DOWN || touchPointers[pointerId] == TOUCH_PTR_SCREENKB ) ) + { + if( SDL_ANDROID_processTouchscreenKeyboard(x, y, action, pointerId) && action == MOUSE_DOWN ) + touchPointers[pointerId] = TOUCH_PTR_SCREENKB; + if( touchPointers[pointerId] == TOUCH_PTR_SCREENKB ) + { + if( action == MOUSE_UP ) + touchPointers[pointerId] = TOUCH_PTR_UP; + return; + } + } + + if( action == MOUSE_DOWN ) + { + touchPointers[pointerId] = TOUCH_PTR_MOUSE; + firstMousePointerId = -1; + for( i = 0; i < MAX_MULTITOUCH_POINTERS; i++ ) + { + if( touchPointers[i] == TOUCH_PTR_MOUSE ) + { + firstMousePointerId = i; + break; + } + } + } + + x -= SDL_ANDROID_TouchscreenCalibrationX; + y -= SDL_ANDROID_TouchscreenCalibrationY; +#if SDL_VIDEO_RENDER_RESIZE + // Translate mouse coordinates + + x = x * SDL_ANDROID_sFakeWindowWidth / SDL_ANDROID_TouchscreenCalibrationWidth; + y = y * SDL_ANDROID_sFakeWindowHeight / SDL_ANDROID_TouchscreenCalibrationHeight; + if( x < 0 ) + x = 0; + if( x > SDL_ANDROID_sFakeWindowWidth ) + x = SDL_ANDROID_sFakeWindowWidth; + if( y < 0 ) + y = 0; + if( y > SDL_ANDROID_sFakeWindowHeight ) + y = SDL_ANDROID_sFakeWindowHeight; +#else + x = x * SDL_ANDROID_sRealWindowWidth / SDL_ANDROID_TouchscreenCalibrationWidth; + y = y * SDL_ANDROID_sRealWindowHeight / SDL_ANDROID_TouchscreenCalibrationHeight; +#endif + + if( action == MOUSE_UP ) + { + multitouchGestureX = -1; + multitouchGestureY = -1; + multitouchGestureDist = -1; + for(i = 0; i < MAX_MULTITOUCH_GESTURES; i++) + { + if( multitouchGestureKeyPressed[i] ) + { + multitouchGestureKeyPressed[i] = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[i] ); + } + } + } + else if( !hardwareMouseDetected ) + { + if( firstMousePointerId != pointerId ) + { + multitouchGestureX = x; + multitouchGestureY = y; + } + if( firstMousePointerId == pointerId && multitouchGestureX >= 0 ) + { + int dist = abs( x - multitouchGestureX ) + abs( y - multitouchGestureY ); + int angle = atan2i( y - multitouchGestureY, x - multitouchGestureX ); + if( multitouchGestureDist < 0 ) + { + multitouchGestureDist = dist; + multitouchGestureAngle = angle; + } + else + { + int distMaxDiff = SDL_ANDROID_sFakeWindowHeight / ( 1 + (1 + multitouchGestureSensitivity) * 2 ); + int angleMaxDiff = atan2i_PI / ( 1 + (1 + multitouchGestureSensitivity) * 2 ); + if( dist - multitouchGestureDist > distMaxDiff ) + { + multitouchGestureKeyPressed[0] = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[0] ); + } + else + if( multitouchGestureKeyPressed[0] ) + { + multitouchGestureKeyPressed[0] = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[0] ); + } + if( multitouchGestureDist - dist > distMaxDiff ) + { + multitouchGestureKeyPressed[1] = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[1] ); + } + else + if( multitouchGestureKeyPressed[1] ) + { + multitouchGestureKeyPressed[1] = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[1] ); + } + + int angleDiff = angle - multitouchGestureAngle; + + while( angleDiff < atan2i_PI ) + angleDiff += atan2i_PI * 2; + while( angleDiff > atan2i_PI ) + angleDiff -= atan2i_PI * 2; + + if( angleDiff < -angleMaxDiff ) + { + multitouchGestureKeyPressed[2] = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[2] ); + } + else + if( multitouchGestureKeyPressed[2] ) + { + multitouchGestureKeyPressed[2] = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[2] ); + } + if( angleDiff > angleMaxDiff ) + { + multitouchGestureKeyPressed[3] = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[3] ); + } + else + if( multitouchGestureKeyPressed[3] ) + { + multitouchGestureKeyPressed[3] = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[3] ); + } + } + } + } + + if( isMultitouchUsed ) + { +#if SDL_VERSION_ATLEAST(1,3,0) + // Use nifty SDL 1.3 multitouch API + if( action == MOUSE_MOVE ) + SDL_ANDROID_MainThreadPushMultitouchMotion(pointerId, x, y, force + radius); + else + SDL_ANDROID_MainThreadPushMultitouchButton(pointerId, action == MOUSE_DOWN ? 1 : 0, x, y, force + radius); +#endif + + if( action == MOUSE_DOWN ) + SDL_ANDROID_MainThreadPushJoystickButton(0, pointerId, SDL_PRESSED); + SDL_ANDROID_MainThreadPushJoystickBall(0, pointerId, x, y); + SDL_ANDROID_MainThreadPushJoystickAxis(0, pointerId+4, force + radius); // Radius is more sensitive usually + if( action == MOUSE_UP ) + SDL_ANDROID_MainThreadPushJoystickButton(0, pointerId, SDL_RELEASED); + } + if( !isMouseUsed && !SDL_ANDROID_isTouchscreenKeyboardUsed ) + { + SDL_keysym keysym; + if( action != MOUSE_MOVE ) + SDL_ANDROID_MainThreadPushKeyboardKey( action == MOUSE_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_ANDROID_GetScreenKeyboardButtonKey(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0) ); + return; + } + + if( !isMouseUsed ) + return; + + if( pointerId == firstMousePointerId ) + { + if( relativeMovement ) + { + if( action == MOUSE_DOWN ) + { + relativeMovementX = currentMouseX - x; + relativeMovementY = currentMouseY - y; + } + x += relativeMovementX; + y += relativeMovementY; + + int diffX = x - currentMouseX; + int diffY = y - currentMouseY; + int coeff = relativeMovementSpeed + 2; + if( relativeMovementSpeed > 2 ) + coeff += relativeMovementSpeed - 2; + diffX = diffX * coeff / 4; + diffY = diffY * coeff / 4; + if( relativeMovementAccel > 0 ) + { + unsigned int newTime = SDL_GetTicks(); + if( newTime - relativeMovementTime > 0 ) + { + diffX += diffX * ( relativeMovementAccel * 30 ) / (int)(newTime - relativeMovementTime); + diffY += diffY * ( relativeMovementAccel * 30 ) / (int)(newTime - relativeMovementTime); + } + relativeMovementTime = newTime; + } + diffX -= x - currentMouseX; + diffY -= y - currentMouseY; + x += diffX; + y += diffY; + relativeMovementX += diffX; + relativeMovementY += diffY; + + diffX = x; + diffY = y; + if( x < 0 ) + x = 0; + if( x > SDL_ANDROID_sFakeWindowWidth ) + x = SDL_ANDROID_sFakeWindowWidth; + if( y < 0 ) + y = 0; + if( y > SDL_ANDROID_sFakeWindowHeight ) + y = SDL_ANDROID_sFakeWindowHeight; + relativeMovementX += x - diffX; + relativeMovementY += y - diffY; + } + if( action == MOUSE_UP ) + { + if( rightClickMethod != RIGHT_CLICK_WITH_KEY ) + SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_RIGHT ); + + if( mouseInitialX >= 0 && mouseInitialY >= 0 && ( + leftClickMethod == LEFT_CLICK_WITH_TAP || leftClickMethod == LEFT_CLICK_WITH_TAP_OR_TIMEOUT ) && + abs(mouseInitialX - x) < SDL_ANDROID_sFakeWindowHeight / 16 && + abs(mouseInitialY - y) < SDL_ANDROID_sFakeWindowHeight / 16 && + SDL_GetTicks() - mouseInitialTime < 700 ) + { + SDL_ANDROID_MainThreadPushMouseMotion(mouseInitialX, mouseInitialY); + SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); + deferredMouseTap = 2; + mouseInitialX = -1; + mouseInitialY = -1; + } + else + { + if( leftClickMethod != LEFT_CLICK_WITH_KEY ) + SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT ); + } + + SDL_ANDROID_ShowScreenUnderFingerRect.w = SDL_ANDROID_ShowScreenUnderFingerRect.h = 0; + SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = 0; + 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); + else + SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y); + } + moveMouseWithKbX = -1; + moveMouseWithKbY = -1; + moveMouseWithKbSpeedX = 0; + 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 ) + { + SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); + moveMouseWithKbX = currentMouseX; + moveMouseWithKbY = currentMouseY; + moveMouseWithKbSpeedX = 0; + moveMouseWithKbSpeedY = 0; + action = MOUSE_MOVE; + } + else + if( leftClickMethod == LEFT_CLICK_NORMAL ) + { + SDL_ANDROID_MainThreadPushMouseMotion(x, y); + if( !hardwareMouseDetected || currentMouseButtons == 0 ) + SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); + } + else + { + SDL_ANDROID_MainThreadPushMouseMotion(x, y); + action == MOUSE_MOVE; + mouseInitialX = x; + mouseInitialY = y; + mouseInitialTime = SDL_GetTicks(); + } + UpdateScreenUnderFingerRect(x, y); + } + if( action == MOUSE_MOVE ) + { + if( moveMouseWithKbX >= 0 ) + { + // Mouse lazily follows magnifying glass, not very intuitive for drag&drop + /* + if( abs(moveMouseWithKbX - x) > SDL_ANDROID_sFakeWindowWidth / 12 ) + moveMouseWithKbSpeedX += moveMouseWithKbX > x ? -1 : 1; + else + moveMouseWithKbSpeedX = moveMouseWithKbSpeedX * 2 / 3; + if( abs(moveMouseWithKbY - y) > SDL_ANDROID_sFakeWindowHeight / 12 ) + moveMouseWithKbSpeedY += moveMouseWithKbY > y ? -1 : 1; + else + moveMouseWithKbSpeedY = moveMouseWithKbSpeedY * 2 / 3; + + moveMouseWithKbX += moveMouseWithKbSpeedX; + 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 ) + { + moveMouseWithKbX = -1; + moveMouseWithKbY = -1; + moveMouseWithKbSpeedX = 0; + moveMouseWithKbSpeedY = 0; + SDL_ANDROID_MainThreadPushMouseMotion(x, y); + } + else + SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); + } + else + { + SDL_ANDROID_MainThreadPushMouseMotion(x, y); + } + + if( rightClickMethod == RIGHT_CLICK_WITH_PRESSURE || leftClickMethod == LEFT_CLICK_WITH_PRESSURE ) + { + int button = (leftClickMethod == LEFT_CLICK_WITH_PRESSURE) ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT; + int buttonState = ( force > maxForce || radius > maxRadius ); + if( button == SDL_BUTTON_RIGHT ) + SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT ); + SDL_ANDROID_MainThreadPushMouseButton( buttonState ? SDL_PRESSED : SDL_RELEASED, button ); + } + if( mouseInitialX >= 0 && mouseInitialY >= 0 && ( + leftClickMethod == LEFT_CLICK_WITH_TIMEOUT || leftClickMethod == LEFT_CLICK_WITH_TAP || + leftClickMethod == LEFT_CLICK_WITH_TAP_OR_TIMEOUT || rightClickMethod == RIGHT_CLICK_WITH_TIMEOUT ) ) + { + if( abs(mouseInitialX - x) >= SDL_ANDROID_sFakeWindowHeight / 15 || abs(mouseInitialY - y) >= SDL_ANDROID_sFakeWindowHeight / 15 ) + { + mouseInitialX = -1; + mouseInitialY = -1; + } + else + { + if( leftClickMethod == LEFT_CLICK_WITH_TIMEOUT || leftClickMethod == LEFT_CLICK_WITH_TAP_OR_TIMEOUT ) + { + if( SDL_GetTicks() - mouseInitialTime > leftClickTimeout ) + { + //SDL_ANDROID_MainThreadPushMouseMotion(mouseInitialX, mouseInitialY); + SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); + mouseInitialX = -1; + mouseInitialY = -1; + } + } + if( rightClickMethod == RIGHT_CLICK_WITH_TIMEOUT ) + { + if( SDL_GetTicks() - mouseInitialTime > rightClickTimeout ) + { + //SDL_ANDROID_MainThreadPushMouseMotion(mouseInitialX, mouseInitialY); + SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_RIGHT ); + mouseInitialX = -1; + mouseInitialY = -1; + } + } + } + } + if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER ) + UpdateScreenUnderFingerRect(x, y); + } + if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_SCREEN_TRANSFORM || + SDL_ANDROID_ShowScreenUnderFinger == ZOOM_FULLSCREEN_MAGNIFIER ) + UpdateScreenUnderFingerRect(x, y); + } + if( pointerId != firstMousePointerId && (action == MOUSE_DOWN || action == MOUSE_UP) ) + { + if( leftClickMethod == LEFT_CLICK_WITH_MULTITOUCH ) + { + SDL_ANDROID_MainThreadPushMouseButton( (action == MOUSE_DOWN) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT ); + } + else if( rightClickMethod == RIGHT_CLICK_WITH_MULTITOUCH ) + { + SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT ); + SDL_ANDROID_MainThreadPushMouseButton( (action == MOUSE_DOWN) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT ); + } + } + + if( action == MOUSE_UP ) + { + touchPointers[pointerId] = TOUCH_PTR_UP; + firstMousePointerId = -1; + for( i = 0; i < MAX_MULTITOUCH_POINTERS; i++ ) + { + if( touchPointers[i] == TOUCH_PTR_MOUSE ) + { + firstMousePointerId = i; + break; + } + } + } + + if( action == MOUSE_HOVER && !relativeMovement ) + { + SDL_ANDROID_MainThreadPushMouseMotion(x, y); + } +} + +void ProcessDeferredMouseTap() +{ + if( deferredMouseTap > 0 ) + { + deferredMouseTap--; + if( deferredMouseTap <= 0 ) + { +#if SDL_VERSION_ATLEAST(1,3,0) + SDL_Window * window = SDL_GetFocusWindow(); + if( !window ) + return; +#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); + 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); + } +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeTouchpad) ( JNIEnv* env, jobject thiz, jint x, jint y, jint down, jint multitouch) +{ + if( !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; + } + else + { + // x and y from 0 to 65535 + if( moveMouseWithKbX < 0 ) + { + moveMouseWithKbX = currentMouseX; + moveMouseWithKbY = currentMouseY; + } + moveMouseWithKbSpeedX = (x - 32767) / 8192; + moveMouseWithKbSpeedY = (y - 32767) / 8192; + //moveMouseWithKbX += moveMouseWithKbSpeedX; + //moveMouseWithKbY += moveMouseWithKbSpeedY; + SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); + moveMouseWithKbAccelUpdateNeeded = 1; + + if( multitouch ) + SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_RIGHT ); + else + if( abs(x - 32767) < 8192 && abs(y - 32767) < 8192 ) + SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); + } +} + +void SDL_ANDROID_WarpMouse(int x, int y) +{ + if(!relativeMovement) + { + //SDL_ANDROID_MainThreadPushMouseMotion(x, 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; + SDL_ANDROID_MainThreadPushMouseMotion(x, y); + } +}; + +static int processAndroidTrackball(int key, int action); + +JNIEXPORT jint JNICALL +JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeKey) ( JNIEnv* env, jobject thiz, jint key, jint action ) +{ +#if SDL_VERSION_ATLEAST(1,3,0) +#else + if( !SDL_CurrentVideoSurface ) + return 1; +#endif + + if( isTrackballUsed ) + if( processAndroidTrackball(key, action) ) + return 1; + if( key == rightClickKey && rightClickMethod == RIGHT_CLICK_WITH_KEY ) + { + SDL_ANDROID_MainThreadPushMouseButton( action ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT ); + return 1; + } + if( (key == leftClickKey && leftClickMethod == LEFT_CLICK_WITH_KEY) || (clickMouseWithDpadCenter && key == KEYCODE_DPAD_CENTER) ) + { + SDL_ANDROID_MainThreadPushMouseButton( action ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT ); + return 1; + } + + if( TranslateKey(key) == SDLK_NO_REMAP || TranslateKey(key) == SDLK_UNKNOWN ) + return 0; + + SDL_ANDROID_MainThreadPushKeyboardKey( action ? SDL_PRESSED : SDL_RELEASED, TranslateKey(key) ); + return 1; +} + +static char * textInputBuffer = NULL; +int textInputBufferLen = 0; +int textInputBufferPos = 0; + +void SDL_ANDROID_TextInputInit(char * buffer, int len) +{ + textInputBuffer = buffer; + textInputBufferLen = len; + textInputBufferPos = 0; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoRenderer_nativeTextInput) ( JNIEnv* env, jobject thiz, jint ascii, jint unicode ) +{ + if( ascii == 10 ) + ascii = SDLK_RETURN; + if( !textInputBuffer ) + SDL_ANDROID_MainThreadPushText(ascii, unicode); + else + { + if( textInputBufferPos < textInputBufferLen + 4 && ascii != SDLK_RETURN && ascii != '\r' && ascii != '\n' ) + { + textInputBufferPos += UnicodeToUtf8(unicode, textInputBuffer + textInputBufferPos); + } + } +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoRenderer_nativeTextInputFinished) ( JNIEnv* env, jobject thiz ) +{ + textInputBuffer = NULL; + SDL_ANDROID_TextInputFinished(); +} + +static void updateOrientation ( float accX, float accY, float accZ ); + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(AccelerometerReader_nativeAccelerometer) ( JNIEnv* env, jobject thiz, jfloat accPosX, jfloat accPosY, jfloat accPosZ ) +{ +#if SDL_VERSION_ATLEAST(1,3,0) +#else + if( !SDL_CurrentVideoSurface ) + return; +#endif + // 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 = 0.00001f; + + updateOrientation (accPosX/normal, accPosY/normal, 0.0f); +} + + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(AccelerometerReader_nativeOrientation) ( JNIEnv* env, jobject thiz, jfloat accX, jfloat accY, jfloat accZ ) +{ +#if SDL_VERSION_ATLEAST(1,3,0) +#else + if( !SDL_CurrentVideoSurface ) + return; +#endif + updateOrientation (accX, accY, accZ); // TODO: make values in range 0.0:1.0 +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetTrackballUsed) ( JNIEnv* env, jobject thiz) +{ + isTrackballUsed = 1; +} + +static int getClickTimeout(int v) +{ + switch(v) + { + case 0: return 200; + case 1: return 300; + case 2: return 400; + case 3: return 700; + case 4: return 1000; + } + return 1000; +} + +// Mwahaha overkill! +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz, + jint RightClickMethod, jint ShowScreenUnderFinger, jint LeftClickMethod, + jint MoveMouseWithJoystick, jint ClickMouseWithDpad, + jint MaxForce, jint MaxRadius, + jint MoveMouseWithJoystickSpeed, jint MoveMouseWithJoystickAccel, + jint LeftClickKeycode, jint RightClickKeycode, + jint LeftClickTimeout, jint RightClickTimeout, + jint RelativeMovement, jint RelativeMovementSpeed, jint RelativeMovementAccel, + jint ShowMouseCursor) +{ + isMouseUsed = 1; + rightClickMethod = RightClickMethod; + SDL_ANDROID_ShowScreenUnderFinger = ShowScreenUnderFinger; + moveMouseWithArrowKeys = MoveMouseWithJoystick; + clickMouseWithDpadCenter = ClickMouseWithDpad; + leftClickMethod = LeftClickMethod; + maxForce = MaxForce; + maxRadius = MaxRadius; + moveMouseWithKbSpeed = MoveMouseWithJoystickSpeed + 1; + moveMouseWithKbAccel = MoveMouseWithJoystickAccel; + leftClickKey = LeftClickKeycode; + rightClickKey = RightClickKeycode; + leftClickTimeout = getClickTimeout(LeftClickTimeout); + rightClickTimeout = getClickTimeout(RightClickTimeout); + relativeMovement = RelativeMovement; + relativeMovementSpeed = RelativeMovementSpeed; + relativeMovementAccel = RelativeMovementAccel; + SDL_ANDROID_ShowMouseCursor = ShowMouseCursor; + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "relativeMovementSpeed %d relativeMovementAccel %d", relativeMovementSpeed, relativeMovementAccel); +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected) +{ + if( !isMouseUsed ) + return; + + static struct { + int leftClickMethod; + int ShowScreenUnderFinger; + int leftClickTimeout; + int relativeMovement; + int ShowMouseCursor; + } cfg = { 0 }; + + if( hardwareMouseDetected != detected ) + { + hardwareMouseDetected = detected; + if(detected) + { + cfg.leftClickMethod = leftClickMethod; + cfg.ShowScreenUnderFinger = SDL_ANDROID_ShowScreenUnderFinger; + cfg.leftClickTimeout = leftClickTimeout; + cfg.relativeMovement = relativeMovement; + cfg.ShowMouseCursor = SDL_ANDROID_ShowMouseCursor; + + leftClickMethod = LEFT_CLICK_NORMAL; + SDL_ANDROID_ShowScreenUnderFinger = 0; + leftClickTimeout = 0; + relativeMovement = 0; + SDL_ANDROID_ShowMouseCursor = 0; + } + else + { + leftClickMethod = cfg.leftClickMethod; + SDL_ANDROID_ShowScreenUnderFinger = cfg.ShowScreenUnderFinger; + leftClickTimeout = cfg.leftClickTimeout; + relativeMovement = cfg.relativeMovement; + SDL_ANDROID_ShowMouseCursor = cfg.ShowMouseCursor; + } + } +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseButtonsPressed) (JNIEnv* env, jobject thiz, jint buttonId, jint pressedState) +{ + int btn = SDL_BUTTON_LEFT; + if( !isMouseUsed ) + return; + + switch(buttonId) + { + case MOUSE_HW_BUTTON_LEFT: + btn = SDL_BUTTON_LEFT; + break; + case MOUSE_HW_BUTTON_RIGHT: + btn = SDL_BUTTON_RIGHT; + break; + case MOUSE_HW_BUTTON_MIDDLE: + btn = SDL_BUTTON_MIDDLE; + break; + case MOUSE_HW_BUTTON_BACK: + btn = SDL_BUTTON_X1; + break; + case MOUSE_HW_BUTTON_FORWARD: + btn = SDL_BUTTON_X2; + break; + } + SDL_ANDROID_MainThreadPushMouseButton( pressedState ? SDL_PRESSED : SDL_RELEASED, btn ); +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseWheel) (JNIEnv* env, jobject thiz, jint scrollX, jint scrollY) +{ +#if SDL_VERSION_ATLEAST(1,3,0) + SDL_ANDROID_MainThreadPushMouseWheel( scrollX, scrollY ); +#else + // TODO: direction might get inverted + for( ; scrollX > 0; scrollX-- ) + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_RIGHT) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) ); + } + for( ; scrollX < 0; scrollX++ ) + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_LEFT) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) ); + } + for( ; scrollY > 0; scrollY-- ) + { + if(!isMouseUsed) + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_DOWN) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) ); + } + else + { + SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_WHEELDOWN ); + SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_WHEELDOWN ); + } + } + for( ; scrollY < 0; scrollY++ ) + { + if(!isMouseUsed) + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_UP) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) ); + } + else + { + SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_WHEELUP ); + SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_WHEELUP ); + } + } +#endif +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetJoystickUsed) (JNIEnv* env, jobject thiz) +{ + SDL_ANDROID_isJoystickUsed = 1; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetAccelerometerUsed) (JNIEnv* env, jobject thiz) +{ + SDL_ANDROID_isAccelerometerUsed = 1; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetMultitouchUsed) ( JNIEnv* env, jobject thiz) +{ + isMultitouchUsed = 1; +} + + +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_nativeSetAccelerometerSettings) ( JNIEnv* env, jobject thiz, jint sensitivity, jint centerPos) +{ + 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; joystickSensitivity = 32767.0f * 2.0f; // Medium sensitivity + } + if( sensitivity == 2 ) + { + dx = 0.2; dy = 0.25; dz = 0.25; joystickSensitivity = 32767.0f; // Slow sensitivity + } + accelerometerCenterPos = centerPos; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetTrackballDampening) ( JNIEnv* env, jobject thiz, jint value) +{ + TrackballDampening = (value * 200); +} + +void updateOrientation ( float accX, float accY, float accZ ) +{ + SDL_keysym keysym; + // TODO: ask user for accelerometer precision from Java + + static float midX = 0, midY = 0, midZ = 0; + static int pressLeft = 0, pressRight = 0, pressUp = 0, pressDown = 0, pressR = 0, pressL = 0; + + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): %f %f %f", accX, accY, accZ); + + if( SDL_ANDROID_isAccelerometerUsed ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): sending joystick event"); + SDL_ANDROID_MainThreadPushJoystickAxis(0, 2, (Sint16)(fminf(32767.0f, fmax(-32767.0f, (accX) * 32767.0f)))); + SDL_ANDROID_MainThreadPushJoystickAxis(0, 3, (Sint16)(fminf(32767.0f, fmax(-32767.0f, -(accY) * 32767.0f)))); + //SDL_ANDROID_MainThreadPushJoystickAxis(0, 2, (Sint16)(fminf(32767.0f, fmax(-32767.0f, -(accZ) * 32767.0f)))); + return; + } + + if( accelerometerCenterPos == ACCELEROMETER_CENTER_FIXED_START ) + { + accelerometerCenterPos = ACCELEROMETER_CENTER_FIXED_HORIZ; + midX = accX; + midY = accY; + midZ = accZ; + } + + if( SDL_ANDROID_isJoystickUsed ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): sending joystick event"); + SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, (Sint16)(fminf(32767.0f, fmax(-32767.0f, (accX - midX) * joystickSensitivity)))); + SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, (Sint16)(fminf(32767.0f, fmax(-32767.0f, -(accY - midY) * joystickSensitivity)))); + //SDL_ANDROID_MainThreadPushJoystickAxis(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; + } + return; + } + + if( accX < midX - dx ) + { + if( !pressLeft ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press left, acc %f mid %f d %f", accX, midX, dx); + pressLeft = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_LEFT) ); + } + } + else + { + if( pressLeft ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release left, acc %f mid %f d %f", accX, midX, dx); + pressLeft = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) ); + } + } + if( accX < midX - dx*2 ) + midX = accX + dx*2; + + if( accX > midX + dx ) + { + if( !pressRight ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press right, acc %f mid %f d %f", accX, midX, dx); + pressRight = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_RIGHT) ); + } + } + else + { + if( pressRight ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release right, acc %f mid %f d %f", accX, midX, dx); + pressRight = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) ); + } + } + if( accX > midX + dx*2 ) + midX = accX - dx*2; + + if( accY < midY - dy ) + { + if( !pressUp ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press up, acc %f mid %f d %f", accY, midY, dy); + pressUp = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_DOWN) ); + } + } + else + { + if( pressUp ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release up, acc %f mid %f d %f", accY, midY, dy); + pressUp = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) ); + } + } + if( accY < midY - dy*2 ) + midY = accY + dy*2; + + if( accY > midY + dy ) + { + if( !pressDown ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press down, acc %f mid %f d %f", accY, midY, dy); + pressDown = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_UP) ); + } + } + else + { + if( pressDown ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release down, acc %f mid %f d %f", accY, midY, dy); + pressDown = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) ); + } + } + if( accY > midY + dy*2 ) + midY = accY - dy*2; + + if( accZ < midZ - dz ) + { + if( !pressL ) + { + pressL = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_ALT_LEFT) ); + } + } + else + { + if( pressL ) + { + pressL = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_ALT_LEFT) ); + } + } + if( accZ < midZ - dz*2 ) + midZ = accZ + dz*2; + + if( accZ > midZ + dz ) + { + if( !pressR ) + { + pressR = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_ALT_RIGHT) ); + } + } + else + { + if( pressR ) + { + pressR = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_ALT_RIGHT) ); + } + } + if( accZ > midZ + dz*2 ) + midZ = accZ - dz*2; + +} + +static int leftPressed = 0, rightPressed = 0, upPressed = 0, downPressed = 0; + +int processAndroidTrackball(int key, int action) +{ + SDL_keysym keysym; + + if( ! action && ( + key == KEYCODE_DPAD_UP || + key == KEYCODE_DPAD_DOWN || + key == KEYCODE_DPAD_LEFT || + key == KEYCODE_DPAD_RIGHT ) ) + return 1; + lastTrackballAction = SDL_GetTicks(); + + if( key == KEYCODE_DPAD_UP ) + { + if( downPressed ) + { + downPressed = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) ); + return 1; + } + if( !upPressed ) + { + upPressed = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); + } + else + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); + } + return 1; + } + + if( key == KEYCODE_DPAD_DOWN ) + { + if( upPressed ) + { + upPressed = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) ); + return 1; + } + if( !upPressed ) + { + downPressed = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); + } + else + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); + } + return 1; + } + + if( key == KEYCODE_DPAD_LEFT ) + { + if( rightPressed ) + { + rightPressed = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) ); + return 1; + } + if( !leftPressed ) + { + leftPressed = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); + } + else + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); + } + return 1; + } + + if( key == KEYCODE_DPAD_RIGHT ) + { + if( leftPressed ) + { + leftPressed = 0; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) ); + return 1; + } + if( !rightPressed ) + { + rightPressed = 1; + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); + } + else + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); + } + return 1; + } + + return 0; +} + +void SDL_ANDROID_processAndroidTrackballDampening() +{ + if( !TrackballDampening ) + return; + if( SDL_GetTicks() > TrackballDampening + lastTrackballAction ) + { + if( upPressed ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) ); + if( downPressed ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) ); + if( leftPressed ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) ); + if( rightPressed ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) ); + upPressed = 0; + downPressed = 0; + leftPressed = 0; + rightPressed = 0; + } +} + +int SDL_SYS_JoystickInit(void) +{ + SDL_numjoysticks = 0; + if( SDL_ANDROID_isJoystickUsed || isMultitouchUsed || SDL_ANDROID_isAccelerometerUsed ) + SDL_numjoysticks = 1; + //if( isMultitouchUsed ) + // SDL_numjoysticks = MAX_MULTITOUCH_POINTERS+1; + + return(SDL_numjoysticks); +} + +/* Function to get the device-dependent name of a joystick */ +const char *SDL_SYS_JoystickName(int index) +{ + return("Android accelerometer/multitouch sensor"); +} + +int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) +{ + joystick->nbuttons = 0; + joystick->nhats = 0; + joystick->nballs = 0; + if( joystick->index == 0 ) + { + joystick->naxes = 4; // Joystick plus accelerometer + if(isMultitouchUsed) + { + joystick->naxes = 4 + MAX_MULTITOUCH_POINTERS; // Joystick plus accelerometer, plus touch pressure/size + joystick->nbuttons = MAX_MULTITOUCH_POINTERS; + joystick->nballs = MAX_MULTITOUCH_POINTERS; + } + } + SDL_ANDROID_CurrentJoysticks[joystick->index] = joystick; + return(0); +} + +void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) +{ + return; +} + +/* Function to close a joystick after use */ +void SDL_SYS_JoystickClose(SDL_Joystick *joystick) +{ + SDL_ANDROID_CurrentJoysticks[joystick->index] = NULL; + return; +} + +/* Function to perform any system-specific joystick related cleanup */ +void SDL_SYS_JoystickQuit(void) +{ + int i; + SDL_ANDROID_CurrentJoysticks[0] = NULL; + 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); + SDL_ANDROID_MainThreadPushMouseMotion(currentMouseX + (currentMouseX % 2 ? -1 : 1), currentMouseY); // Force screen redraw + } + + SDL_mutexV(deferredTextMutex); +}; + +extern void SDL_ANDROID_MainThreadPushText( int ascii, int unicode ) +{ + int shiftRequired; + + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_MainThreadPushText(): %i %i", scancode, unicode); + 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 = unicode; + 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 ) + return; + + Uint32 ticks = SDL_GetTicks(); + + if( ticks - lastMoveMouseWithKeyboardUpdate < 20 ) // Update at 50 FPS max, or it will not work properlty on very fast devices + return; + + lastMoveMouseWithKeyboardUpdate = ticks; + + moveMouseWithKbSpeedX += moveMouseWithKbAccelX; + moveMouseWithKbSpeedY += moveMouseWithKbAccelY; + + moveMouseWithKbX += moveMouseWithKbSpeedX; + moveMouseWithKbY += moveMouseWithKbSpeedY; + SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); +}; + +extern void SDL_ANDROID_ProcessDeferredEvents() +{ + SDL_ANDROID_DeferredTextInput(); + ProcessDeferredMouseTap(); +}; + +void ANDROID_InitOSKeymap() +{ +#if (SDL_VERSION_ATLEAST(1,3,0)) + SDLKey defaultKeymap[SDL_NUM_SCANCODES]; + SDL_GetDefaultKeymap(defaultKeymap); + SDL_SetKeymap(0, defaultKeymap, SDL_NUM_SCANCODES); + + SDL_Touch touch; + memset( &touch, 0, sizeof(touch) ); + touch.x_min = touch.y_min = touch.pressure_min = 0.0f; + touch.pressure_max = 1000000; + touch.x_max = SDL_ANDROID_sWindowWidth; + touch.y_max = SDL_ANDROID_sWindowHeight; + + // These constants are hardcoded inside SDL_touch.c, which makes no sense for me. + touch.xres = touch.yres = 32768; + touch.native_xres = touch.native_yres = 32768.0f; + + touch.pressureres = 1; + touch.native_pressureres = 1.0f; + touch.id = 0; + + SDL_AddTouch(&touch, "Android touch screen"); +#endif +} + +JNIEXPORT jint JNICALL +JAVA_EXPORT_NAME(Settings_nativeGetKeymapKey) (JNIEnv* env, jobject thiz, jint code) +{ + if( code < 0 || code > KEYCODE_LAST ) + return SDL_KEY(UNKNOWN); + return SDL_android_keymap[code]; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetKeymapKey) (JNIEnv* env, jobject thiz, jint javakey, jint key) +{ + if( javakey < 0 || javakey > KEYCODE_LAST ) + return; + SDL_android_keymap[javakey] = key; +} + +JNIEXPORT jint JNICALL +JAVA_EXPORT_NAME(Settings_nativeGetKeymapKeyScreenKb) (JNIEnv* env, jobject thiz, jint keynum) +{ + if( keynum < 0 || keynum > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 + 4 ) + return SDL_KEY(UNKNOWN); + + if( keynum <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 ) + return SDL_ANDROID_GetScreenKeyboardButtonKey(keynum + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0); + + return SDL_KEY(UNKNOWN); +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetKeymapKeyScreenKb) (JNIEnv* env, jobject thiz, jint keynum, jint key) +{ + if( keynum < 0 || keynum > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 + 4 ) + return; + + if( keynum <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 ) + SDL_ANDROID_SetScreenKeyboardButtonKey(keynum + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, key); +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetScreenKbKeyUsed) (JNIEnv* env, jobject thiz, jint keynum, jint used) +{ + SDL_Rect rect = {0, 0, 0, 0}; + int key = -1; + if( keynum == 0 ) + key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD; + if( keynum == 1 ) + key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT; + if( keynum - 2 >= 0 && keynum - 2 <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 ) + key = keynum - 2 + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0; + + if( key >= 0 && !used ) + SDL_ANDROID_SetScreenKeyboardButtonPos(key, &rect); +} + +JNIEXPORT jint JNICALL +JAVA_EXPORT_NAME(Settings_nativeGetKeymapKeyMultitouchGesture) (JNIEnv* env, jobject thiz, jint keynum) +{ + if( keynum < 0 || keynum >= MAX_MULTITOUCH_GESTURES ) + return SDL_KEY(UNKNOWN); + return multitouchGestureKeycode[keynum]; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetKeymapKeyMultitouchGesture) (JNIEnv* env, jobject thiz, jint keynum, jint keycode) +{ + if( keynum < 0 || keynum >= MAX_MULTITOUCH_GESTURES ) + return; + multitouchGestureKeycode[keynum] = keycode; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetMultitouchGestureSensitivity) (JNIEnv* env, jobject thiz, jint sensitivity) +{ + multitouchGestureSensitivity = sensitivity; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetTouchscreenCalibration) (JNIEnv* env, jobject thiz, jint x1, jint y1, jint x2, jint y2) +{ + SDL_ANDROID_TouchscreenCalibrationX = x1; + SDL_ANDROID_TouchscreenCalibrationY = y1; + SDL_ANDROID_TouchscreenCalibrationWidth = x2 - x1; + SDL_ANDROID_TouchscreenCalibrationHeight = y2 - y1; +} + +static int ScreenKbRedefinedByUser = 0; + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetScreenKbKeyLayout) (JNIEnv* env, jobject thiz, jint keynum, jint x1, jint y1, jint x2, jint y2) +{ + SDL_Rect rect = {x1, y1, x2-x1, y2-y1}; + int key = -1; + if( keynum == 0 ) + key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD; + if( keynum == 1 ) + key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT; + if( keynum - 2 >= 0 && keynum - 2 <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 ) + key = keynum - 2 + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0; + + if( key >= 0 ) + { + ScreenKbRedefinedByUser = 1; + SDL_ANDROID_SetScreenKeyboardButtonPos(key, &rect); + } +} + +int SDL_ANDROID_GetScreenKeyboardRedefinedByUser() +{ + return ScreenKbRedefinedByUser; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeInitKeymap) ( JNIEnv* env, jobject thiz ) +{ + SDL_android_init_keymap(SDL_android_keymap); +} 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 deleted file mode 120000 index 26a72c68d..000000000 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/video/android/SDL_androidinput.h \ No newline at end of file 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 new file mode 100644 index 000000000..b7e813d81 --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.h @@ -0,0 +1,206 @@ +/* + 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 +*/ +#ifndef _SDL_ANDROIDINPUT_H_ +#define _SDL_ANDROIDINPUT_H_ + +#include "SDL_config.h" + +#include "SDL_version.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "SDL_events.h" +#if (SDL_VERSION_ATLEAST(1,3,0)) +#include "../../events/SDL_events_c.h" +#include "../../events/SDL_keyboard_c.h" +#include "../../events/SDL_mouse_c.h" +#include "SDL_keycode.h" +#include "SDL_scancode.h" +//#include "SDL_compat.h" +#else +#include "SDL_keysym.h" +#include "../../events/SDL_events_c.h" +#endif +#include "SDL_joystick.h" +#include "../../joystick/SDL_sysjoystick.h" +#include "../../joystick/SDL_joystick_c.h" + +#include "../SDL_sysvideo.h" +#include "SDL_androidvideo.h" +#include "javakeycodes.h" + +/* JNI-C++ wrapper stuff */ + +// Special key to signal that key should be handled by Java internally, such as Volume Up/Down keys +#define SDLK_NO_REMAP 512 +#define SDL_SCANCODE_NO_REMAP SDLK_NO_REMAP + +#if SDL_VERSION_ATLEAST(1,3,0) + +#define SDL_KEY2(X) SDL_SCANCODE_ ## X +#define SDL_KEY(X) SDL_KEY2(X) +typedef SDL_Scancode SDL_scancode; +typedef SDL_Keycode SDLKey; +typedef SDL_Keysym SDL_keysym; + +#else + +#define SDL_KEY2(X) SDLK_ ## X +#define SDL_KEY(X) SDL_KEY2(X) + +// Randomly redefining SDL 1.3 scancodes to SDL 1.2 keycodes +#define KP_0 KP0 +#define KP_1 KP1 +#define KP_2 KP2 +#define KP_3 KP3 +#define KP_4 KP4 +#define KP_5 KP5 +#define KP_6 KP6 +#define KP_7 KP7 +#define KP_8 KP8 +#define KP_9 KP9 +#define NUMLOCKCLEAR NUMLOCK +#define GRAVE DOLLAR +#define APOSTROPHE QUOTE +#define LGUI LMETA +#define RGUI RMETA +#define SCROLLLOCK SCROLLOCK +// Overkill haha +#define A a +#define B b +#define C c +#define D d +#define E e +#define F f +#define G g +#define H h +#define I i +#define J j +#define K k +#define L l +#define M m +#define N n +#define O o +#define P p +#define Q q +#define R r +#define S s +#define T t +#define U u +#define V v +#define W w +#define X x +#define Y y +#define Z z + +typedef SDLKey SDL_scancode; +#define SDL_GetKeyboardState SDL_GetKeyState + +#endif + +#define SDL_KEY_VAL(X) X + +enum MOUSE_ACTION { MOUSE_DOWN = 0, MOUSE_UP = 1, MOUSE_MOVE = 2, MOUSE_HOVER = 3 }; + +extern int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointerId); +extern int SDL_ANDROID_isTouchscreenKeyboardUsed; + +#ifndef SDL_ANDROID_KEYCODE_0 +#define SDL_ANDROID_KEYCODE_0 RETURN +#endif +#ifndef SDL_ANDROID_KEYCODE_1 +#define SDL_ANDROID_KEYCODE_1 END +#endif +#ifndef SDL_ANDROID_KEYCODE_2 +#define SDL_ANDROID_KEYCODE_2 NO_REMAP +#endif +#ifndef SDL_ANDROID_KEYCODE_3 +#define SDL_ANDROID_KEYCODE_3 NO_REMAP +#endif +#ifndef SDL_ANDROID_KEYCODE_4 +#define SDL_ANDROID_KEYCODE_4 LCTRL +#endif +#ifndef SDL_ANDROID_KEYCODE_5 +#define SDL_ANDROID_KEYCODE_5 ESCAPE +#endif +#ifndef SDL_ANDROID_KEYCODE_6 +#define SDL_ANDROID_KEYCODE_6 RSHIFT +#endif +#ifndef SDL_ANDROID_KEYCODE_7 +#define SDL_ANDROID_KEYCODE_7 SDL_ANDROID_KEYCODE_1 +#endif +#ifndef SDL_ANDROID_KEYCODE_8 +#define SDL_ANDROID_KEYCODE_8 LALT +#endif +#ifndef SDL_ANDROID_KEYCODE_9 +#define SDL_ANDROID_KEYCODE_9 RALT +#endif + +// Touchscreen keyboard keys + zoom and rotate keycodes +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_0 +#define SDL_ANDROID_SCREENKB_KEYCODE_0 SDL_ANDROID_KEYCODE_0 +#endif +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_1 +#define SDL_ANDROID_SCREENKB_KEYCODE_1 SDL_ANDROID_KEYCODE_1 +#endif +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_2 +#define SDL_ANDROID_SCREENKB_KEYCODE_2 PAGEUP +#endif +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_3 +#define SDL_ANDROID_SCREENKB_KEYCODE_3 PAGEDOWN +#endif +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_4 +#define SDL_ANDROID_SCREENKB_KEYCODE_4 SDL_ANDROID_KEYCODE_6 +#endif +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_5 +#define SDL_ANDROID_SCREENKB_KEYCODE_5 SDL_ANDROID_KEYCODE_7 +#endif +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_6 +#define SDL_ANDROID_SCREENKB_KEYCODE_6 SDL_ANDROID_KEYCODE_4 +#endif +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_7 +#define SDL_ANDROID_SCREENKB_KEYCODE_7 SDL_ANDROID_KEYCODE_5 +#endif +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_8 +#define SDL_ANDROID_SCREENKB_KEYCODE_8 SDL_ANDROID_KEYCODE_8 +#endif +#ifndef SDL_ANDROID_SCREENKB_KEYCODE_9 +#define SDL_ANDROID_SCREENKB_KEYCODE_9 SDL_ANDROID_KEYCODE_9 +#endif + +// Queue events to main thread +extern void SDL_ANDROID_MainThreadPushMouseMotion(int x, int y); +extern void SDL_ANDROID_MainThreadPushMouseButton(int pressed, int button); +extern void SDL_ANDROID_MainThreadPushKeyboardKey(int pressed, SDL_scancode key); +extern void SDL_ANDROID_MainThreadPushMultitouchButton(int id, int pressed, int x, int y, int force); // SDL 1.3 only +extern void SDL_ANDROID_MainThreadPushMultitouchMotion(int id, int x, int y, int force); // SDL 1.3 only +extern void SDL_ANDROID_MainThreadPushJoystickAxis(int joy, int axis, int value); +extern void SDL_ANDROID_MainThreadPushJoystickButton(int joy, int button, int pressed); +extern void SDL_ANDROID_MainThreadPushJoystickBall(int joy, int ball, int x, int y); +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); +#endif diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c deleted file mode 120000 index e303fe70c..000000000 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/video/android/SDL_androidvideo.c \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c new file mode 100644 index 000000000..1416e064b --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.c @@ -0,0 +1,402 @@ +/* + 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 +#include +#include // for memset() + +#include "SDL_config.h" +#include "SDL_version.h" + +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include "SDL_android.h" +#include "../SDL_sysvideo.h" +#include "../SDL_pixels_c.h" +#include "../../events/SDL_events_c.h" + +#include "../SDL_sysvideo.h" +#include "SDL_androidvideo.h" +#include "jniwrapperstuff.h" + + +// The device screen dimensions to draw on +int SDL_ANDROID_sWindowWidth = 0; +int SDL_ANDROID_sWindowHeight = 0; + +int SDL_ANDROID_sRealWindowWidth = 0; +int SDL_ANDROID_sRealWindowHeight = 0; + +SDL_Rect SDL_ANDROID_ForceClearScreenRect = { 0, 0, 0, 0 }; + +// Extremely wicked JNI environment to call Java functions from C code +static JNIEnv* JavaEnv = NULL; +static jclass JavaRendererClass = NULL; +static jobject JavaRenderer = NULL; +static jmethodID JavaSwapBuffers = NULL; +static jmethodID JavaShowScreenKeyboard = NULL; +static jmethodID JavaToggleScreenKeyboardWithoutTextInput = NULL; +static jmethodID JavaGetAdvertisementParams = NULL; +static jmethodID JavaSetAdvertisementVisible = NULL; +static jmethodID JavaSetAdvertisementPosition = NULL; +static jmethodID JavaRequestNewAdvertisement = NULL; +static int glContextLost = 0; +static int showScreenKeyboardDeferred = 0; +static const char * showScreenKeyboardOldText = ""; +static int showScreenKeyboardSendBackspace = 0; +int SDL_ANDROID_VideoLinearFilter = 0; +int SDL_ANDROID_VideoMultithreaded = 0; +int SDL_ANDROID_VideoForceSoftwareMode = 0; +int SDL_ANDROID_CompatibilityHacks = 0; +int SDL_ANDROID_BYTESPERPIXEL = 2; +int SDL_ANDROID_BITSPERPIXEL = 16; +int SDL_ANDROID_UseGles2 = 0; +int SDL_ANDROID_ShowMouseCursor = 0; + +static void appPutToBackgroundCallbackDefault(void) +{ + SDL_ANDROID_PauseAudioPlayback(); +} +static void appRestoredCallbackDefault(void) +{ + SDL_ANDROID_ResumeAudioPlayback(); +} + +static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appPutToBackgroundCallback = appPutToBackgroundCallbackDefault; +static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appRestoredCallback = appRestoredCallbackDefault; +static SDL_ANDROID_ApplicationPutToBackgroundCallback_t openALPutToBackgroundCallback = NULL; +static SDL_ANDROID_ApplicationPutToBackgroundCallback_t openALRestoredCallback = NULL; + +int SDL_ANDROID_CallJavaSwapBuffers() +{ + if( !glContextLost ) + { + SDL_ANDROID_drawTouchscreenKeyboard(); + } + + // Clear part of screen not used by SDL - on Android the screen contains garbage after each frame + if( SDL_ANDROID_ForceClearScreenRect.w != 0 && SDL_ANDROID_ForceClearScreenRect.h != 0 ) + { + glPushMatrix(); + glLoadIdentity(); + glOrthox( 0, (SDL_ANDROID_sRealWindowWidth) * 0x10000, SDL_ANDROID_sRealWindowHeight * 0x10000, 0, 0, 1 * 0x10000 ); + glColor4x(0, 0, 0, 0x10000); + glEnableClientState(GL_VERTEX_ARRAY); + + GLshort vertices[] = { SDL_ANDROID_ForceClearScreenRect.x, SDL_ANDROID_ForceClearScreenRect.y, + SDL_ANDROID_ForceClearScreenRect.x + SDL_ANDROID_ForceClearScreenRect.w, SDL_ANDROID_ForceClearScreenRect.y, + SDL_ANDROID_ForceClearScreenRect.x + SDL_ANDROID_ForceClearScreenRect.w, SDL_ANDROID_ForceClearScreenRect.y + SDL_ANDROID_ForceClearScreenRect.h, + SDL_ANDROID_ForceClearScreenRect.x, SDL_ANDROID_ForceClearScreenRect.y + SDL_ANDROID_ForceClearScreenRect.h }; + glVertexPointer(2, GL_SHORT, 0, vertices); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glDisableClientState(GL_VERTEX_ARRAY); + glPopMatrix(); + } + + if( ! (*JavaEnv)->CallIntMethod( JavaEnv, JavaRenderer, JavaSwapBuffers ) ) + return 0; + if( glContextLost ) + { + glContextLost = 0; + __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context recreated, refreshing textures"); + SDL_ANDROID_VideoContextRecreated(); + appRestoredCallback(); + if(openALRestoredCallback) + openALRestoredCallback(); + } + if( showScreenKeyboardDeferred ) + { + showScreenKeyboardDeferred = 0; + (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaShowScreenKeyboard, (*JavaEnv)->NewStringUTF(JavaEnv, showScreenKeyboardOldText), showScreenKeyboardSendBackspace ); + } + SDL_ANDROID_ProcessDeferredEvents(); + return 1; +} + + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoRenderer_nativeResize) ( JNIEnv* env, jobject thiz, jint w, jint h, jint keepRatio ) +{ + if( SDL_ANDROID_sWindowWidth == 0 ) + { + SDL_ANDROID_sRealWindowWidth = w; + SDL_ANDROID_sRealWindowHeight = h; +#if SDL_VERSION_ATLEAST(1,3,0) + // Not supported in SDL 1.3 +#else + if( keepRatio ) + { + // TODO: tweak that parameters when app calls SetVideoMode(), not here - app may request something else than 640x480, it's okay for most apps though + SDL_ANDROID_sWindowWidth = (SDL_ANDROID_sFakeWindowWidth*h)/SDL_ANDROID_sFakeWindowHeight; + SDL_ANDROID_sWindowHeight = h; + SDL_ANDROID_ForceClearScreenRect.x = SDL_ANDROID_sWindowWidth; + SDL_ANDROID_ForceClearScreenRect.y = 0; + SDL_ANDROID_ForceClearScreenRect.w = w - SDL_ANDROID_sWindowWidth; + SDL_ANDROID_ForceClearScreenRect.h = h; + + if(SDL_ANDROID_sWindowWidth >= w) + { + SDL_ANDROID_sWindowWidth = w; + SDL_ANDROID_sWindowHeight = (SDL_ANDROID_sFakeWindowHeight*w)/SDL_ANDROID_sFakeWindowWidth; + SDL_ANDROID_ForceClearScreenRect.x = 0; + SDL_ANDROID_ForceClearScreenRect.y = SDL_ANDROID_sWindowHeight; + SDL_ANDROID_ForceClearScreenRect.w = w; + SDL_ANDROID_ForceClearScreenRect.h = SDL_ANDROID_sWindowHeight - h; // OpenGL vertical coord is inverted + } + } + else +#endif + { + SDL_ANDROID_ForceClearScreenRect.w = 0; + SDL_ANDROID_ForceClearScreenRect.h = 0; + SDL_ANDROID_ForceClearScreenRect.x = 0; + SDL_ANDROID_ForceClearScreenRect.y = 0; + SDL_ANDROID_sWindowWidth = w; + SDL_ANDROID_sWindowHeight = h; + } + __android_log_print(ANDROID_LOG_INFO, "libSDL", "Physical screen resolution is %dx%d, virtual screen %dx%d", w, h, SDL_ANDROID_sWindowWidth, SDL_ANDROID_sWindowHeight ); + SDL_ANDROID_TouchscreenCalibrationWidth = SDL_ANDROID_sWindowWidth; + SDL_ANDROID_TouchscreenCalibrationHeight = SDL_ANDROID_sWindowHeight; + } +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoRenderer_nativeDone) ( JNIEnv* env, jobject thiz ) +{ + __android_log_print(ANDROID_LOG_INFO, "libSDL", "quitting..."); +#if SDL_VERSION_ATLEAST(1,3,0) + SDL_SendQuit(); +#else + SDL_PrivateQuit(); +#endif + __android_log_print(ANDROID_LOG_INFO, "libSDL", "quit OK"); +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextLost) ( JNIEnv* env, jobject thiz ) +{ + __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context lost, waiting for new OpenGL context"); + glContextLost = 1; + appPutToBackgroundCallback(); + if(openALPutToBackgroundCallback) + openALPutToBackgroundCallback(); + + SDL_ANDROID_VideoContextLost(); +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextLostAsyncEvent) ( JNIEnv* env, jobject thiz ) +{ + __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context lost - sending SDL_ACTIVEEVENT"); + SDL_ANDROID_MainThreadPushAppActive(0); +} + + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextRecreated) ( JNIEnv* env, jobject thiz ) +{ + __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context recreated, sending SDL_ACTIVEEVENT"); +#if SDL_VERSION_ATLEAST(1,3,0) + //if( ANDROID_CurrentWindow ) + // SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_RESTORED, 0, 0); +#else + SDL_PrivateAppActive(1, SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); +#endif +} + +int SDL_ANDROID_ToggleScreenKeyboardWithoutTextInput(void) +{ + (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaToggleScreenKeyboardWithoutTextInput ); + return 1; +} + +volatile static textInputFinished = 0; +void SDL_ANDROID_TextInputFinished() +{ + textInputFinished = 1; +}; + +#if SDL_VERSION_ATLEAST(1,3,0) +#else +extern int SDL_Flip(SDL_Surface *screen); +extern SDL_Surface *SDL_GetVideoSurface(void); +#endif + +void SDL_ANDROID_CallJavaShowScreenKeyboard(const char * oldText, char * outBuf, int outBufLen) +{ + if( !outBuf ) + { + showScreenKeyboardDeferred = 1; + showScreenKeyboardOldText = oldText; + showScreenKeyboardSendBackspace = 1; + // Move mouse by 1 pixel to force screen update + int x, y; + SDL_GetMouseState( &x, &y ); + SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y); + } + else + { + textInputFinished = 0; + SDL_ANDROID_TextInputInit(outBuf, outBufLen); + + if( SDL_ANDROID_VideoMultithreaded ) + { +#if SDL_VERSION_ATLEAST(1,3,0) +#else + // Dirty hack: we may call (*JavaEnv)->CallVoidMethod(...) only from video thread + showScreenKeyboardDeferred = 1; + showScreenKeyboardOldText = oldText; + showScreenKeyboardSendBackspace = 0; + SDL_Flip(SDL_GetVideoSurface()); +#endif + } + else + (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaShowScreenKeyboard, (*JavaEnv)->NewStringUTF(JavaEnv, oldText), 0 ); + + while( !textInputFinished ) + SDL_Delay(100); + textInputFinished = 0; + } +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoRenderer_nativeInitJavaCallbacks) ( JNIEnv* env, jobject thiz ) +{ + JavaEnv = env; + JavaRenderer = (*JavaEnv)->NewGlobalRef( JavaEnv, thiz ); + + JavaRendererClass = (*JavaEnv)->GetObjectClass(JavaEnv, thiz); + JavaSwapBuffers = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "swapBuffers", "()I"); + JavaShowScreenKeyboard = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "showScreenKeyboard", "(Ljava/lang/String;I)V"); + JavaToggleScreenKeyboardWithoutTextInput = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "showScreenKeyboardWithoutTextInputField", "()V"); + // TODO: implement it + JavaGetAdvertisementParams = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "getAdvertisementParams", "([I)V"); + JavaSetAdvertisementVisible = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "setAdvertisementVisible", "(I)V"); + JavaSetAdvertisementPosition = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "setAdvertisementPosition", "(II)V"); + JavaRequestNewAdvertisement = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "requestNewAdvertisement", "()V"); + + ANDROID_InitOSKeymap(); +} + +int SDL_ANDROID_SetApplicationPutToBackgroundCallback( + SDL_ANDROID_ApplicationPutToBackgroundCallback_t appPutToBackground, + SDL_ANDROID_ApplicationPutToBackgroundCallback_t appRestored ) +{ + appPutToBackgroundCallback = appPutToBackgroundCallbackDefault; + appRestoredCallback = appRestoredCallbackDefault; + + if( appPutToBackground ) + appPutToBackgroundCallback = appPutToBackground; + + if( appRestoredCallback ) + appRestoredCallback = appRestored; +} + +extern int SDL_ANDROID_SetOpenALPutToBackgroundCallback( + SDL_ANDROID_ApplicationPutToBackgroundCallback_t PutToBackground, + SDL_ANDROID_ApplicationPutToBackgroundCallback_t Restored ); + +int SDL_ANDROID_SetOpenALPutToBackgroundCallback( + SDL_ANDROID_ApplicationPutToBackgroundCallback_t PutToBackground, + SDL_ANDROID_ApplicationPutToBackgroundCallback_t Restored ) +{ + openALPutToBackgroundCallback = PutToBackground; + openALRestoredCallback = Restored; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetVideoLinearFilter) (JNIEnv* env, jobject thiz) +{ + SDL_ANDROID_VideoLinearFilter = 1; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetVideoMultithreaded) (JNIEnv* env, jobject thiz) +{ + SDL_ANDROID_VideoMultithreaded = 1; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetVideoForceSoftwareMode) (JNIEnv* env, jobject thiz) +{ + SDL_ANDROID_VideoForceSoftwareMode = 1; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetCompatibilityHacks) (JNIEnv* env, jobject thiz) +{ + SDL_ANDROID_CompatibilityHacks = 1; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetVideoDepth) (JNIEnv* env, jobject thiz, jint bpp, jint UseGles2) +{ + SDL_ANDROID_BITSPERPIXEL = bpp; + SDL_ANDROID_BYTESPERPIXEL = SDL_ANDROID_BITSPERPIXEL / 8; + SDL_ANDROID_UseGles2 = UseGles2; +} + +int SDLCALL SDL_ANDROID_GetAdvertisementParams(int * visible, SDL_Rect * position) +{ + jint arr[5]; + jintArray elemArr = (*JavaEnv)->NewIntArray(JavaEnv, 5); + if (elemArr == NULL) + return 0; + (*JavaEnv)->SetIntArrayRegion(JavaEnv, elemArr, 0, 5, arr); + (*JavaEnv)->CallVoidMethod(JavaEnv, JavaRenderer, JavaGetAdvertisementParams, elemArr); + (*JavaEnv)->GetIntArrayRegion(JavaEnv, elemArr, 0, 5, arr); + (*JavaEnv)->DeleteLocalRef(JavaEnv, elemArr); + if(visible) + *visible = arr[0]; + if(position) + { + position->x = arr[1]; + position->y = arr[2]; + position->w = arr[3]; + position->h = arr[4]; + } + return 1; +} +int SDLCALL SDL_ANDROID_SetAdvertisementVisible(int visible) +{ + (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementVisible, (jint)visible ); + return 1; +} +int SDLCALL SDL_ANDROID_SetAdvertisementPosition(int left, int top) +{ + (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementPosition, (jint)left, (jint)top ); + return 1; +} +int SDLCALL SDL_ANDROID_RequestNewAdvertisement(void) +{ + (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestNewAdvertisement ); + return 1; +} diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h deleted file mode 120000 index a12012da0..000000000 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/video/android/SDL_androidvideo.h \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h new file mode 100644 index 000000000..c24bc205d --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidvideo.h @@ -0,0 +1,86 @@ +/* + 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 +*/ +#ifndef _SDL_androidvideo_h +#define _SDL_androidvideo_h + +#include "SDL_version.h" +#include "SDL_config.h" +#include "SDL_video.h" +#include "SDL_joystick.h" +#include "SDL_events.h" + +enum ScreenZoom { ZOOM_NONE = 0, ZOOM_MAGNIFIER = 1, ZOOM_SCREEN_TRANSFORM = 2, ZOOM_FULLSCREEN_MAGNIFIER = 3 }; + +extern int SDL_ANDROID_sWindowWidth; +extern int SDL_ANDROID_sWindowHeight; +extern int SDL_ANDROID_sRealWindowWidth; +extern int SDL_ANDROID_sRealWindowHeight; +extern int SDL_ANDROID_sFakeWindowWidth; // SDL 1.2 only +extern int SDL_ANDROID_sFakeWindowHeight; // SDL 1.2 only +extern int SDL_ANDROID_TouchscreenCalibrationWidth; +extern int SDL_ANDROID_TouchscreenCalibrationHeight; +extern int SDL_ANDROID_TouchscreenCalibrationX; +extern int SDL_ANDROID_TouchscreenCalibrationY; +extern int SDL_ANDROID_VideoLinearFilter; +extern int SDL_ANDROID_VideoMultithreaded; +extern int SDL_ANDROID_VideoForceSoftwareMode; +extern int SDL_ANDROID_CompatibilityHacks; +extern int SDL_ANDROID_ShowMouseCursor; +extern int SDL_ANDROID_UseGles2; +extern int SDL_ANDROID_BYTESPERPIXEL; +extern int SDL_ANDROID_BITSPERPIXEL; +extern void SDL_ANDROID_TextInputInit(char * buffer, int len); +extern void SDL_ANDROID_TextInputFinished(); +extern SDL_Surface *SDL_CurrentVideoSurface; +extern SDL_Rect SDL_ANDROID_ForceClearScreenRect; +extern int SDL_ANDROID_ShowScreenUnderFinger; +extern SDL_Rect SDL_ANDROID_ShowScreenUnderFingerRect, SDL_ANDROID_ShowScreenUnderFingerRectSrc; +extern int SDL_ANDROID_CallJavaSwapBuffers(); +extern void SDL_ANDROID_CallJavaShowScreenKeyboard(const char * oldText, char * outBuf, int outBufLen); +extern int SDL_ANDROID_drawTouchscreenKeyboard(); +extern void SDL_ANDROID_VideoContextLost(); +extern void SDL_ANDROID_VideoContextRecreated(); +extern void SDL_ANDROID_processAndroidTrackballDampening(); +extern void SDL_ANDROID_processMoveMouseWithKeyboard(); +extern int SDL_ANDROID_InsideVideoThread(); +extern void SDL_ANDROID_initFakeStdout(); +extern SDL_VideoDevice *ANDROID_CreateDevice_1_3(int devindex); +extern void SDL_ANDROID_ProcessDeferredEvents(); +extern void SDL_ANDROID_WarpMouse(int x, int y); +extern void SDL_ANDROID_DrawMouseCursor(int x, int y, int size, int alpha); +extern void SDL_ANDROID_DrawMouseCursorIfNeeded(); +extern void SDL_ANDROID_CallJavaTogglePlainAndroidSoftKeyboardInput(); + + +#if SDL_VERSION_ATLEAST(1,3,0) +extern SDL_Window * ANDROID_CurrentWindow; +#endif + +// Exports from SDL_androidinput.c - SDL_androidinput.h is too encumbered +enum { MAX_MULTITOUCH_POINTERS = 16 }; +extern void ANDROID_InitOSKeymap(); +extern int SDL_ANDROID_isJoystickUsed; +// Events have to be sent only from main thread from PumpEvents(), so we'll buffer them here +extern void SDL_ANDROID_PumpEvents(); + + +#endif /* _SDL_androidvideo_h */ diff --git a/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c b/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c deleted file mode 120000 index b20d33e3b..000000000 --- a/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c b/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c new file mode 100644 index 000000000..ca94dd998 --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c @@ -0,0 +1,1064 @@ +/* + 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 +#include +#include + +#include "SDL_config.h" + +#include "SDL_version.h" + +//#include "SDL_opengles.h" +#include "SDL_screenkeyboard.h" +#include "../SDL_sysvideo.h" +#include "SDL_androidvideo.h" +#include "SDL_androidinput.h" +#include "jniwrapperstuff.h" + +// #include "touchscreentheme.h" // Not used yet + +// TODO: this code is a HUGE MESS + +#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) +#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) + +enum { MAX_BUTTONS = SDL_ANDROID_SCREENKEYBOARD_BUTTON_NUM-1, MAX_BUTTONS_AUTOFIRE = 2, BUTTON_TEXT_INPUT = SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT-1, BUTTON_ARROWS = MAX_BUTTONS } ; // Max amount of custom buttons + +int SDL_ANDROID_isTouchscreenKeyboardUsed = 0; +static int touchscreenKeyboardTheme = 0; +static int touchscreenKeyboardShown = 1; +static int AutoFireButtonsNum = 0; +static int buttonsize = 1; +static int buttonDrawSize = 1; +static int transparency = 128; + +static SDL_Rect arrows, arrowsExtended, buttons[MAX_BUTTONS], buttonsAutoFireRect[MAX_BUTTONS_AUTOFIRE]; +static SDL_Rect arrowsDraw, buttonsDraw[MAX_BUTTONS]; +static SDLKey buttonKeysyms[MAX_BUTTONS] = { +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_0)), +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_1)), +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_2)), +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_3)), +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_4)), +SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_5)), +0 +}; + +enum { ARROW_LEFT = 1, ARROW_RIGHT = 2, ARROW_UP = 4, ARROW_DOWN = 8 }; +static int oldArrows = 0; +static int ButtonAutoFire[MAX_BUTTONS_AUTOFIRE]; +static int ButtonAutoFireX[MAX_BUTTONS_AUTOFIRE*2]; +static int ButtonAutoFireRot[MAX_BUTTONS_AUTOFIRE]; +static int ButtonAutoFireDecay[MAX_BUTTONS_AUTOFIRE]; + +static int pointerInButtonRect[MAX_BUTTONS + 1]; + +typedef struct +{ + GLuint id; + GLfloat w; + GLfloat h; +} GLTexture_t; + +static GLTexture_t arrowImages[5]; +static GLTexture_t buttonAutoFireImages[MAX_BUTTONS_AUTOFIRE*2]; +static GLTexture_t buttonImages[MAX_BUTTONS*2]; +static GLTexture_t mousePointer; +enum { MOUSE_POINTER_W = 32, MOUSE_POINTER_H = 32, MOUSE_POINTER_X = 5, MOUSE_POINTER_Y = 7 }; // X and Y are offsets of the pointer tip + +static int sunTheme = 0; +static int joystickTouchPoints[2]; + +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 ); +} + +static struct ScreenKbGlState_t +{ + GLboolean texture2d; + GLuint textureId; + GLfloat color[4]; + GLint texEnvMode; + GLboolean blend; + GLenum blend1, blend2; + GLint texFilter1, texFilter2; +} +oldGlState; + +static inline void beginDrawingTex() +{ + // Save OpenGL state + glGetError(); // Clear error flag + // This code does not work on 1.6 emulator, and on some older devices + // However GLES 1.1 spec defines all theese values, so it's a device fault for not implementing them + oldGlState.texture2d = glIsEnabled(GL_TEXTURE_2D); + glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldGlState.textureId); + glGetFloatv(GL_CURRENT_COLOR, &(oldGlState.color[0])); + glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &oldGlState.texEnvMode); + oldGlState.blend = glIsEnabled(GL_BLEND); + glGetIntegerv(GL_BLEND_SRC, &oldGlState.blend1); + glGetIntegerv(GL_BLEND_DST, &oldGlState.blend2); + glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &oldGlState.texFilter1); + glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &oldGlState.texFilter2); + // It's very unlikely that some app will use GL_TEXTURE_CROP_RECT_OES, so just skip it + if( glGetError() != GL_NO_ERROR ) + { + // Make the video somehow work on emulator + oldGlState.texture2d = GL_FALSE; + oldGlState.textureId = 0; + oldGlState.texEnvMode = GL_MODULATE; + oldGlState.blend = GL_FALSE; + oldGlState.blend1 = GL_SRC_ALPHA; + oldGlState.blend2 = GL_ONE_MINUS_SRC_ALPHA; + oldGlState.texFilter1 = GL_NEAREST; + oldGlState.texFilter2 = GL_NEAREST; + } + + glEnable(GL_TEXTURE_2D); +} + +static inline void endDrawingTex() +{ + // Restore OpenGL state + if( oldGlState.texture2d == GL_FALSE ) + glDisable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, oldGlState.textureId); + glColor4f(oldGlState.color[0], oldGlState.color[1], oldGlState.color[2], oldGlState.color[3]); + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, oldGlState.texEnvMode); + if( oldGlState.blend == GL_FALSE ) + glDisable(GL_BLEND); + glBlendFunc(oldGlState.blend1, oldGlState.blend2); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, oldGlState.texFilter1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, oldGlState.texFilter2); + + /* + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + */ +} + +static inline void drawCharTexFlip(GLTexture_t * tex, SDL_Rect * src, SDL_Rect * dest, int flipX, int flipY, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + GLint cropRect[4]; + + if( !dest->h || !dest->w ) + return; + + glBindTexture(GL_TEXTURE_2D, tex->id); + + glColor4x(r * 0x100, g * 0x100, b * 0x100, a * 0x100 ); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if( SDL_ANDROID_VideoLinearFilter ) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + if(src) + { + cropRect[0] = src->x; + cropRect[1] = tex->h - src->y; + cropRect[2] = src->w; + cropRect[3] = -src->h; + } + else + { + cropRect[0] = 0; + cropRect[1] = tex->h; + cropRect[2] = tex->w; + cropRect[3] = -tex->h; + } + if(flipX) + { + cropRect[0] += cropRect[2]; + cropRect[2] = -cropRect[2]; + } + if(flipY) + { + cropRect[1] += cropRect[3]; + cropRect[3] = -cropRect[3]; + } + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); + glDrawTexiOES(dest->x, SDL_ANDROID_sWindowHeight - dest->y - dest->h, 0, dest->w, dest->h); +} + +static inline void drawCharTex(GLTexture_t * tex, SDL_Rect * src, SDL_Rect * dest, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + drawCharTexFlip(tex, src, dest, 0, 0, r, g, b, a); +} + +static void drawTouchscreenKeyboardLegacy() +{ + int i; + int blendFactor; + + blendFactor = ( SDL_GetKeyboardState(NULL)[SDL_KEY(LEFT)] ? 1 : 0 ) + + ( SDL_GetKeyboardState(NULL)[SDL_KEY(RIGHT)] ? 1 : 0 ) + + ( SDL_GetKeyboardState(NULL)[SDL_KEY(UP)] ? 1 : 0 ) + + ( SDL_GetKeyboardState(NULL)[SDL_KEY(DOWN)] ? 1 : 0 ); + if( blendFactor == 0 ) + drawCharTex( &arrowImages[0], NULL, &arrowsDraw, 255, 255, 255, transparency ); + else + { + if( SDL_GetKeyboardState(NULL)[SDL_KEY(LEFT)] ) + drawCharTex( &arrowImages[1], NULL, &arrowsDraw, 255, 255, 255, transparency / blendFactor ); + if( SDL_GetKeyboardState(NULL)[SDL_KEY(RIGHT)] ) + drawCharTex( &arrowImages[2], NULL, &arrowsDraw, 255, 255, 255, transparency / blendFactor ); + if( SDL_GetKeyboardState(NULL)[SDL_KEY(UP)] ) + drawCharTex( &arrowImages[3], NULL, &arrowsDraw, 255, 255, 255, transparency / blendFactor ); + if( SDL_GetKeyboardState(NULL)[SDL_KEY(DOWN)] ) + drawCharTex( &arrowImages[4], NULL, &arrowsDraw, 255, 255, 255, transparency / blendFactor ); + } + + for( i = 0; i < MAX_BUTTONS; i++ ) + { + if( ! buttons[i].h || ! buttons[i].w ) + continue; + if( i < AutoFireButtonsNum ) + { + if( ButtonAutoFire[i] == 1 && SDL_GetTicks() - ButtonAutoFireDecay[i] > 1000 ) + { + ButtonAutoFire[i] = 0; + } + if( ! ButtonAutoFire[i] && SDL_GetTicks() - ButtonAutoFireDecay[i] > 300 ) + { + if( ButtonAutoFireX[i*2] > 0 ) + ButtonAutoFireX[i*2] --; + if( ButtonAutoFireX[i*2+1] > 0 ) + ButtonAutoFireX[i*2+1] --; + ButtonAutoFireDecay[i] = SDL_GetTicks(); + } + } + + if( i < AutoFireButtonsNum && ! ButtonAutoFire[i] && + ( ButtonAutoFireX[i*2] > 0 || ButtonAutoFireX[i*2+1] > 0 ) ) + { + int pos1src = buttonImages[i*2+1].w / 2 - ButtonAutoFireX[i*2]; + int pos1dst = buttonsDraw[i].w * pos1src / buttonImages[i*2+1].w; + int pos2src = buttonImages[i*2+1].w - ( buttonImages[i*2+1].w / 2 - ButtonAutoFireX[i*2+1] ); + int pos2dst = buttonsDraw[i].w * pos2src / buttonImages[i*2+1].w; + + SDL_Rect autoFireCrop = { 0, 0, pos1src, buttonImages[i*2+1].h }; + SDL_Rect autoFireDest = buttonsDraw[i]; + autoFireDest.w = pos1dst; + + drawCharTex( &buttonImages[i*2+1], + &autoFireCrop, &autoFireDest, 255, 255, 255, transparency ); + + autoFireCrop.x = pos2src; + autoFireCrop.w = buttonImages[i*2+1].w - pos2src; + autoFireDest.x = buttonsDraw[i].x + pos2dst; + autoFireDest.w = buttonsDraw[i].w - pos2dst; + + drawCharTex( &buttonImages[i*2+1], + &autoFireCrop, &autoFireDest, 255, 255, 255, transparency ); + + autoFireCrop.x = pos1src; + autoFireCrop.w = pos2src - pos1src; + autoFireDest.x = buttonsDraw[i].x + pos1dst; + autoFireDest.w = pos2dst - pos1dst; + + drawCharTex( &buttonAutoFireImages[i*2+1], + &autoFireCrop, &autoFireDest, 255, 255, 255, transparency ); + } + else + { + drawCharTex( ( i < AutoFireButtonsNum && ButtonAutoFire[i] ) ? &buttonAutoFireImages[i*2] : + &buttonImages[ SDL_GetKeyboardState(NULL)[buttonKeysyms[i]] ? (i * 2 + 1) : (i * 2) ], + NULL, &buttonsDraw[i], 255, 255, 255, transparency ); + } + } +} + +static void drawTouchscreenKeyboardSun() +{ + int i; + + drawCharTex( &arrowImages[0], NULL, &arrowsDraw, 255, 255, 255, transparency ); + if(pointerInButtonRect[BUTTON_ARROWS] != -1) + { + SDL_Rect touch = arrowsDraw; + touch.w /= 2; + touch.h /= 2; + touch.x = joystickTouchPoints[0] - touch.w / 2; + touch.y = joystickTouchPoints[1] - touch.h / 2; + drawCharTex( &arrowImages[0], NULL, &touch, 255, 255, 255, transparency ); + } + + for( i = 0; i < MAX_BUTTONS; i++ ) + { + int pressed = SDL_GetKeyboardState(NULL)[buttonKeysyms[i]]; + if( ! buttons[i].h || ! buttons[i].w ) + continue; + if( i < AutoFireButtonsNum ) + { + if( ButtonAutoFire[i] == 1 && SDL_GetTicks() - ButtonAutoFireDecay[i] > 1000 ) + { + ButtonAutoFire[i] = 0; + } + if( ! ButtonAutoFire[i] && SDL_GetTicks() - ButtonAutoFireDecay[i] > 300 ) + { + if( ButtonAutoFireX[i*2] > 0 ) + ButtonAutoFireX[i*2] --; + if( ButtonAutoFireX[i*2+1] > 0 ) + ButtonAutoFireX[i*2+1] --; + ButtonAutoFireDecay[i] = SDL_GetTicks(); + } + } + + if( i < AutoFireButtonsNum && ButtonAutoFire[i] ) + drawCharTex( &buttonAutoFireImages[i*2+1], + NULL, &buttonsDraw[i], 255, 255, 255, transparency ); + + drawCharTexFlip( &buttonImages[ pressed ? (i * 2 + 1) : (i * 2) ], + NULL, &buttonsDraw[i], (i >= 2 && pressed), 0, 255, 255, 255, transparency ); + + if( i < AutoFireButtonsNum && ! ButtonAutoFire[i] && + ( ButtonAutoFireX[i*2] > 0 || ButtonAutoFireX[i*2+1] > 0 ) ) + { + int pos1src = buttonImages[i*2+1].w / 2 - ButtonAutoFireX[i*2]; + int pos1dst = buttonsDraw[i].w * pos1src / buttonImages[i*2+1].w; + int pos2src = buttonImages[i*2+1].w - ( buttonImages[i*2+1].w / 2 - ButtonAutoFireX[i*2+1] ); + int pos2dst = buttonsDraw[i].w * pos2src / buttonImages[i*2+1].w; + SDL_Rect autoFireDest; + + autoFireDest.w = pos2dst - pos1dst; + autoFireDest.h = pos2dst - pos1dst; + autoFireDest.x = buttonsDraw[i].x + buttonsDraw[i].w/2 - autoFireDest.w/2; + autoFireDest.y = buttonsDraw[i].y + buttonsDraw[i].h/2 - autoFireDest.h/2; + + drawCharTex( &buttonAutoFireImages[i*2], + NULL, &autoFireDest, 255, 255, 255, transparency ); + } + } +} + +int SDL_ANDROID_drawTouchscreenKeyboard() +{ + if( !SDL_ANDROID_isTouchscreenKeyboardUsed || !touchscreenKeyboardShown ) + return 0; + + beginDrawingTex(); + + if(sunTheme) + drawTouchscreenKeyboardSun(); + else + drawTouchscreenKeyboardLegacy(); + + endDrawingTex(); + + return 1; +}; + +static inline int ArrowKeysPressed(int x, int y) +{ + int ret = 0, dx, dy; + dx = x - arrows.x - arrows.w / 2; + dy = y - arrows.y - arrows.h / 2; + // Single arrow key pressed + if( abs(dy / 2) >= abs(dx) ) + { + if( dy < 0 ) + ret |= ARROW_UP; + else + ret |= ARROW_DOWN; + } + else + if( abs(dx / 2) >= abs(dy) ) + { + if( dx > 0 ) + ret |= ARROW_RIGHT; + else + ret |= ARROW_LEFT; + } + else // Two arrow keys pressed + { + if( dx > 0 ) + ret |= ARROW_RIGHT; + else + ret |= ARROW_LEFT; + + if( dy < 0 ) + ret |= ARROW_UP; + else + ret |= ARROW_DOWN; + } + return ret; +} + +int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointerId) +{ + int i; + int processed = 0; + + + if( !touchscreenKeyboardShown ) + return 0; + + + if( action == MOUSE_DOWN ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "touch %03dx%03d ptr %d action %d", x, y, pointerId, action); + if( InsideRect( &arrows, x, y ) ) + { + processed = 1; + if( pointerInButtonRect[BUTTON_ARROWS] == -1 ) + { + pointerInButtonRect[BUTTON_ARROWS] = pointerId; + joystickTouchPoints[0] = x; + joystickTouchPoints[1] = y; + if( SDL_ANDROID_isJoystickUsed ) + { + SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, (x - arrows.x - arrows.w / 2) * 65534 / arrows.w ); + SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, (y - arrows.y - arrows.h / 2) * 65534 / arrows.h ); + } + else + { + i = ArrowKeysPressed(x, y); + if( i & ARROW_UP ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(UP) ); + if( i & ARROW_DOWN ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(DOWN) ); + if( i & ARROW_LEFT ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(LEFT) ); + if( i & ARROW_RIGHT ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(RIGHT) ); + oldArrows = i; + } + } + } + + for( i = 0; i < MAX_BUTTONS; i++ ) + { + if( ! buttons[i].h || ! buttons[i].w ) + continue; + if( InsideRect( &buttons[i], x, y) ) + { + processed = 1; + if( pointerInButtonRect[i] == -1 ) + { + pointerInButtonRect[i] = pointerId; + if( i == BUTTON_TEXT_INPUT ) + SDL_ANDROID_ToggleScreenKeyboardTextInput(NULL); + else + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, buttonKeysyms[i] ); + if( i < AutoFireButtonsNum ) + { + ButtonAutoFire[i] = 0; + ButtonAutoFireX[i*2] = 0; + ButtonAutoFireX[i*2+1] = 0; + ButtonAutoFireRot[i] = x; + ButtonAutoFireDecay[i] = SDL_GetTicks(); + } + } + } + } + } + else + if( action == MOUSE_UP ) + { + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "touch %03dx%03d ptr %d action %d", x, y, pointerId, action); + if( pointerInButtonRect[BUTTON_ARROWS] == pointerId ) + { + processed = 1; + pointerInButtonRect[BUTTON_ARROWS] = -1; + if( SDL_ANDROID_isJoystickUsed ) + { + SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, 0 ); + SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, 0 ); + } + else + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(UP) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(DOWN) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(LEFT) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(RIGHT) ); + oldArrows = 0; + } + } + for( i = 0; i < MAX_BUTTONS; i++ ) + { + if( ! buttons[i].h || ! buttons[i].w ) + continue; + if( pointerInButtonRect[i] == pointerId ) + { + processed = 1; + pointerInButtonRect[i] = -1; + if( i < AutoFireButtonsNum && ButtonAutoFire[i] ) + { + ButtonAutoFire[i] = 2; + } + else + { + if( i != BUTTON_TEXT_INPUT ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, buttonKeysyms[i] ); + } + if( i < AutoFireButtonsNum ) + { + ButtonAutoFireX[i*2] = 0; + ButtonAutoFireX[i*2+1] = 0; + } + } + } + } + else + if( action == MOUSE_MOVE ) + { + // Process cases when pointer enters button area (it won't send keypress twice if button already pressed) + processed = SDL_ANDROID_processTouchscreenKeyboard(x, y, MOUSE_DOWN, pointerId); + + // Process cases when pointer leaves button area + // TODO: huge code size, split it or somehow make it more readable + if( pointerInButtonRect[BUTTON_ARROWS] == pointerId ) + { + processed = 1; + if( ! InsideRect( &arrowsExtended, x, y ) ) + { + pointerInButtonRect[BUTTON_ARROWS] = -1; + if( SDL_ANDROID_isJoystickUsed ) + { + SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, 0 ); + SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, 0 ); + } + else + { + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(UP) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(DOWN) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(LEFT) ); + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(RIGHT) ); + oldArrows = 0; + } + } + else + { + joystickTouchPoints[0] = x; + joystickTouchPoints[1] = y; + if( SDL_ANDROID_isJoystickUsed ) + { + SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, (x - arrows.x - arrows.w / 2) * 65534 / arrows.w ); + SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, (y - arrows.y - arrows.h / 2) * 65534 / arrows.h ); + } + else + { + i = ArrowKeysPressed(x, y); + if( i != oldArrows ) + { + if( oldArrows & ARROW_UP && ! (i & ARROW_UP) ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(UP) ); + if( oldArrows & ARROW_DOWN && ! (i & ARROW_DOWN) ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(DOWN) ); + if( oldArrows & ARROW_LEFT && ! (i & ARROW_LEFT) ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(LEFT) ); + if( oldArrows & ARROW_RIGHT && ! (i & ARROW_RIGHT) ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(RIGHT) ); + if( i & ARROW_UP ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(UP) ); + if( i & ARROW_DOWN ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(DOWN) ); + if( i & ARROW_LEFT ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(LEFT) ); + if( i & ARROW_RIGHT ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(RIGHT) ); + } + oldArrows = i; + } + } + } + for( i = 0; i < AutoFireButtonsNum; i++ ) + { + if( pointerInButtonRect[i] == pointerId ) + { + processed = 1; + if( ! InsideRect( &buttonsAutoFireRect[i], x, y ) ) + { + pointerInButtonRect[i] = -1; + if( !ButtonAutoFire[i] ) + { + if( i != BUTTON_TEXT_INPUT ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, buttonKeysyms[i] ); + } + else + { + ButtonAutoFire[i] = 2; + } + ButtonAutoFireX[i*2] = 0; + ButtonAutoFireX[i*2+1] = 0; + } + else + { + int coeff = (buttonAutoFireImages[i*2+1].w > buttons[i].w) ? buttonAutoFireImages[i*2+1].w / buttons[i].w + 1 : 1; + if( ButtonAutoFireRot[i] < x ) + ButtonAutoFireX[i*2+1] += (x - ButtonAutoFireRot[i]) * coeff; + if( ButtonAutoFireRot[i] > x ) + ButtonAutoFireX[i*2] += (ButtonAutoFireRot[i] - x) * coeff; + + ButtonAutoFireRot[i] = x; + + if( ButtonAutoFireX[i*2] < 0 ) + ButtonAutoFireX[i*2] = 0; + if( ButtonAutoFireX[i*2+1] < 0 ) + ButtonAutoFireX[i*2+1] = 0; + if( ButtonAutoFireX[i*2] > buttonAutoFireImages[i*2+1].w / 2 ) + ButtonAutoFireX[i*2] = buttonAutoFireImages[i*2+1].w / 2; + if( ButtonAutoFireX[i*2+1] > buttonAutoFireImages[i*2+1].w / 2 ) + ButtonAutoFireX[i*2+1] = buttonAutoFireImages[i*2+1].w / 2; + + if( ButtonAutoFireX[i*2] == buttonAutoFireImages[i*2+1].w / 2 && + ButtonAutoFireX[i*2+1] == buttonAutoFireImages[i*2+1].w / 2 ) + { + if( ! ButtonAutoFire[i] ) + ButtonAutoFireDecay[i] = SDL_GetTicks(); + ButtonAutoFire[i] = 1; + } + } + } + } + for( i = AutoFireButtonsNum; i < MAX_BUTTONS; i++ ) + { + if( ! buttons[i].h || ! buttons[i].w ) + continue; + if( pointerInButtonRect[i] == pointerId ) + { + processed = 1; + if( ! InsideRect( &buttons[i], x, y ) ) + { + pointerInButtonRect[i] = -1; + if( i != BUTTON_TEXT_INPUT ) + SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, buttonKeysyms[i] ); + } + } + } + } + + return processed; +}; + +void shrinkButtonRect(SDL_Rect s, SDL_Rect * d) +{ + int i; + + if( !buttonDrawSize ) + { + memcpy(d, &s, sizeof(s)); + return; + } + + d->w = s.w * 2 / (buttonDrawSize+2); + d->h = s.h * 2 / (buttonDrawSize+2); + d->x = s.x + s.w / 2 - d->w / 2; + d->y = s.y + s.h / 2 - d->h / 2; +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thiz, jint size, jint drawsize, jint theme, jint nbuttonsAutoFire, jint _transparency ) +{ + int i, ii; + int nbuttons1row, nbuttons2row; + int _nbuttons = MAX_BUTTONS; + SDL_Rect * r; + touchscreenKeyboardTheme = theme; + AutoFireButtonsNum = nbuttonsAutoFire; + if( AutoFireButtonsNum > MAX_BUTTONS_AUTOFIRE ) + AutoFireButtonsNum = MAX_BUTTONS_AUTOFIRE; + // TODO: works for horizontal screen orientation only! + buttonsize = size; + buttonDrawSize = drawsize; + switch(_transparency) + { + case 0: transparency = 32; break; + case 1: transparency = 64; break; + case 2: transparency = 128; break; + case 3: transparency = 192; break; + case 4: transparency = 255; break; + default: transparency = 192; break; + } + + // Arrows to the lower-left part of screen + arrows.w = SDL_ANDROID_sWindowWidth / (size + 2) * 2 / 3; + arrows.h = arrows.w; + // Move to the screen edge + arrows.x = 0; + arrows.y = SDL_ANDROID_sWindowHeight - arrows.h; + + arrowsExtended.w = arrows.w * 2; + arrowsExtended.h = arrows.h * 2; + arrowsExtended.x = arrows.x + arrows.w / 2 - arrowsExtended.w / 2; + arrowsExtended.y = arrows.y + arrows.h / 2 - arrowsExtended.h / 2; + /* + // This will leave some unused space near the edge + arrows.x = SDL_ANDROID_sWindowWidth / 4; + arrows.y = SDL_ANDROID_sWindowHeight - SDL_ANDROID_sWindowWidth / 4; + arrows.x -= arrows.w/2; + arrows.y -= arrows.h/2; + // Move arrows from the center of the screen + arrows.x -= size * SDL_ANDROID_sWindowWidth / 32; + arrows.y += size * SDL_ANDROID_sWindowWidth / 32; + */ + + // Buttons to the lower-right in 2 rows + for(i = 0; i < 3; i++) + for(ii = 0; ii < 2; ii++) + { + // Custom button ordering + int iii = ii + i*2; + buttons[iii].w = SDL_ANDROID_sWindowWidth / (size + 2) / 3; + buttons[iii].h = buttons[iii].w; + // Move to the screen edge + buttons[iii].x = SDL_ANDROID_sWindowWidth - buttons[iii].w * (ii + 1); + buttons[iii].y = SDL_ANDROID_sWindowHeight - buttons[iii].h * (i + 1); + /* + // This will leave some unused space near the edge and between buttons + buttons[iii].x = SDL_ANDROID_sWindowWidth - SDL_ANDROID_sWindowWidth / 12 - (SDL_ANDROID_sWindowWidth * ii / 6); + buttons[iii].y = SDL_ANDROID_sWindowHeight - SDL_ANDROID_sWindowHeight / 8 - (SDL_ANDROID_sWindowHeight * i / 4); + buttons[iii].x -= buttons[iii].w/2; + buttons[iii].y -= buttons[iii].h/2; + */ + } + buttons[6].x = 0; + buttons[6].y = 0; + buttons[6].w = SDL_ANDROID_sWindowHeight/10; + buttons[6].h = SDL_ANDROID_sWindowHeight/10; + + for( i = 0; i < sizeof(pointerInButtonRect)/sizeof(pointerInButtonRect[0]); i++ ) + { + pointerInButtonRect[i] = -1; + } + for( i = 0; i < nbuttonsAutoFire; i++ ) + { + buttonsAutoFireRect[i].w = buttons[i].w * 2; + buttonsAutoFireRect[i].h = buttons[i].h * 2; + buttonsAutoFireRect[i].x = buttons[i].x - buttons[i].w / 2; + buttonsAutoFireRect[i].y = buttons[i].y - buttons[i].h / 2; + } + shrinkButtonRect(arrows, &arrowsDraw); + for(i = 0; i < MAX_BUTTONS; i++) + { + shrinkButtonRect(buttons[i], &buttonsDraw[i]); + } +}; + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetTouchscreenKeyboardUsed) ( JNIEnv* env, jobject thiz) +{ + SDL_ANDROID_isTouchscreenKeyboardUsed = 1; +} + +void SDL_ANDROID_DrawMouseCursor(int x, int y, int size, int alpha) +{ + SDL_Rect r; + // I've failed with size calcualtions, so leaving it as-is + r.x = x - MOUSE_POINTER_X; + r.y = y - MOUSE_POINTER_Y; + r.w = MOUSE_POINTER_W; + r.h = MOUSE_POINTER_H; + beginDrawingTex(); + drawCharTex( &mousePointer, NULL, &r, 255, 255, 255, alpha ); + endDrawingTex(); +} + +static int +power_of_2(int input) +{ + int value = 1; + + while (value < input) { + value <<= 1; + } + return value; +} + +static int setupScreenKeyboardButtonTexture( GLTexture_t * data, Uint8 * charBuf ) +{ + int w, h, format, bpp; + int texture_w, texture_h; + + memcpy(&w, charBuf, sizeof(int)); + memcpy(&h, charBuf + sizeof(int), sizeof(int)); + memcpy(&format, charBuf + 2*sizeof(int), sizeof(int)); + w = ntohl(w); + h = ntohl(h); + format = ntohl(format); + bpp = 2; + if(format == 2) + bpp = 4; + + texture_w = power_of_2(w); + texture_h = power_of_2(h); + data->w = w; + data->h = h; + + glEnable(GL_TEXTURE_2D); + + glGenTextures(1, &data->id); + glBindTexture(GL_TEXTURE_2D, data->id); + //__android_log_print(ANDROID_LOG_INFO, "libSDL", "On-screen keyboard generated OpenGL texture ID %d", data->id); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_w, texture_h, 0, GL_RGBA, + bpp == 4 ? GL_UNSIGNED_BYTE : (format ? GL_UNSIGNED_SHORT_4_4_4_4 : GL_UNSIGNED_SHORT_5_5_5_1), NULL); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, + bpp == 4 ? GL_UNSIGNED_BYTE : (format ? GL_UNSIGNED_SHORT_4_4_4_4 : GL_UNSIGNED_SHORT_5_5_5_1), + charBuf + 3*sizeof(int) ); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glDisable(GL_TEXTURE_2D); + + return 3*sizeof(int) + w * h * bpp; +} + +static int setupScreenKeyboardButtonLegacy( int buttonID, Uint8 * charBuf ) +{ + GLTexture_t * data = NULL; + + if( buttonID < 5 ) + data = &(arrowImages[buttonID]); + else + if( buttonID < 9 ) + data = &(buttonAutoFireImages[buttonID-5]); + else + data = &(buttonImages[buttonID-9]); + + if( buttonID == 23 ) + data = &mousePointer; + else if( buttonID > 22 ) // Error, array too big + return 12; // Return value bigger than zero to iterate it + + return setupScreenKeyboardButtonTexture(data, charBuf); +} + +static int setupScreenKeyboardButtonSun( int buttonID, Uint8 * charBuf ) +{ + GLTexture_t * data = NULL; + int i, ret; + + if( buttonID == 0 ) + data = &(arrowImages[0]); + if( buttonID >= 1 && buttonID <= 4 ) + data = &(buttonImages[buttonID-1]); + if( buttonID >= 5 && buttonID <= 8 ) + data = &(buttonImages[4+(buttonID-5)*2]); + if( buttonID == 9 ) + data = &mousePointer; + else if( buttonID > 9 ) // Error, array too big + return 12; // Return value bigger than zero to iterate it + + ret = setupScreenKeyboardButtonTexture(data, charBuf); + + for( i = 1; i <=4; i++ ) + arrowImages[i] = arrowImages[0]; + + for( i = 2; i < MAX_BUTTONS; i++ ) + buttonImages[i * 2 + 1] = buttonImages[i * 2]; + + for( i = 0; i < MAX_BUTTONS_AUTOFIRE*2; i++ ) + buttonAutoFireImages[i] = arrowImages[0]; + + buttonImages[BUTTON_TEXT_INPUT*2] = buttonImages[10]; + buttonImages[BUTTON_TEXT_INPUT*2+1] = buttonImages[10]; + + return ret; +} + +static int setupScreenKeyboardButton( int buttonID, Uint8 * charBuf, int count ) +{ + if(count == 24) + { + sunTheme = 0; + return setupScreenKeyboardButtonLegacy(buttonID, charBuf); + } + else if(count == 10) + { + sunTheme = 1; + return setupScreenKeyboardButtonSun(buttonID, charBuf); + } + else + { + __android_log_print(ANDROID_LOG_FATAL, "libSDL", "On-screen keyboard buton img count = %d, should be 10 or 24", count); + return 12; // Return value bigger than zero to iterate it + } +} + + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboardButtons) ( JNIEnv* env, jobject thiz, jbyteArray charBufJava ) +{ + jboolean isCopy = JNI_TRUE; + int len = (*env)->GetArrayLength(env, charBufJava); + Uint8 * charBuf = (Uint8 *) (*env)->GetByteArrayElements(env, charBufJava, &isCopy); + int but, pos, count; + memcpy(&count, charBuf, sizeof(int)); + count = ntohl(count); + + for( but = 0, pos = sizeof(int); pos < len; but ++ ) + pos += setupScreenKeyboardButton( but, charBuf + pos, count ); + + (*env)->ReleaseByteArrayElements(env, charBufJava, (jbyte *)charBuf, 0); +} + + +int SDL_ANDROID_SetScreenKeyboardButtonPos(int buttonId, SDL_Rect * pos) +{ + if( buttonId < 0 || buttonId >= SDL_ANDROID_SCREENKEYBOARD_BUTTON_NUM || ! pos ) + return 0; + + if( buttonId == SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD ) + { + arrows = *pos; + arrowsExtended.w = arrows.w * 2; + arrowsExtended.h = arrows.h * 2; + arrowsExtended.x = arrows.x + arrows.w / 2 - arrowsExtended.w / 2; + arrowsExtended.y = arrows.y + arrows.h / 2 - arrowsExtended.h / 2; + shrinkButtonRect(arrows, &arrowsDraw); + } + else + { + int i = buttonId - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0; + buttons[i] = *pos; + shrinkButtonRect(buttons[i], &buttonsDraw[i]); + if( i < AutoFireButtonsNum ) + { + buttonsAutoFireRect[i].w = buttons[i].w * 3 / 2; + buttonsAutoFireRect[i].h = buttons[i].h * 3 / 2; + buttonsAutoFireRect[i].x = buttons[i].x + buttons[i].w / 2 - buttonsAutoFireRect[i].w / 2; + buttonsAutoFireRect[i].y = buttons[i].y + buttons[i].h / 2 - buttonsAutoFireRect[i].h / 2; + } + } + return 1; +}; + +int SDL_ANDROID_GetScreenKeyboardButtonPos(int buttonId, SDL_Rect * pos) +{ + if( buttonId < 0 || buttonId >= SDL_ANDROID_SCREENKEYBOARD_BUTTON_NUM || ! pos ) + return 0; + + if( buttonId == SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD ) + { + *pos = arrows; + } + else + { + *pos = buttons[buttonId - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0]; + } + return 1; +}; + +int SDL_ANDROID_SetScreenKeyboardButtonKey(int buttonId, SDLKey key) +{ + if( buttonId < SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 || buttonId > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 || ! key ) + return 0; + buttonKeysyms[buttonId - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0] = key; + return 1; +}; + +SDLKey SDL_ANDROID_GetScreenKeyboardButtonKey(int buttonId) +{ + if( buttonId < SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 || buttonId > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 ) + return SDLK_UNKNOWN; + return buttonKeysyms[buttonId - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0]; +}; + +int SDL_ANDROID_SetScreenKeyboardAutoFireButtonsAmount(int nbuttons) +{ + if( nbuttons < 0 || nbuttons >= MAX_BUTTONS_AUTOFIRE ) + return 0; + AutoFireButtonsNum = nbuttons; + return 1; +}; + +int SDL_ANDROID_GetScreenKeyboardAutoFireButtonsAmount(void) +{ + return AutoFireButtonsNum; +}; + +int SDL_ANDROID_SetScreenKeyboardShown(int shown) +{ + touchscreenKeyboardShown = shown; +}; + +int SDL_ANDROID_GetScreenKeyboardShown(void) +{ + return touchscreenKeyboardShown; +}; + +int SDL_ANDROID_GetScreenKeyboardSize(void) +{ + return buttonsize; +}; + +int SDL_ANDROID_ToggleScreenKeyboardTextInput(const char * previousText) +{ + static char textIn[255]; + if( previousText == NULL ) + previousText = ""; + strncpy(textIn, previousText, sizeof(textIn)); + textIn[sizeof(textIn)-1] = 0; + SDL_ANDROID_CallJavaShowScreenKeyboard(textIn, NULL, 0); + return 1; +}; + +int SDLCALL SDL_ANDROID_GetScreenKeyboardTextInput(char * textBuf, int textBufSize) +{ + SDL_ANDROID_CallJavaShowScreenKeyboard(textBuf, textBuf, textBufSize); + return 1; +}; + +// That's probably not the right file to put this func +JNIEXPORT jint JNICALL +JAVA_EXPORT_NAME(Settings_nativeChmod) ( JNIEnv* env, jobject thiz, jstring j_name, jint mode ) +{ + jboolean iscopy; + const char *name = (*env)->GetStringUTFChars(env, j_name, &iscopy); + int ret = chmod(name, mode); + (*env)->ReleaseStringUTFChars(env, j_name, name); + return (ret == 0); +} + +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(Settings_nativeSetEnv) ( JNIEnv* env, jobject thiz, jstring j_name, jstring j_value ) +{ + jboolean iscopy; + const char *name = (*env)->GetStringUTFChars(env, j_name, &iscopy); + const char *value = (*env)->GetStringUTFChars(env, j_value, &iscopy); + setenv(name, value, 1); + (*env)->ReleaseStringUTFChars(env, j_name, name); + (*env)->ReleaseStringUTFChars(env, j_value, value); +} diff --git a/project/jni/sdl-1.2/src/video/android/atan2i.h b/project/jni/sdl-1.2/src/video/android/atan2i.h deleted file mode 120000 index d67f9a7a7..000000000 --- a/project/jni/sdl-1.2/src/video/android/atan2i.h +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/video/android/atan2i.h \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/video/android/atan2i.h b/project/jni/sdl-1.2/src/video/android/atan2i.h new file mode 100644 index 000000000..e7111a618 --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/atan2i.h @@ -0,0 +1,33 @@ +#ifndef __ATAN2I_H__ +#define __ATAN2I_H__ +#include + +// Fast arctan2, returns angle in radians as integer, with fractional part in lower 16 bits +// Stolen from http://www.dspguru.com/dsp/tricks/fixed-point-atan2-with-self-normalization , precision is said to be 0.07 rads + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif +enum { atan2i_coeff_1 = ((int)(M_PI*65536.0/4)), atan2i_coeff_2 = (3*atan2i_coeff_1), atan2i_PI = (int)(M_PI * 65536.0) }; + +static inline int atan2i(int y, int x) +{ + int angle; + int abs_y = abs(y); + if( abs_y == 0 ) + abs_y = 1; + if (x>=0) + { + angle = atan2i_coeff_1 - atan2i_coeff_1 * (x - abs_y) / (x + abs_y); + } + else + { + angle = atan2i_coeff_2 - atan2i_coeff_1 * (x + abs_y) / (abs_y - x); + } + if (y < 0) + return(-angle); // negate if in quad III or IV + else + return(angle); +}; + +#endif diff --git a/project/jni/sdl-1.2/src/video/android/javakeycodes.h b/project/jni/sdl-1.2/src/video/android/javakeycodes.h deleted file mode 120000 index b73dc56f0..000000000 --- a/project/jni/sdl-1.2/src/video/android/javakeycodes.h +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/video/android/javakeycodes.h \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/video/android/javakeycodes.h b/project/jni/sdl-1.2/src/video/android/javakeycodes.h new file mode 100644 index 000000000..4c07fc397 --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/javakeycodes.h @@ -0,0 +1,215 @@ +#ifndef _JAVA_KEY_CODES_H_ +#define _JAVA_KEY_CODES_H_ + +// Keycodes ripped from Java SDK +enum KEYCODES_ANDROID +{ +KEYCODE_UNKNOWN = 0, +KEYCODE_SOFT_LEFT = 1, +KEYCODE_SOFT_RIGHT = 2, +KEYCODE_HOME = 3, +KEYCODE_BACK = 4, +KEYCODE_CALL = 5, +KEYCODE_ENDCALL = 6, +KEYCODE_0 = 7, +KEYCODE_1 = 8, +KEYCODE_2 = 9, +KEYCODE_3 = 10, +KEYCODE_4 = 11, +KEYCODE_5 = 12, +KEYCODE_6 = 13, +KEYCODE_7 = 14, +KEYCODE_8 = 15, +KEYCODE_9 = 16, +KEYCODE_STAR = 17, +KEYCODE_POUND = 18, +KEYCODE_DPAD_UP = 19, +KEYCODE_DPAD_DOWN = 20, +KEYCODE_DPAD_LEFT = 21, +KEYCODE_DPAD_RIGHT = 22, +KEYCODE_DPAD_CENTER = 23, +KEYCODE_VOLUME_UP = 24, +KEYCODE_VOLUME_DOWN = 25, +KEYCODE_POWER = 26, +KEYCODE_CAMERA = 27, +KEYCODE_CLEAR = 28, +KEYCODE_A = 29, +KEYCODE_B = 30, +KEYCODE_C = 31, +KEYCODE_D = 32, +KEYCODE_E = 33, +KEYCODE_F = 34, +KEYCODE_G = 35, +KEYCODE_H = 36, +KEYCODE_I = 37, +KEYCODE_J = 38, +KEYCODE_K = 39, +KEYCODE_L = 40, +KEYCODE_M = 41, +KEYCODE_N = 42, +KEYCODE_O = 43, +KEYCODE_P = 44, +KEYCODE_Q = 45, +KEYCODE_R = 46, +KEYCODE_S = 47, +KEYCODE_T = 48, +KEYCODE_U = 49, +KEYCODE_V = 50, +KEYCODE_W = 51, +KEYCODE_X = 52, +KEYCODE_Y = 53, +KEYCODE_Z = 54, +KEYCODE_COMMA = 55, +KEYCODE_PERIOD = 56, +KEYCODE_ALT_LEFT = 57, +KEYCODE_ALT_RIGHT = 58, +KEYCODE_SHIFT_LEFT = 59, +KEYCODE_SHIFT_RIGHT = 60, +KEYCODE_TAB = 61, +KEYCODE_SPACE = 62, +KEYCODE_SYM = 63, +KEYCODE_EXPLORER = 64, +KEYCODE_ENVELOPE = 65, +KEYCODE_ENTER = 66, +KEYCODE_DEL = 67, +KEYCODE_GRAVE = 68, +KEYCODE_MINUS = 69, +KEYCODE_EQUALS = 70, +KEYCODE_LEFT_BRACKET = 71, +KEYCODE_RIGHT_BRACKET = 72, +KEYCODE_BACKSLASH = 73, +KEYCODE_SEMICOLON = 74, +KEYCODE_APOSTROPHE = 75, +KEYCODE_SLASH = 76, +KEYCODE_AT = 77, +KEYCODE_NUM = 78, +KEYCODE_HEADSETHOOK = 79, +KEYCODE_FOCUS = 80, +KEYCODE_PLUS = 81, +KEYCODE_MENU = 82, +KEYCODE_NOTIFICATION = 83, +KEYCODE_SEARCH = 84, +KEYCODE_MEDIA_PLAY_PAUSE= 85, +KEYCODE_MEDIA_STOP = 86, +KEYCODE_MEDIA_NEXT = 87, +KEYCODE_MEDIA_PREVIOUS = 88, +KEYCODE_MEDIA_REWIND = 89, +KEYCODE_MEDIA_FAST_FORWARD = 90, +KEYCODE_MUTE = 91, +KEYCODE_PAGE_UP = 92, +KEYCODE_PAGE_DOWN = 93, +KEYCODE_PICTSYMBOLS = 94, +KEYCODE_SWITCH_CHARSET = 95, +KEYCODE_BUTTON_A = 96, +KEYCODE_BUTTON_B = 97, +KEYCODE_BUTTON_C = 98, +KEYCODE_BUTTON_X = 99, +KEYCODE_BUTTON_Y = 100, +KEYCODE_BUTTON_Z = 101, +KEYCODE_BUTTON_L1 = 102, +KEYCODE_BUTTON_R1 = 103, +KEYCODE_BUTTON_L2 = 104, +KEYCODE_BUTTON_R2 = 105, +KEYCODE_BUTTON_THUMBL = 106, +KEYCODE_BUTTON_THUMBR = 107, +KEYCODE_BUTTON_START = 108, +KEYCODE_BUTTON_SELECT = 109, +KEYCODE_BUTTON_MODE = 110, +KEYCODE_ESCAPE = 111, +KEYCODE_FORWARD_DEL = 112, +KEYCODE_CTRL_LEFT = 113, +KEYCODE_CTRL_RIGHT = 114, +KEYCODE_CAPS_LOCK = 115, +KEYCODE_SCROLL_LOCK = 116, +KEYCODE_META_LEFT = 117, +KEYCODE_META_RIGHT = 118, +KEYCODE_FUNCTION = 119, +KEYCODE_SYSRQ = 120, +KEYCODE_BREAK = 121, +KEYCODE_MOVE_HOME = 122, +KEYCODE_MOVE_END = 123, +KEYCODE_INSERT = 124, +KEYCODE_FORWARD = 125, +KEYCODE_MEDIA_PLAY = 126, +KEYCODE_MEDIA_PAUSE = 127, +KEYCODE_MEDIA_CLOSE = 128, +KEYCODE_MEDIA_EJECT = 129, +KEYCODE_MEDIA_RECORD = 130, +KEYCODE_F1 = 131, +KEYCODE_F2 = 132, +KEYCODE_F3 = 133, +KEYCODE_F4 = 134, +KEYCODE_F5 = 135, +KEYCODE_F6 = 136, +KEYCODE_F7 = 137, +KEYCODE_F8 = 138, +KEYCODE_F9 = 139, +KEYCODE_F10 = 140, +KEYCODE_F11 = 141, +KEYCODE_F12 = 142, +KEYCODE_NUM_LOCK = 143, +KEYCODE_NUMPAD_0 = 144, +KEYCODE_NUMPAD_1 = 145, +KEYCODE_NUMPAD_2 = 146, +KEYCODE_NUMPAD_3 = 147, +KEYCODE_NUMPAD_4 = 148, +KEYCODE_NUMPAD_5 = 149, +KEYCODE_NUMPAD_6 = 150, +KEYCODE_NUMPAD_7 = 151, +KEYCODE_NUMPAD_8 = 152, +KEYCODE_NUMPAD_9 = 153, +KEYCODE_NUMPAD_DIVIDE = 154, +KEYCODE_NUMPAD_MULTIPLY = 155, +KEYCODE_NUMPAD_SUBTRACT = 156, +KEYCODE_NUMPAD_ADD = 157, +KEYCODE_NUMPAD_DOT = 158, +KEYCODE_NUMPAD_COMMA = 159, +KEYCODE_NUMPAD_ENTER = 160, +KEYCODE_NUMPAD_EQUALS = 161, +KEYCODE_NUMPAD_LEFT_PAREN = 162, +KEYCODE_NUMPAD_RIGHT_PAREN = 163, +KEYCODE_VOLUME_MUTE = 164, +KEYCODE_INFO = 165, +KEYCODE_CHANNEL_UP = 166, +KEYCODE_CHANNEL_DOWN = 167, +KEYCODE_ZOOM_IN = 168, +KEYCODE_ZOOM_OUT = 169, +KEYCODE_TV = 170, +KEYCODE_WINDOW = 171, +KEYCODE_GUIDE = 172, +KEYCODE_DVR = 173, +KEYCODE_BOOKMARK = 174, +KEYCODE_CAPTIONS = 175, +KEYCODE_SETTINGS = 176, +KEYCODE_TV_POWER = 177, +KEYCODE_TV_INPUT = 178, +KEYCODE_STB_POWER = 179, +KEYCODE_STB_INPUT = 180, +KEYCODE_AVR_POWER = 181, +KEYCODE_AVR_INPUT = 182, +KEYCODE_PROG_RED = 183, +KEYCODE_PROG_GREEN = 184, +KEYCODE_PROG_YELLOW = 185, +KEYCODE_PROG_BLUE = 186, +KEYCODE_APP_SWITCH = 187, +KEYCODE_BUTTON_1 = 188, +KEYCODE_BUTTON_2 = 189, +KEYCODE_BUTTON_3 = 190, +KEYCODE_BUTTON_4 = 191, +KEYCODE_BUTTON_5 = 192, +KEYCODE_BUTTON_6 = 193, +KEYCODE_BUTTON_7 = 194, +KEYCODE_BUTTON_8 = 195, +KEYCODE_BUTTON_9 = 196, +KEYCODE_BUTTON_10 = 197, +KEYCODE_BUTTON_11 = 198, +KEYCODE_BUTTON_12 = 199, +KEYCODE_BUTTON_13 = 200, +KEYCODE_BUTTON_14 = 201, +KEYCODE_BUTTON_15 = 202, +KEYCODE_BUTTON_16 = 203, + +KEYCODE_LAST = 255 // Android 2.3 added several new gaming keys, Android 3.1 added even more - plz keep in sync with Keycodes.java +}; + +#endif diff --git a/project/jni/sdl-1.2/src/video/android/jniwrapperstuff.h b/project/jni/sdl-1.2/src/video/android/jniwrapperstuff.h deleted file mode 120000 index 235f27468..000000000 --- a/project/jni/sdl-1.2/src/video/android/jniwrapperstuff.h +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/video/android/jniwrapperstuff.h \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/video/android/jniwrapperstuff.h b/project/jni/sdl-1.2/src/video/android/jniwrapperstuff.h new file mode 100644 index 000000000..6a37980aa --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/jniwrapperstuff.h @@ -0,0 +1,13 @@ + +/* JNI-C++ wrapper stuff */ +#ifndef _JNI_WRAPPER_STUFF_H_ +#define _JNI_WRAPPER_STUFF_H_ + +#ifndef SDL_JAVA_PACKAGE_PATH +#error You have to define SDL_JAVA_PACKAGE_PATH to your package path with dots replaced with underscores, for example "com_example_SanAngeles" +#endif +#define JAVA_EXPORT_NAME2(name,package) Java_##package##_##name +#define JAVA_EXPORT_NAME1(name,package) JAVA_EXPORT_NAME2(name,package) +#define JAVA_EXPORT_NAME(name) JAVA_EXPORT_NAME1(name,SDL_JAVA_PACKAGE_PATH) + +#endif diff --git a/project/jni/sdl-1.2/src/video/android/keymap.c b/project/jni/sdl-1.2/src/video/android/keymap.c deleted file mode 120000 index 429338bb6..000000000 --- a/project/jni/sdl-1.2/src/video/android/keymap.c +++ /dev/null @@ -1 +0,0 @@ -../../../../sdl-1.3/src/video/android/keymap.c \ No newline at end of file diff --git a/project/jni/sdl-1.2/src/video/android/keymap.c b/project/jni/sdl-1.2/src/video/android/keymap.c new file mode 100644 index 000000000..eb0eb69bc --- /dev/null +++ b/project/jni/sdl-1.2/src/video/android/keymap.c @@ -0,0 +1,242 @@ +#include "SDL_config.h" + +#include "SDL_version.h" +#include "SDL_androidinput.h" +#include "SDL_screenkeyboard.h" + +void SDL_android_init_keymap(SDLKey *SDL_android_keymap) +{ + int i; + SDLKey * keymap = SDL_android_keymap; + + for (i=0; i -#include -#include // for memset() -#include - -#define _THIS SDL_AudioDevice *this - -/* Audio driver functions */ - -static void ANDROIDAUD_WaitAudio(_THIS); -static void ANDROIDAUD_PlayAudio(_THIS); -static Uint8 *ANDROIDAUD_GetAudioBuf(_THIS); -static void ANDROIDAUD_CloseAudio(_THIS); -static void ANDROIDAUD_ThreadInit(_THIS); -static void ANDROIDAUD_ThreadDeinit(_THIS); - -#if SDL_VERSION_ATLEAST(1,3,0) - -static int ANDROIDAUD_OpenAudio(_THIS, const char *devname, int iscapture); - -static void ANDROIDAUD_DeleteDevice() -{ -} - -static int ANDROIDAUD_CreateDevice(SDL_AudioDriverImpl * impl) -{ - - /* Set the function pointers */ - impl->OpenDevice = ANDROIDAUD_OpenAudio; - impl->WaitDevice = ANDROIDAUD_WaitAudio; - impl->PlayDevice = ANDROIDAUD_PlayAudio; - impl->GetDeviceBuf = ANDROIDAUD_GetAudioBuf; - impl->CloseDevice = ANDROIDAUD_CloseAudio; - impl->ThreadInit = ANDROIDAUD_ThreadInit; - impl->WaitDone = ANDROIDAUD_ThreadDeinit; - impl->Deinitialize = ANDROIDAUD_DeleteDevice; - impl->OnlyHasDefaultOutputDevice = 1; - - return 1; -} - -AudioBootStrap ANDROIDAUD_bootstrap = { - "android", "SDL Android audio driver", - ANDROIDAUD_CreateDevice, 0 -}; - -#else - -static int ANDROIDAUD_OpenAudio(_THIS, SDL_AudioSpec *spec); - -static int ANDROIDAUD_Available(void) -{ - return(1); -} - -static void ANDROIDAUD_DeleteDevice(SDL_AudioDevice *device) -{ - SDL_free(device); -} - -static SDL_AudioDevice *ANDROIDAUD_CreateDevice(int devindex) -{ - SDL_AudioDevice *this; - - /* Initialize all variables that we clean on shutdown */ - this = (SDL_AudioDevice *)SDL_malloc(sizeof(SDL_AudioDevice)); - if ( this ) { - SDL_memset(this, 0, (sizeof *this)); - this->hidden = NULL; - } else { - SDL_OutOfMemory(); - return(0); - } - - /* Set the function pointers */ - this->OpenAudio = ANDROIDAUD_OpenAudio; - this->WaitAudio = ANDROIDAUD_WaitAudio; - this->PlayAudio = ANDROIDAUD_PlayAudio; - this->GetAudioBuf = ANDROIDAUD_GetAudioBuf; - this->CloseAudio = ANDROIDAUD_CloseAudio; - this->ThreadInit = ANDROIDAUD_ThreadInit; - this->WaitDone = ANDROIDAUD_ThreadDeinit; - this->free = ANDROIDAUD_DeleteDevice; - - return this; -} - -AudioBootStrap ANDROIDAUD_bootstrap = { - "android", "SDL Android audio driver", - ANDROIDAUD_Available, ANDROIDAUD_CreateDevice -}; - -#endif - - -static unsigned char * audioBuffer = NULL; -static size_t audioBufferSize = 0; - -// Extremely wicked JNI environment to call Java functions from C code -static jbyteArray audioBufferJNI = NULL; -static JavaVM *jniVM = NULL; -static jobject JavaAudioThread = NULL; -static jmethodID JavaInitAudio = NULL; -static jmethodID JavaDeinitAudio = NULL; -static jmethodID JavaPauseAudioPlayback = NULL; -static jmethodID JavaResumeAudioPlayback = NULL; - - -static Uint8 *ANDROIDAUD_GetAudioBuf(_THIS) -{ - return(audioBuffer); -} - - -#if SDL_VERSION_ATLEAST(1,3,0) -static int ANDROIDAUD_OpenAudio (_THIS, const char *devname, int iscapture) -{ - SDL_AudioSpec *audioFormat = &this->spec; - -#else -static int ANDROIDAUD_OpenAudio (_THIS, SDL_AudioSpec *spec) -{ - SDL_AudioSpec *audioFormat = spec; -#endif - - int bytesPerSample; - JNIEnv * jniEnv = NULL; - - this->hidden = NULL; - - if( ! (audioFormat->format == AUDIO_S8 || audioFormat->format == AUDIO_S16) ) - { - __android_log_print(ANDROID_LOG_ERROR, "libSDL", "Application requested unsupported audio format - only S8 and S16 are supported"); - return (-1); // TODO: enable format conversion? Don't know how to do that in SDL - } - - bytesPerSample = (audioFormat->format & 0xFF) / 8; - audioFormat->format = ( bytesPerSample == 2 ) ? AUDIO_S16 : AUDIO_S8; - - __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): app requested audio bytespersample %d freq %d channels %d samples %d", bytesPerSample, audioFormat->freq, (int)audioFormat->channels, (int)audioFormat->samples); - - if(audioFormat->samples <= 0) - audioFormat->samples = 128; // Some sane value - if( audioFormat->samples > 32768 ) // Why anyone need so huge audio buffer? - { - audioFormat->samples = 32768; - __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): limiting samples size to ", (int)audioFormat->samples); - } - - SDL_CalculateAudioSpec(audioFormat); - - - (*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL); - - if( !jniEnv ) - { - __android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_OpenAudio: Java VM AttachCurrentThread() failed"); - return (-1); // TODO: enable format conversion? Don't know how to do that in SDL - } - - // The returned audioBufferSize may be huge, up to 100 Kb for 44100 because user may have selected large audio buffer to get rid of choppy sound - audioBufferSize = (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaInitAudio, - (jint)audioFormat->freq, (jint)audioFormat->channels, - (jint)(( bytesPerSample == 2 ) ? 1 : 0), (jint)(audioFormat->size) ); - - if( audioBufferSize == 0 ) - { - __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): failed to get audio buffer from JNI"); - ANDROIDAUD_CloseAudio(this); - return(-1); - } - - /* We cannot call DetachCurrentThread() from main thread or we'll crash */ - /* (*jniVM)->DetachCurrentThread(jniVM); */ - - audioFormat->samples = audioBufferSize / bytesPerSample / audioFormat->channels; - audioFormat->size = audioBufferSize; - __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_OpenAudio(): app opened audio bytespersample %d freq %d channels %d bufsize %d", bytesPerSample, audioFormat->freq, (int)audioFormat->channels, audioBufferSize); - - SDL_CalculateAudioSpec(audioFormat); - -#if SDL_VERSION_ATLEAST(1,3,0) - return(1); -#else - return(0); -#endif -} - -static void ANDROIDAUD_CloseAudio(_THIS) -{ - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_CloseAudio()"); - JNIEnv * jniEnv = NULL; - (*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL); - - (*jniEnv)->DeleteGlobalRef(jniEnv, audioBufferJNI); - audioBufferJNI = NULL; - audioBuffer = NULL; - audioBufferSize = 0; - - (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaDeinitAudio ); - - /* We cannot call DetachCurrentThread() from main thread or we'll crash */ - /* (*jniVM)->DetachCurrentThread(jniVM); */ - -} - -/* This function waits until it is possible to write a full sound buffer */ -static void ANDROIDAUD_WaitAudio(_THIS) -{ - /* We will block in PlayAudio(), do nothing here */ -} - -static JNIEnv * jniEnvPlaying = NULL; -static jmethodID JavaFillBuffer = NULL; - -static void ANDROIDAUD_ThreadInit(_THIS) -{ - jclass JavaAudioThreadClass = NULL; - jmethodID JavaInitThread = NULL; - jmethodID JavaGetBuffer = NULL; - jboolean isCopy = JNI_TRUE; - - (*jniVM)->AttachCurrentThread(jniVM, &jniEnvPlaying, NULL); - - JavaAudioThreadClass = (*jniEnvPlaying)->GetObjectClass(jniEnvPlaying, JavaAudioThread); - JavaFillBuffer = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "fillBuffer", "()I"); - - /* HACK: raise our own thread priority to max to get rid of "W/AudioFlinger: write blocked for 54 msecs" errors */ - JavaInitThread = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "initAudioThread", "()I"); - (*jniEnvPlaying)->CallIntMethod( jniEnvPlaying, JavaAudioThread, JavaInitThread ); - - JavaGetBuffer = (*jniEnvPlaying)->GetMethodID(jniEnvPlaying, JavaAudioThreadClass, "getBuffer", "()[B"); - audioBufferJNI = (*jniEnvPlaying)->CallObjectMethod( jniEnvPlaying, JavaAudioThread, JavaGetBuffer ); - audioBufferJNI = (*jniEnvPlaying)->NewGlobalRef(jniEnvPlaying, audioBufferJNI); - audioBuffer = (unsigned char *) (*jniEnvPlaying)->GetByteArrayElements(jniEnvPlaying, audioBufferJNI, &isCopy); - if( !audioBuffer ) - { - __android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_ThreadInit() JNI::GetByteArrayElements() failed! we will crash now"); - return; - } - if( isCopy == JNI_TRUE ) - __android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_ThreadInit(): JNI returns a copy of byte array - no audio will be played"); - - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_ThreadInit()"); - SDL_memset(audioBuffer, this->spec.silence, this->spec.size); -}; - -static void ANDROIDAUD_ThreadDeinit(_THIS) -{ - (*jniVM)->DetachCurrentThread(jniVM); -}; - -static void ANDROIDAUD_PlayAudio(_THIS) -{ - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio()"); - jboolean isCopy = JNI_TRUE; - - (*jniEnvPlaying)->ReleaseByteArrayElements(jniEnvPlaying, audioBufferJNI, (jbyte *)audioBuffer, 0); - audioBuffer = NULL; - - (*jniEnvPlaying)->CallIntMethod( jniEnvPlaying, JavaAudioThread, JavaFillBuffer ); - - audioBuffer = (unsigned char *) (*jniEnvPlaying)->GetByteArrayElements(jniEnvPlaying, audioBufferJNI, &isCopy); - if( !audioBuffer ) - __android_log_print(ANDROID_LOG_ERROR, "libSDL", "ANDROIDAUD_PlayAudio() JNI::GetByteArrayElements() failed! we will crash now"); - - if( isCopy == JNI_TRUE ) - __android_log_print(ANDROID_LOG_INFO, "libSDL", "ANDROIDAUD_PlayAudio() JNI returns a copy of byte array - that's slow"); -} - -int SDL_ANDROID_PauseAudioPlayback(void) -{ - JNIEnv * jniEnv = NULL; - (*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL); - return (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaPauseAudioPlayback ); -}; -int SDL_ANDROID_ResumeAudioPlayback(void) -{ - JNIEnv * jniEnv = NULL; - (*jniVM)->AttachCurrentThread(jniVM, &jniEnv, NULL); - return (*jniEnv)->CallIntMethod( jniEnv, JavaAudioThread, JavaResumeAudioPlayback ); -}; - - -#ifndef SDL_JAVA_PACKAGE_PATH -#error You have to define SDL_JAVA_PACKAGE_PATH to your package path with dots replaced with underscores, for example "com_example_SanAngeles" -#endif -#define JAVA_EXPORT_NAME2(name,package) Java_##package##_##name -#define JAVA_EXPORT_NAME1(name,package) JAVA_EXPORT_NAME2(name,package) -#define JAVA_EXPORT_NAME(name) JAVA_EXPORT_NAME1(name,SDL_JAVA_PACKAGE_PATH) - -JNIEXPORT jint JNICALL JAVA_EXPORT_NAME(AudioThread_nativeAudioInitJavaCallbacks) (JNIEnv * jniEnv, jobject thiz) -{ - jclass JavaAudioThreadClass = NULL; - JavaAudioThread = (*jniEnv)->NewGlobalRef(jniEnv, thiz); - JavaAudioThreadClass = (*jniEnv)->GetObjectClass(jniEnv, JavaAudioThread); - JavaInitAudio = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "initAudio", "(IIII)I"); - JavaDeinitAudio = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "deinitAudio", "()I"); - JavaPauseAudioPlayback = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "pauseAudioPlayback", "()I"); - JavaResumeAudioPlayback = (*jniEnv)->GetMethodID(jniEnv, JavaAudioThreadClass, "resumeAudioPlayback", "()I"); -} - -JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) -{ - jniVM = vm; - return JNI_VERSION_1_2; -}; - -JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) -{ - /* TODO: free JavaAudioThread */ - jniVM = vm; -}; - diff --git a/project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.c b/project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.c new file mode 120000 index 000000000..e3925ed6f --- /dev/null +++ b/project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.c @@ -0,0 +1 @@ +../../../../sdl-1.2/src/audio/android/SDL_androidaudio.c \ No newline at end of file diff --git a/project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.h b/project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.h deleted file mode 100644 index ae1e745d3..000000000 --- a/project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - 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 "SDL_config.h" - -#ifndef _SDL_androidaudio_h -#define _SDL_androidaudio_h - -#include "../SDL_sysaudio.h" - -struct SDL_PrivateAudioData { -}; - -#endif /* _SDL_androidaudio_h */ diff --git a/project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.h b/project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.h new file mode 120000 index 000000000..9f42b6613 --- /dev/null +++ b/project/jni/sdl-1.3/src/audio/android/SDL_androidaudio.h @@ -0,0 +1 @@ +../../../../sdl-1.2/src/audio/android/SDL_androidaudio.h \ No newline at end of file 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 deleted file mode 100644 index 03d3a55fb..000000000 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c +++ /dev/null @@ -1,2183 +0,0 @@ -/* - 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 "SDL_screenkeyboard.h" -#include "jniwrapperstuff.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]; - -static inline SDL_scancode TranslateKey(int scancode) -{ - if ( scancode >= SDL_arraysize(SDL_android_keymap) ) - scancode = KEYCODE_UNKNOWN; - return SDL_android_keymap[scancode]; -} - -static int isTrackballUsed = 0; -static int isMouseUsed = 0; - -enum { RIGHT_CLICK_NONE = 0, RIGHT_CLICK_WITH_MULTITOUCH = 1, RIGHT_CLICK_WITH_PRESSURE = 2, - RIGHT_CLICK_WITH_KEY = 3, RIGHT_CLICK_WITH_TIMEOUT = 4 }; -enum { LEFT_CLICK_NORMAL = 0, LEFT_CLICK_NEAR_CURSOR = 1, LEFT_CLICK_WITH_MULTITOUCH = 2, LEFT_CLICK_WITH_PRESSURE = 3, - LEFT_CLICK_WITH_KEY = 4, LEFT_CLICK_WITH_TIMEOUT = 5, LEFT_CLICK_WITH_TAP = 6, LEFT_CLICK_WITH_TAP_OR_TIMEOUT = 7 }; -static int leftClickMethod = LEFT_CLICK_NORMAL; -static int rightClickMethod = RIGHT_CLICK_NONE; -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; -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}; -static int TrackballDampening = 0; // in milliseconds -static Uint32 lastTrackballAction = 0; -enum { TOUCH_PTR_UP = 0, TOUCH_PTR_MOUSE = 1, TOUCH_PTR_SCREENKB = 2 }; -static int touchPointers[MAX_MULTITOUCH_POINTERS] = {0}; -static int firstMousePointerId = -1; -enum { MAX_MULTITOUCH_GESTURES = 4 }; -static int multitouchGestureKeycode[MAX_MULTITOUCH_GESTURES] = { -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_6)), -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_7)), -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_8)), -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_9)) -}; -static int multitouchGestureKeyPressed[MAX_MULTITOUCH_GESTURES] = { 0, 0, 0, 0 }; -static int multitouchGestureSensitivity = 0; -static int multitouchGestureDist = -1; -static int multitouchGestureAngle = 0; -static int multitouchGestureX = -1; -static int multitouchGestureY = -1; -int SDL_ANDROID_TouchscreenCalibrationWidth = 480; -int SDL_ANDROID_TouchscreenCalibrationHeight = 320; -int SDL_ANDROID_TouchscreenCalibrationX = 0; -int SDL_ANDROID_TouchscreenCalibrationY = 0; -static int leftClickTimeout = 0; -static int rightClickTimeout = 0; -static int mouseInitialX = -1; -static int mouseInitialY = -1; -static unsigned int mouseInitialTime = 0; -static volatile int deferredMouseTap = 0; -static int relativeMovement = 0; -static int relativeMovementSpeed = 2; -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; - -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 ); -} - -void UpdateScreenUnderFingerRect(int x, int y) -{ -#if SDL_VERSION_ATLEAST(1,3,0) - return; -#else - int screenX = SDL_ANDROID_sFakeWindowWidth, screenY = SDL_ANDROID_sFakeWindowHeight; - if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_NONE ) - return; - - if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER ) - { - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = screenX / 4; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = screenY / 4; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = x - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w/2; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = y - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h/2; - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = 0; - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = 0; - - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x > screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w; - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y > screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h; - - SDL_ANDROID_ShowScreenUnderFingerRect.w = SDL_ANDROID_ShowScreenUnderFingerRectSrc.w * 3 / 2; - SDL_ANDROID_ShowScreenUnderFingerRect.h = SDL_ANDROID_ShowScreenUnderFingerRectSrc.h * 3 / 2; - SDL_ANDROID_ShowScreenUnderFingerRect.x = x + SDL_ANDROID_ShowScreenUnderFingerRect.w/10; - SDL_ANDROID_ShowScreenUnderFingerRect.y = y - SDL_ANDROID_ShowScreenUnderFingerRect.h*11/10; - if( SDL_ANDROID_ShowScreenUnderFingerRect.x < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRect.x = 0; - if( SDL_ANDROID_ShowScreenUnderFingerRect.y < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRect.y = 0; - if( SDL_ANDROID_ShowScreenUnderFingerRect.x + SDL_ANDROID_ShowScreenUnderFingerRect.w >= screenX ) - SDL_ANDROID_ShowScreenUnderFingerRect.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRect.w - 1; - if( SDL_ANDROID_ShowScreenUnderFingerRect.y + SDL_ANDROID_ShowScreenUnderFingerRect.h >= screenY ) - SDL_ANDROID_ShowScreenUnderFingerRect.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRect.h - 1; - if( InsideRect(&SDL_ANDROID_ShowScreenUnderFingerRect, x, y) ) - SDL_ANDROID_ShowScreenUnderFingerRect.x = x - SDL_ANDROID_ShowScreenUnderFingerRect.w*11/10 - 1; - } - if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_SCREEN_TRANSFORM ) - { - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = screenX / 3; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = screenY / 3; - //SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = x - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w/2; - //SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = y - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h/2; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = x * (screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w) / screenX; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = y * (screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h) / screenY; - - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = 0; - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = 0; - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x > screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w; - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y > screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h; - - SDL_ANDROID_ShowScreenUnderFingerRect.w = screenX * 2 / 3; - SDL_ANDROID_ShowScreenUnderFingerRect.h = screenY * 2 / 3; - //SDL_ANDROID_ShowScreenUnderFingerRect.x = x - SDL_ANDROID_ShowScreenUnderFingerRect.w/2; - //SDL_ANDROID_ShowScreenUnderFingerRect.y = y - SDL_ANDROID_ShowScreenUnderFingerRect.h/2; - SDL_ANDROID_ShowScreenUnderFingerRect.x = x * (screenX - SDL_ANDROID_ShowScreenUnderFingerRect.w) / screenX; - SDL_ANDROID_ShowScreenUnderFingerRect.y = y * (screenY - SDL_ANDROID_ShowScreenUnderFingerRect.h) / screenY; - - - if( SDL_ANDROID_ShowScreenUnderFingerRect.x > SDL_ANDROID_ShowScreenUnderFingerRectSrc.x ) - SDL_ANDROID_ShowScreenUnderFingerRect.x = SDL_ANDROID_ShowScreenUnderFingerRectSrc.x; - if( SDL_ANDROID_ShowScreenUnderFingerRect.y > SDL_ANDROID_ShowScreenUnderFingerRectSrc.y ) - SDL_ANDROID_ShowScreenUnderFingerRect.y = SDL_ANDROID_ShowScreenUnderFingerRectSrc.y; - if( SDL_ANDROID_ShowScreenUnderFingerRect.x + SDL_ANDROID_ShowScreenUnderFingerRect.w < SDL_ANDROID_ShowScreenUnderFingerRectSrc.x + SDL_ANDROID_ShowScreenUnderFingerRectSrc.w ) - SDL_ANDROID_ShowScreenUnderFingerRect.x = SDL_ANDROID_ShowScreenUnderFingerRectSrc.x + SDL_ANDROID_ShowScreenUnderFingerRectSrc.w - SDL_ANDROID_ShowScreenUnderFingerRect.w; - if( SDL_ANDROID_ShowScreenUnderFingerRect.y + SDL_ANDROID_ShowScreenUnderFingerRect.h < SDL_ANDROID_ShowScreenUnderFingerRectSrc.y + SDL_ANDROID_ShowScreenUnderFingerRectSrc.h ) - SDL_ANDROID_ShowScreenUnderFingerRect.y = SDL_ANDROID_ShowScreenUnderFingerRectSrc.y + SDL_ANDROID_ShowScreenUnderFingerRectSrc.h - SDL_ANDROID_ShowScreenUnderFingerRect.h; - - if( SDL_ANDROID_ShowScreenUnderFingerRect.x < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRect.x = 0; - if( SDL_ANDROID_ShowScreenUnderFingerRect.y < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRect.y = 0; - if( SDL_ANDROID_ShowScreenUnderFingerRect.x > screenX - SDL_ANDROID_ShowScreenUnderFingerRect.w ) - SDL_ANDROID_ShowScreenUnderFingerRect.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRect.w; - if( SDL_ANDROID_ShowScreenUnderFingerRect.y > screenY - SDL_ANDROID_ShowScreenUnderFingerRect.h ) - SDL_ANDROID_ShowScreenUnderFingerRect.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRect.h; - } - if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_FULLSCREEN_MAGNIFIER ) - { - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = screenX / 2; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = screenY / 2; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = x - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w/2; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = y - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h/2; - - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = 0; - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y < 0 ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = 0; - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.x > screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.x = screenX - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w; - if( SDL_ANDROID_ShowScreenUnderFingerRectSrc.y > screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h ) - SDL_ANDROID_ShowScreenUnderFingerRectSrc.y = screenY - SDL_ANDROID_ShowScreenUnderFingerRectSrc.h; - - SDL_ANDROID_ShowScreenUnderFingerRect.x = 0; - SDL_ANDROID_ShowScreenUnderFingerRect.y = 0; - SDL_ANDROID_ShowScreenUnderFingerRect.w = screenX; - SDL_ANDROID_ShowScreenUnderFingerRect.h = screenY; - } -#endif -} - - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMotionEvent) ( JNIEnv* env, jobject thiz, jint x, jint y, jint action, jint pointerId, jint force, jint radius ) -{ - // TODO: this method is damn huge - int i; -#if SDL_VERSION_ATLEAST(1,3,0) - - SDL_Window * window = SDL_GetFocusWindow(); - if( !window ) - return; - -#define SDL_ANDROID_sFakeWindowWidth window->w -#define SDL_ANDROID_sFakeWindowHeight window->h - -#else - if( !SDL_CurrentVideoSurface ) - return; -#endif - if(pointerId < 0) - pointerId = 0; - if(pointerId > MAX_MULTITOUCH_POINTERS) - pointerId = MAX_MULTITOUCH_POINTERS; - - // The touch is passed either to on-screen keyboard or as mouse event for all duration of touch between down and up, - // even if the finger is not anymore above screen kb button it will not acr as mouse event, and if it's initially - // touches the screen outside of screen kb it won't trigger button keypress - - // I think it's more logical this way - if( SDL_ANDROID_isTouchscreenKeyboardUsed && ( action == MOUSE_DOWN || touchPointers[pointerId] == TOUCH_PTR_SCREENKB ) ) - { - if( SDL_ANDROID_processTouchscreenKeyboard(x, y, action, pointerId) && action == MOUSE_DOWN ) - touchPointers[pointerId] = TOUCH_PTR_SCREENKB; - if( touchPointers[pointerId] == TOUCH_PTR_SCREENKB ) - { - if( action == MOUSE_UP ) - touchPointers[pointerId] = TOUCH_PTR_UP; - return; - } - } - - if( action == MOUSE_DOWN ) - { - touchPointers[pointerId] = TOUCH_PTR_MOUSE; - firstMousePointerId = -1; - for( i = 0; i < MAX_MULTITOUCH_POINTERS; i++ ) - { - if( touchPointers[i] == TOUCH_PTR_MOUSE ) - { - firstMousePointerId = i; - break; - } - } - } - - x -= SDL_ANDROID_TouchscreenCalibrationX; - y -= SDL_ANDROID_TouchscreenCalibrationY; -#if SDL_VIDEO_RENDER_RESIZE - // Translate mouse coordinates - - x = x * SDL_ANDROID_sFakeWindowWidth / SDL_ANDROID_TouchscreenCalibrationWidth; - y = y * SDL_ANDROID_sFakeWindowHeight / SDL_ANDROID_TouchscreenCalibrationHeight; - if( x < 0 ) - x = 0; - if( x > SDL_ANDROID_sFakeWindowWidth ) - x = SDL_ANDROID_sFakeWindowWidth; - if( y < 0 ) - y = 0; - if( y > SDL_ANDROID_sFakeWindowHeight ) - y = SDL_ANDROID_sFakeWindowHeight; -#else - x = x * SDL_ANDROID_sRealWindowWidth / SDL_ANDROID_TouchscreenCalibrationWidth; - y = y * SDL_ANDROID_sRealWindowHeight / SDL_ANDROID_TouchscreenCalibrationHeight; -#endif - - if( action == MOUSE_UP ) - { - multitouchGestureX = -1; - multitouchGestureY = -1; - multitouchGestureDist = -1; - for(i = 0; i < MAX_MULTITOUCH_GESTURES; i++) - { - if( multitouchGestureKeyPressed[i] ) - { - multitouchGestureKeyPressed[i] = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[i] ); - } - } - } - else if( !hardwareMouseDetected ) - { - if( firstMousePointerId != pointerId ) - { - multitouchGestureX = x; - multitouchGestureY = y; - } - if( firstMousePointerId == pointerId && multitouchGestureX >= 0 ) - { - int dist = abs( x - multitouchGestureX ) + abs( y - multitouchGestureY ); - int angle = atan2i( y - multitouchGestureY, x - multitouchGestureX ); - if( multitouchGestureDist < 0 ) - { - multitouchGestureDist = dist; - multitouchGestureAngle = angle; - } - else - { - int distMaxDiff = SDL_ANDROID_sFakeWindowHeight / ( 1 + (1 + multitouchGestureSensitivity) * 2 ); - int angleMaxDiff = atan2i_PI / ( 1 + (1 + multitouchGestureSensitivity) * 2 ); - if( dist - multitouchGestureDist > distMaxDiff ) - { - multitouchGestureKeyPressed[0] = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[0] ); - } - else - if( multitouchGestureKeyPressed[0] ) - { - multitouchGestureKeyPressed[0] = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[0] ); - } - if( multitouchGestureDist - dist > distMaxDiff ) - { - multitouchGestureKeyPressed[1] = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[1] ); - } - else - if( multitouchGestureKeyPressed[1] ) - { - multitouchGestureKeyPressed[1] = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[1] ); - } - - int angleDiff = angle - multitouchGestureAngle; - - while( angleDiff < atan2i_PI ) - angleDiff += atan2i_PI * 2; - while( angleDiff > atan2i_PI ) - angleDiff -= atan2i_PI * 2; - - if( angleDiff < -angleMaxDiff ) - { - multitouchGestureKeyPressed[2] = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[2] ); - } - else - if( multitouchGestureKeyPressed[2] ) - { - multitouchGestureKeyPressed[2] = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[2] ); - } - if( angleDiff > angleMaxDiff ) - { - multitouchGestureKeyPressed[3] = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, multitouchGestureKeycode[3] ); - } - else - if( multitouchGestureKeyPressed[3] ) - { - multitouchGestureKeyPressed[3] = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, multitouchGestureKeycode[3] ); - } - } - } - } - - if( isMultitouchUsed ) - { -#if SDL_VERSION_ATLEAST(1,3,0) - // Use nifty SDL 1.3 multitouch API - if( action == MOUSE_MOVE ) - SDL_ANDROID_MainThreadPushMultitouchMotion(pointerId, x, y, force + radius); - else - SDL_ANDROID_MainThreadPushMultitouchButton(pointerId, action == MOUSE_DOWN ? 1 : 0, x, y, force + radius); -#endif - - if( action == MOUSE_DOWN ) - SDL_ANDROID_MainThreadPushJoystickButton(0, pointerId, SDL_PRESSED); - SDL_ANDROID_MainThreadPushJoystickBall(0, pointerId, x, y); - SDL_ANDROID_MainThreadPushJoystickAxis(0, pointerId+4, force + radius); // Radius is more sensitive usually - if( action == MOUSE_UP ) - SDL_ANDROID_MainThreadPushJoystickButton(0, pointerId, SDL_RELEASED); - } - if( !isMouseUsed && !SDL_ANDROID_isTouchscreenKeyboardUsed ) - { - SDL_keysym keysym; - if( action != MOUSE_MOVE ) - SDL_ANDROID_MainThreadPushKeyboardKey( action == MOUSE_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_ANDROID_GetScreenKeyboardButtonKey(SDL_ANDROID_SCREENKEYBOARD_BUTTON_0) ); - return; - } - - if( !isMouseUsed ) - return; - - if( pointerId == firstMousePointerId ) - { - if( relativeMovement ) - { - if( action == MOUSE_DOWN ) - { - relativeMovementX = currentMouseX - x; - relativeMovementY = currentMouseY - y; - } - x += relativeMovementX; - y += relativeMovementY; - - int diffX = x - currentMouseX; - int diffY = y - currentMouseY; - int coeff = relativeMovementSpeed + 2; - if( relativeMovementSpeed > 2 ) - coeff += relativeMovementSpeed - 2; - diffX = diffX * coeff / 4; - diffY = diffY * coeff / 4; - if( relativeMovementAccel > 0 ) - { - unsigned int newTime = SDL_GetTicks(); - if( newTime - relativeMovementTime > 0 ) - { - diffX += diffX * ( relativeMovementAccel * 30 ) / (int)(newTime - relativeMovementTime); - diffY += diffY * ( relativeMovementAccel * 30 ) / (int)(newTime - relativeMovementTime); - } - relativeMovementTime = newTime; - } - diffX -= x - currentMouseX; - diffY -= y - currentMouseY; - x += diffX; - y += diffY; - relativeMovementX += diffX; - relativeMovementY += diffY; - - diffX = x; - diffY = y; - if( x < 0 ) - x = 0; - if( x > SDL_ANDROID_sFakeWindowWidth ) - x = SDL_ANDROID_sFakeWindowWidth; - if( y < 0 ) - y = 0; - if( y > SDL_ANDROID_sFakeWindowHeight ) - y = SDL_ANDROID_sFakeWindowHeight; - relativeMovementX += x - diffX; - relativeMovementY += y - diffY; - } - if( action == MOUSE_UP ) - { - if( rightClickMethod != RIGHT_CLICK_WITH_KEY ) - SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_RIGHT ); - - if( mouseInitialX >= 0 && mouseInitialY >= 0 && ( - leftClickMethod == LEFT_CLICK_WITH_TAP || leftClickMethod == LEFT_CLICK_WITH_TAP_OR_TIMEOUT ) && - abs(mouseInitialX - x) < SDL_ANDROID_sFakeWindowHeight / 16 && - abs(mouseInitialY - y) < SDL_ANDROID_sFakeWindowHeight / 16 && - SDL_GetTicks() - mouseInitialTime < 700 ) - { - SDL_ANDROID_MainThreadPushMouseMotion(mouseInitialX, mouseInitialY); - SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); - deferredMouseTap = 2; - mouseInitialX = -1; - mouseInitialY = -1; - } - else - { - if( leftClickMethod != LEFT_CLICK_WITH_KEY ) - SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT ); - } - - SDL_ANDROID_ShowScreenUnderFingerRect.w = SDL_ANDROID_ShowScreenUnderFingerRect.h = 0; - SDL_ANDROID_ShowScreenUnderFingerRectSrc.w = SDL_ANDROID_ShowScreenUnderFingerRectSrc.h = 0; - 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); - else - SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y); - } - moveMouseWithKbX = -1; - moveMouseWithKbY = -1; - moveMouseWithKbSpeedX = 0; - 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 ) - { - SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); - moveMouseWithKbX = currentMouseX; - moveMouseWithKbY = currentMouseY; - moveMouseWithKbSpeedX = 0; - moveMouseWithKbSpeedY = 0; - action = MOUSE_MOVE; - } - else - if( leftClickMethod == LEFT_CLICK_NORMAL ) - { - SDL_ANDROID_MainThreadPushMouseMotion(x, y); - if( !hardwareMouseDetected || currentMouseButtons == 0 ) - SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); - } - else - { - SDL_ANDROID_MainThreadPushMouseMotion(x, y); - action == MOUSE_MOVE; - mouseInitialX = x; - mouseInitialY = y; - mouseInitialTime = SDL_GetTicks(); - } - UpdateScreenUnderFingerRect(x, y); - } - if( action == MOUSE_MOVE ) - { - if( moveMouseWithKbX >= 0 ) - { - // Mouse lazily follows magnifying glass, not very intuitive for drag&drop - /* - if( abs(moveMouseWithKbX - x) > SDL_ANDROID_sFakeWindowWidth / 12 ) - moveMouseWithKbSpeedX += moveMouseWithKbX > x ? -1 : 1; - else - moveMouseWithKbSpeedX = moveMouseWithKbSpeedX * 2 / 3; - if( abs(moveMouseWithKbY - y) > SDL_ANDROID_sFakeWindowHeight / 12 ) - moveMouseWithKbSpeedY += moveMouseWithKbY > y ? -1 : 1; - else - moveMouseWithKbSpeedY = moveMouseWithKbSpeedY * 2 / 3; - - moveMouseWithKbX += moveMouseWithKbSpeedX; - 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 ) - { - moveMouseWithKbX = -1; - moveMouseWithKbY = -1; - moveMouseWithKbSpeedX = 0; - moveMouseWithKbSpeedY = 0; - SDL_ANDROID_MainThreadPushMouseMotion(x, y); - } - else - SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); - } - else - { - SDL_ANDROID_MainThreadPushMouseMotion(x, y); - } - - if( rightClickMethod == RIGHT_CLICK_WITH_PRESSURE || leftClickMethod == LEFT_CLICK_WITH_PRESSURE ) - { - int button = (leftClickMethod == LEFT_CLICK_WITH_PRESSURE) ? SDL_BUTTON_LEFT : SDL_BUTTON_RIGHT; - int buttonState = ( force > maxForce || radius > maxRadius ); - if( button == SDL_BUTTON_RIGHT ) - SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT ); - SDL_ANDROID_MainThreadPushMouseButton( buttonState ? SDL_PRESSED : SDL_RELEASED, button ); - } - if( mouseInitialX >= 0 && mouseInitialY >= 0 && ( - leftClickMethod == LEFT_CLICK_WITH_TIMEOUT || leftClickMethod == LEFT_CLICK_WITH_TAP || - leftClickMethod == LEFT_CLICK_WITH_TAP_OR_TIMEOUT || rightClickMethod == RIGHT_CLICK_WITH_TIMEOUT ) ) - { - if( abs(mouseInitialX - x) >= SDL_ANDROID_sFakeWindowHeight / 15 || abs(mouseInitialY - y) >= SDL_ANDROID_sFakeWindowHeight / 15 ) - { - mouseInitialX = -1; - mouseInitialY = -1; - } - else - { - if( leftClickMethod == LEFT_CLICK_WITH_TIMEOUT || leftClickMethod == LEFT_CLICK_WITH_TAP_OR_TIMEOUT ) - { - if( SDL_GetTicks() - mouseInitialTime > leftClickTimeout ) - { - //SDL_ANDROID_MainThreadPushMouseMotion(mouseInitialX, mouseInitialY); - SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); - mouseInitialX = -1; - mouseInitialY = -1; - } - } - if( rightClickMethod == RIGHT_CLICK_WITH_TIMEOUT ) - { - if( SDL_GetTicks() - mouseInitialTime > rightClickTimeout ) - { - //SDL_ANDROID_MainThreadPushMouseMotion(mouseInitialX, mouseInitialY); - SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_RIGHT ); - mouseInitialX = -1; - mouseInitialY = -1; - } - } - } - } - if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_MAGNIFIER ) - UpdateScreenUnderFingerRect(x, y); - } - if( SDL_ANDROID_ShowScreenUnderFinger == ZOOM_SCREEN_TRANSFORM || - SDL_ANDROID_ShowScreenUnderFinger == ZOOM_FULLSCREEN_MAGNIFIER ) - UpdateScreenUnderFingerRect(x, y); - } - if( pointerId != firstMousePointerId && (action == MOUSE_DOWN || action == MOUSE_UP) ) - { - if( leftClickMethod == LEFT_CLICK_WITH_MULTITOUCH ) - { - SDL_ANDROID_MainThreadPushMouseButton( (action == MOUSE_DOWN) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT ); - } - else if( rightClickMethod == RIGHT_CLICK_WITH_MULTITOUCH ) - { - SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_LEFT ); - SDL_ANDROID_MainThreadPushMouseButton( (action == MOUSE_DOWN) ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT ); - } - } - - if( action == MOUSE_UP ) - { - touchPointers[pointerId] = TOUCH_PTR_UP; - firstMousePointerId = -1; - for( i = 0; i < MAX_MULTITOUCH_POINTERS; i++ ) - { - if( touchPointers[i] == TOUCH_PTR_MOUSE ) - { - firstMousePointerId = i; - break; - } - } - } - - if( action == MOUSE_HOVER && !relativeMovement ) - { - SDL_ANDROID_MainThreadPushMouseMotion(x, y); - } -} - -void ProcessDeferredMouseTap() -{ - if( deferredMouseTap > 0 ) - { - deferredMouseTap--; - if( deferredMouseTap <= 0 ) - { -#if SDL_VERSION_ATLEAST(1,3,0) - SDL_Window * window = SDL_GetFocusWindow(); - if( !window ) - return; -#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); - 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); - } -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeTouchpad) ( JNIEnv* env, jobject thiz, jint x, jint y, jint down, jint multitouch) -{ - if( !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; - } - else - { - // x and y from 0 to 65535 - if( moveMouseWithKbX < 0 ) - { - moveMouseWithKbX = currentMouseX; - moveMouseWithKbY = currentMouseY; - } - moveMouseWithKbSpeedX = (x - 32767) / 8192; - moveMouseWithKbSpeedY = (y - 32767) / 8192; - //moveMouseWithKbX += moveMouseWithKbSpeedX; - //moveMouseWithKbY += moveMouseWithKbSpeedY; - SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); - moveMouseWithKbAccelUpdateNeeded = 1; - - if( multitouch ) - SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_RIGHT ); - else - if( abs(x - 32767) < 8192 && abs(y - 32767) < 8192 ) - SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_LEFT ); - } -} - -void SDL_ANDROID_WarpMouse(int x, int y) -{ - if(!relativeMovement) - { - //SDL_ANDROID_MainThreadPushMouseMotion(x, 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; - SDL_ANDROID_MainThreadPushMouseMotion(x, y); - } -}; - -static int processAndroidTrackball(int key, int action); - -JNIEXPORT jint JNICALL -JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeKey) ( JNIEnv* env, jobject thiz, jint key, jint action ) -{ -#if SDL_VERSION_ATLEAST(1,3,0) -#else - if( !SDL_CurrentVideoSurface ) - return 1; -#endif - - if( isTrackballUsed ) - if( processAndroidTrackball(key, action) ) - return 1; - if( key == rightClickKey && rightClickMethod == RIGHT_CLICK_WITH_KEY ) - { - SDL_ANDROID_MainThreadPushMouseButton( action ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_RIGHT ); - return 1; - } - if( (key == leftClickKey && leftClickMethod == LEFT_CLICK_WITH_KEY) || (clickMouseWithDpadCenter && key == KEYCODE_DPAD_CENTER) ) - { - SDL_ANDROID_MainThreadPushMouseButton( action ? SDL_PRESSED : SDL_RELEASED, SDL_BUTTON_LEFT ); - return 1; - } - - if( TranslateKey(key) == SDLK_NO_REMAP || TranslateKey(key) == SDLK_UNKNOWN ) - return 0; - - SDL_ANDROID_MainThreadPushKeyboardKey( action ? SDL_PRESSED : SDL_RELEASED, TranslateKey(key) ); - return 1; -} - -static char * textInputBuffer = NULL; -int textInputBufferLen = 0; -int textInputBufferPos = 0; - -void SDL_ANDROID_TextInputInit(char * buffer, int len) -{ - textInputBuffer = buffer; - textInputBufferLen = len; - textInputBufferPos = 0; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoRenderer_nativeTextInput) ( JNIEnv* env, jobject thiz, jint ascii, jint unicode ) -{ - if( ascii == 10 ) - ascii = SDLK_RETURN; - if( !textInputBuffer ) - SDL_ANDROID_MainThreadPushText(ascii, unicode); - else - { - if( textInputBufferPos < textInputBufferLen + 4 && ascii != SDLK_RETURN && ascii != '\r' && ascii != '\n' ) - { - textInputBufferPos += UnicodeToUtf8(unicode, textInputBuffer + textInputBufferPos); - } - } -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoRenderer_nativeTextInputFinished) ( JNIEnv* env, jobject thiz ) -{ - textInputBuffer = NULL; - SDL_ANDROID_TextInputFinished(); -} - -static void updateOrientation ( float accX, float accY, float accZ ); - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(AccelerometerReader_nativeAccelerometer) ( JNIEnv* env, jobject thiz, jfloat accPosX, jfloat accPosY, jfloat accPosZ ) -{ -#if SDL_VERSION_ATLEAST(1,3,0) -#else - if( !SDL_CurrentVideoSurface ) - return; -#endif - // 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 = 0.00001f; - - updateOrientation (accPosX/normal, accPosY/normal, 0.0f); -} - - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(AccelerometerReader_nativeOrientation) ( JNIEnv* env, jobject thiz, jfloat accX, jfloat accY, jfloat accZ ) -{ -#if SDL_VERSION_ATLEAST(1,3,0) -#else - if( !SDL_CurrentVideoSurface ) - return; -#endif - updateOrientation (accX, accY, accZ); // TODO: make values in range 0.0:1.0 -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetTrackballUsed) ( JNIEnv* env, jobject thiz) -{ - isTrackballUsed = 1; -} - -static int getClickTimeout(int v) -{ - switch(v) - { - case 0: return 200; - case 1: return 300; - case 2: return 400; - case 3: return 700; - case 4: return 1000; - } - return 1000; -} - -// Mwahaha overkill! -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz, - jint RightClickMethod, jint ShowScreenUnderFinger, jint LeftClickMethod, - jint MoveMouseWithJoystick, jint ClickMouseWithDpad, - jint MaxForce, jint MaxRadius, - jint MoveMouseWithJoystickSpeed, jint MoveMouseWithJoystickAccel, - jint LeftClickKeycode, jint RightClickKeycode, - jint LeftClickTimeout, jint RightClickTimeout, - jint RelativeMovement, jint RelativeMovementSpeed, jint RelativeMovementAccel, - jint ShowMouseCursor) -{ - isMouseUsed = 1; - rightClickMethod = RightClickMethod; - SDL_ANDROID_ShowScreenUnderFinger = ShowScreenUnderFinger; - moveMouseWithArrowKeys = MoveMouseWithJoystick; - clickMouseWithDpadCenter = ClickMouseWithDpad; - leftClickMethod = LeftClickMethod; - maxForce = MaxForce; - maxRadius = MaxRadius; - moveMouseWithKbSpeed = MoveMouseWithJoystickSpeed + 1; - moveMouseWithKbAccel = MoveMouseWithJoystickAccel; - leftClickKey = LeftClickKeycode; - rightClickKey = RightClickKeycode; - leftClickTimeout = getClickTimeout(LeftClickTimeout); - rightClickTimeout = getClickTimeout(RightClickTimeout); - relativeMovement = RelativeMovement; - relativeMovementSpeed = RelativeMovementSpeed; - relativeMovementAccel = RelativeMovementAccel; - SDL_ANDROID_ShowMouseCursor = ShowMouseCursor; - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "relativeMovementSpeed %d relativeMovementAccel %d", relativeMovementSpeed, relativeMovementAccel); -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeHardwareMouseDetected) (JNIEnv* env, jobject thiz, int detected) -{ - if( !isMouseUsed ) - return; - - static struct { - int leftClickMethod; - int ShowScreenUnderFinger; - int leftClickTimeout; - int relativeMovement; - int ShowMouseCursor; - } cfg = { 0 }; - - if( hardwareMouseDetected != detected ) - { - hardwareMouseDetected = detected; - if(detected) - { - cfg.leftClickMethod = leftClickMethod; - cfg.ShowScreenUnderFinger = SDL_ANDROID_ShowScreenUnderFinger; - cfg.leftClickTimeout = leftClickTimeout; - cfg.relativeMovement = relativeMovement; - cfg.ShowMouseCursor = SDL_ANDROID_ShowMouseCursor; - - leftClickMethod = LEFT_CLICK_NORMAL; - SDL_ANDROID_ShowScreenUnderFinger = 0; - leftClickTimeout = 0; - relativeMovement = 0; - SDL_ANDROID_ShowMouseCursor = 0; - } - else - { - leftClickMethod = cfg.leftClickMethod; - SDL_ANDROID_ShowScreenUnderFinger = cfg.ShowScreenUnderFinger; - leftClickTimeout = cfg.leftClickTimeout; - relativeMovement = cfg.relativeMovement; - SDL_ANDROID_ShowMouseCursor = cfg.ShowMouseCursor; - } - } -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseButtonsPressed) (JNIEnv* env, jobject thiz, jint buttonId, jint pressedState) -{ - int btn = SDL_BUTTON_LEFT; - if( !isMouseUsed ) - return; - - switch(buttonId) - { - case MOUSE_HW_BUTTON_LEFT: - btn = SDL_BUTTON_LEFT; - break; - case MOUSE_HW_BUTTON_RIGHT: - btn = SDL_BUTTON_RIGHT; - break; - case MOUSE_HW_BUTTON_MIDDLE: - btn = SDL_BUTTON_MIDDLE; - break; - case MOUSE_HW_BUTTON_BACK: - btn = SDL_BUTTON_X1; - break; - case MOUSE_HW_BUTTON_FORWARD: - btn = SDL_BUTTON_X2; - break; - } - SDL_ANDROID_MainThreadPushMouseButton( pressedState ? SDL_PRESSED : SDL_RELEASED, btn ); -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeMouseWheel) (JNIEnv* env, jobject thiz, jint scrollX, jint scrollY) -{ -#if SDL_VERSION_ATLEAST(1,3,0) - SDL_ANDROID_MainThreadPushMouseWheel( scrollX, scrollY ); -#else - // TODO: direction might get inverted - for( ; scrollX > 0; scrollX-- ) - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_RIGHT) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) ); - } - for( ; scrollX < 0; scrollX++ ) - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_LEFT) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) ); - } - for( ; scrollY > 0; scrollY-- ) - { - if(!isMouseUsed) - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_DOWN) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) ); - } - else - { - SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_WHEELDOWN ); - SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_WHEELDOWN ); - } - } - for( ; scrollY < 0; scrollY++ ) - { - if(!isMouseUsed) - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_UP) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) ); - } - else - { - SDL_ANDROID_MainThreadPushMouseButton( SDL_PRESSED, SDL_BUTTON_WHEELUP ); - SDL_ANDROID_MainThreadPushMouseButton( SDL_RELEASED, SDL_BUTTON_WHEELUP ); - } - } -#endif -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetJoystickUsed) (JNIEnv* env, jobject thiz) -{ - SDL_ANDROID_isJoystickUsed = 1; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetAccelerometerUsed) (JNIEnv* env, jobject thiz) -{ - SDL_ANDROID_isAccelerometerUsed = 1; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetMultitouchUsed) ( JNIEnv* env, jobject thiz) -{ - isMultitouchUsed = 1; -} - - -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_nativeSetAccelerometerSettings) ( JNIEnv* env, jobject thiz, jint sensitivity, jint centerPos) -{ - 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; joystickSensitivity = 32767.0f * 2.0f; // Medium sensitivity - } - if( sensitivity == 2 ) - { - dx = 0.2; dy = 0.25; dz = 0.25; joystickSensitivity = 32767.0f; // Slow sensitivity - } - accelerometerCenterPos = centerPos; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetTrackballDampening) ( JNIEnv* env, jobject thiz, jint value) -{ - TrackballDampening = (value * 200); -} - -void updateOrientation ( float accX, float accY, float accZ ) -{ - SDL_keysym keysym; - // TODO: ask user for accelerometer precision from Java - - static float midX = 0, midY = 0, midZ = 0; - static int pressLeft = 0, pressRight = 0, pressUp = 0, pressDown = 0, pressR = 0, pressL = 0; - - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): %f %f %f", accX, accY, accZ); - - if( SDL_ANDROID_isAccelerometerUsed ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): sending joystick event"); - SDL_ANDROID_MainThreadPushJoystickAxis(0, 2, (Sint16)(fminf(32767.0f, fmax(-32767.0f, (accX) * 32767.0f)))); - SDL_ANDROID_MainThreadPushJoystickAxis(0, 3, (Sint16)(fminf(32767.0f, fmax(-32767.0f, -(accY) * 32767.0f)))); - //SDL_ANDROID_MainThreadPushJoystickAxis(0, 2, (Sint16)(fminf(32767.0f, fmax(-32767.0f, -(accZ) * 32767.0f)))); - return; - } - - if( accelerometerCenterPos == ACCELEROMETER_CENTER_FIXED_START ) - { - accelerometerCenterPos = ACCELEROMETER_CENTER_FIXED_HORIZ; - midX = accX; - midY = accY; - midZ = accZ; - } - - if( SDL_ANDROID_isJoystickUsed ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "updateOrientation(): sending joystick event"); - SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, (Sint16)(fminf(32767.0f, fmax(-32767.0f, (accX - midX) * joystickSensitivity)))); - SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, (Sint16)(fminf(32767.0f, fmax(-32767.0f, -(accY - midY) * joystickSensitivity)))); - //SDL_ANDROID_MainThreadPushJoystickAxis(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; - } - return; - } - - if( accX < midX - dx ) - { - if( !pressLeft ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press left, acc %f mid %f d %f", accX, midX, dx); - pressLeft = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_LEFT) ); - } - } - else - { - if( pressLeft ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release left, acc %f mid %f d %f", accX, midX, dx); - pressLeft = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) ); - } - } - if( accX < midX - dx*2 ) - midX = accX + dx*2; - - if( accX > midX + dx ) - { - if( !pressRight ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press right, acc %f mid %f d %f", accX, midX, dx); - pressRight = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_RIGHT) ); - } - } - else - { - if( pressRight ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release right, acc %f mid %f d %f", accX, midX, dx); - pressRight = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) ); - } - } - if( accX > midX + dx*2 ) - midX = accX - dx*2; - - if( accY < midY - dy ) - { - if( !pressUp ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press up, acc %f mid %f d %f", accY, midY, dy); - pressUp = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_DOWN) ); - } - } - else - { - if( pressUp ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release up, acc %f mid %f d %f", accY, midY, dy); - pressUp = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) ); - } - } - if( accY < midY - dy*2 ) - midY = accY + dy*2; - - if( accY > midY + dy ) - { - if( !pressDown ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: press down, acc %f mid %f d %f", accY, midY, dy); - pressDown = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_DPAD_UP) ); - } - } - else - { - if( pressDown ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "Accelerometer: release down, acc %f mid %f d %f", accY, midY, dy); - pressDown = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) ); - } - } - if( accY > midY + dy*2 ) - midY = accY - dy*2; - - if( accZ < midZ - dz ) - { - if( !pressL ) - { - pressL = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_ALT_LEFT) ); - } - } - else - { - if( pressL ) - { - pressL = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_ALT_LEFT) ); - } - } - if( accZ < midZ - dz*2 ) - midZ = accZ + dz*2; - - if( accZ > midZ + dz ) - { - if( !pressR ) - { - pressR = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(KEYCODE_ALT_RIGHT) ); - } - } - else - { - if( pressR ) - { - pressR = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_ALT_RIGHT) ); - } - } - if( accZ > midZ + dz*2 ) - midZ = accZ - dz*2; - -} - -static int leftPressed = 0, rightPressed = 0, upPressed = 0, downPressed = 0; - -int processAndroidTrackball(int key, int action) -{ - SDL_keysym keysym; - - if( ! action && ( - key == KEYCODE_DPAD_UP || - key == KEYCODE_DPAD_DOWN || - key == KEYCODE_DPAD_LEFT || - key == KEYCODE_DPAD_RIGHT ) ) - return 1; - lastTrackballAction = SDL_GetTicks(); - - if( key == KEYCODE_DPAD_UP ) - { - if( downPressed ) - { - downPressed = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) ); - return 1; - } - if( !upPressed ) - { - upPressed = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); - } - else - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); - } - return 1; - } - - if( key == KEYCODE_DPAD_DOWN ) - { - if( upPressed ) - { - upPressed = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) ); - return 1; - } - if( !upPressed ) - { - downPressed = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); - } - else - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); - } - return 1; - } - - if( key == KEYCODE_DPAD_LEFT ) - { - if( rightPressed ) - { - rightPressed = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) ); - return 1; - } - if( !leftPressed ) - { - leftPressed = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); - } - else - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); - } - return 1; - } - - if( key == KEYCODE_DPAD_RIGHT ) - { - if( leftPressed ) - { - leftPressed = 0; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) ); - return 1; - } - if( !rightPressed ) - { - rightPressed = 1; - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); - } - else - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(key) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, TranslateKey(key) ); - } - return 1; - } - - return 0; -} - -void SDL_ANDROID_processAndroidTrackballDampening() -{ - if( !TrackballDampening ) - return; - if( SDL_GetTicks() > TrackballDampening + lastTrackballAction ) - { - if( upPressed ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_UP) ); - if( downPressed ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_DOWN) ); - if( leftPressed ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_LEFT) ); - if( rightPressed ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, TranslateKey(KEYCODE_DPAD_RIGHT) ); - upPressed = 0; - downPressed = 0; - leftPressed = 0; - rightPressed = 0; - } -} - -int SDL_SYS_JoystickInit(void) -{ - SDL_numjoysticks = 0; - if( SDL_ANDROID_isJoystickUsed || isMultitouchUsed || SDL_ANDROID_isAccelerometerUsed ) - SDL_numjoysticks = 1; - //if( isMultitouchUsed ) - // SDL_numjoysticks = MAX_MULTITOUCH_POINTERS+1; - - return(SDL_numjoysticks); -} - -/* Function to get the device-dependent name of a joystick */ -const char *SDL_SYS_JoystickName(int index) -{ - return("Android accelerometer/multitouch sensor"); -} - -int SDL_SYS_JoystickOpen(SDL_Joystick *joystick) -{ - joystick->nbuttons = 0; - joystick->nhats = 0; - joystick->nballs = 0; - if( joystick->index == 0 ) - { - joystick->naxes = 4; // Joystick plus accelerometer - if(isMultitouchUsed) - { - joystick->naxes = 4 + MAX_MULTITOUCH_POINTERS; // Joystick plus accelerometer, plus touch pressure/size - joystick->nbuttons = MAX_MULTITOUCH_POINTERS; - joystick->nballs = MAX_MULTITOUCH_POINTERS; - } - } - SDL_ANDROID_CurrentJoysticks[joystick->index] = joystick; - return(0); -} - -void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick) -{ - return; -} - -/* Function to close a joystick after use */ -void SDL_SYS_JoystickClose(SDL_Joystick *joystick) -{ - SDL_ANDROID_CurrentJoysticks[joystick->index] = NULL; - return; -} - -/* Function to perform any system-specific joystick related cleanup */ -void SDL_SYS_JoystickQuit(void) -{ - int i; - SDL_ANDROID_CurrentJoysticks[0] = NULL; - 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); - SDL_ANDROID_MainThreadPushMouseMotion(currentMouseX + (currentMouseX % 2 ? -1 : 1), currentMouseY); // Force screen redraw - } - - SDL_mutexV(deferredTextMutex); -}; - -extern void SDL_ANDROID_MainThreadPushText( int ascii, int unicode ) -{ - int shiftRequired; - - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_ANDROID_MainThreadPushText(): %i %i", scancode, unicode); - 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 = unicode; - 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 ) - return; - - Uint32 ticks = SDL_GetTicks(); - - if( ticks - lastMoveMouseWithKeyboardUpdate < 20 ) // Update at 50 FPS max, or it will not work properlty on very fast devices - return; - - lastMoveMouseWithKeyboardUpdate = ticks; - - moveMouseWithKbSpeedX += moveMouseWithKbAccelX; - moveMouseWithKbSpeedY += moveMouseWithKbAccelY; - - moveMouseWithKbX += moveMouseWithKbSpeedX; - moveMouseWithKbY += moveMouseWithKbSpeedY; - SDL_ANDROID_MainThreadPushMouseMotion(moveMouseWithKbX, moveMouseWithKbY); -}; - -extern void SDL_ANDROID_ProcessDeferredEvents() -{ - SDL_ANDROID_DeferredTextInput(); - ProcessDeferredMouseTap(); -}; - -void ANDROID_InitOSKeymap() -{ -#if (SDL_VERSION_ATLEAST(1,3,0)) - SDLKey defaultKeymap[SDL_NUM_SCANCODES]; - SDL_GetDefaultKeymap(defaultKeymap); - SDL_SetKeymap(0, defaultKeymap, SDL_NUM_SCANCODES); - - SDL_Touch touch; - memset( &touch, 0, sizeof(touch) ); - touch.x_min = touch.y_min = touch.pressure_min = 0.0f; - touch.pressure_max = 1000000; - touch.x_max = SDL_ANDROID_sWindowWidth; - touch.y_max = SDL_ANDROID_sWindowHeight; - - // These constants are hardcoded inside SDL_touch.c, which makes no sense for me. - touch.xres = touch.yres = 32768; - touch.native_xres = touch.native_yres = 32768.0f; - - touch.pressureres = 1; - touch.native_pressureres = 1.0f; - touch.id = 0; - - SDL_AddTouch(&touch, "Android touch screen"); -#endif -} - -JNIEXPORT jint JNICALL -JAVA_EXPORT_NAME(Settings_nativeGetKeymapKey) (JNIEnv* env, jobject thiz, jint code) -{ - if( code < 0 || code > KEYCODE_LAST ) - return SDL_KEY(UNKNOWN); - return SDL_android_keymap[code]; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetKeymapKey) (JNIEnv* env, jobject thiz, jint javakey, jint key) -{ - if( javakey < 0 || javakey > KEYCODE_LAST ) - return; - SDL_android_keymap[javakey] = key; -} - -JNIEXPORT jint JNICALL -JAVA_EXPORT_NAME(Settings_nativeGetKeymapKeyScreenKb) (JNIEnv* env, jobject thiz, jint keynum) -{ - if( keynum < 0 || keynum > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 + 4 ) - return SDL_KEY(UNKNOWN); - - if( keynum <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 ) - return SDL_ANDROID_GetScreenKeyboardButtonKey(keynum + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0); - - return SDL_KEY(UNKNOWN); -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetKeymapKeyScreenKb) (JNIEnv* env, jobject thiz, jint keynum, jint key) -{ - if( keynum < 0 || keynum > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 + 4 ) - return; - - if( keynum <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 ) - SDL_ANDROID_SetScreenKeyboardButtonKey(keynum + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0, key); -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetScreenKbKeyUsed) (JNIEnv* env, jobject thiz, jint keynum, jint used) -{ - SDL_Rect rect = {0, 0, 0, 0}; - int key = -1; - if( keynum == 0 ) - key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD; - if( keynum == 1 ) - key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT; - if( keynum - 2 >= 0 && keynum - 2 <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 ) - key = keynum - 2 + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0; - - if( key >= 0 && !used ) - SDL_ANDROID_SetScreenKeyboardButtonPos(key, &rect); -} - -JNIEXPORT jint JNICALL -JAVA_EXPORT_NAME(Settings_nativeGetKeymapKeyMultitouchGesture) (JNIEnv* env, jobject thiz, jint keynum) -{ - if( keynum < 0 || keynum >= MAX_MULTITOUCH_GESTURES ) - return SDL_KEY(UNKNOWN); - return multitouchGestureKeycode[keynum]; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetKeymapKeyMultitouchGesture) (JNIEnv* env, jobject thiz, jint keynum, jint keycode) -{ - if( keynum < 0 || keynum >= MAX_MULTITOUCH_GESTURES ) - return; - multitouchGestureKeycode[keynum] = keycode; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetMultitouchGestureSensitivity) (JNIEnv* env, jobject thiz, jint sensitivity) -{ - multitouchGestureSensitivity = sensitivity; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetTouchscreenCalibration) (JNIEnv* env, jobject thiz, jint x1, jint y1, jint x2, jint y2) -{ - SDL_ANDROID_TouchscreenCalibrationX = x1; - SDL_ANDROID_TouchscreenCalibrationY = y1; - SDL_ANDROID_TouchscreenCalibrationWidth = x2 - x1; - SDL_ANDROID_TouchscreenCalibrationHeight = y2 - y1; -} - -static int ScreenKbRedefinedByUser = 0; - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetScreenKbKeyLayout) (JNIEnv* env, jobject thiz, jint keynum, jint x1, jint y1, jint x2, jint y2) -{ - SDL_Rect rect = {x1, y1, x2-x1, y2-y1}; - int key = -1; - if( keynum == 0 ) - key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD; - if( keynum == 1 ) - key = SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT; - if( keynum - 2 >= 0 && keynum - 2 <= SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 ) - key = keynum - 2 + SDL_ANDROID_SCREENKEYBOARD_BUTTON_0; - - if( key >= 0 ) - { - ScreenKbRedefinedByUser = 1; - SDL_ANDROID_SetScreenKeyboardButtonPos(key, &rect); - } -} - -int SDL_ANDROID_GetScreenKeyboardRedefinedByUser() -{ - return ScreenKbRedefinedByUser; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeInitKeymap) ( JNIEnv* env, jobject thiz ) -{ - SDL_android_init_keymap(SDL_android_keymap); -} 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 new file mode 120000 index 000000000..351c7ae45 --- /dev/null +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c @@ -0,0 +1 @@ +../../../../sdl-1.2/src/video/android/SDL_androidinput.c \ No newline at end of file diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h deleted file mode 100644 index b7e813d81..000000000 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h +++ /dev/null @@ -1,206 +0,0 @@ -/* - 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 -*/ -#ifndef _SDL_ANDROIDINPUT_H_ -#define _SDL_ANDROIDINPUT_H_ - -#include "SDL_config.h" - -#include "SDL_version.h" -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "SDL_mutex.h" -#include "SDL_thread.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "SDL_events.h" -#if (SDL_VERSION_ATLEAST(1,3,0)) -#include "../../events/SDL_events_c.h" -#include "../../events/SDL_keyboard_c.h" -#include "../../events/SDL_mouse_c.h" -#include "SDL_keycode.h" -#include "SDL_scancode.h" -//#include "SDL_compat.h" -#else -#include "SDL_keysym.h" -#include "../../events/SDL_events_c.h" -#endif -#include "SDL_joystick.h" -#include "../../joystick/SDL_sysjoystick.h" -#include "../../joystick/SDL_joystick_c.h" - -#include "../SDL_sysvideo.h" -#include "SDL_androidvideo.h" -#include "javakeycodes.h" - -/* JNI-C++ wrapper stuff */ - -// Special key to signal that key should be handled by Java internally, such as Volume Up/Down keys -#define SDLK_NO_REMAP 512 -#define SDL_SCANCODE_NO_REMAP SDLK_NO_REMAP - -#if SDL_VERSION_ATLEAST(1,3,0) - -#define SDL_KEY2(X) SDL_SCANCODE_ ## X -#define SDL_KEY(X) SDL_KEY2(X) -typedef SDL_Scancode SDL_scancode; -typedef SDL_Keycode SDLKey; -typedef SDL_Keysym SDL_keysym; - -#else - -#define SDL_KEY2(X) SDLK_ ## X -#define SDL_KEY(X) SDL_KEY2(X) - -// Randomly redefining SDL 1.3 scancodes to SDL 1.2 keycodes -#define KP_0 KP0 -#define KP_1 KP1 -#define KP_2 KP2 -#define KP_3 KP3 -#define KP_4 KP4 -#define KP_5 KP5 -#define KP_6 KP6 -#define KP_7 KP7 -#define KP_8 KP8 -#define KP_9 KP9 -#define NUMLOCKCLEAR NUMLOCK -#define GRAVE DOLLAR -#define APOSTROPHE QUOTE -#define LGUI LMETA -#define RGUI RMETA -#define SCROLLLOCK SCROLLOCK -// Overkill haha -#define A a -#define B b -#define C c -#define D d -#define E e -#define F f -#define G g -#define H h -#define I i -#define J j -#define K k -#define L l -#define M m -#define N n -#define O o -#define P p -#define Q q -#define R r -#define S s -#define T t -#define U u -#define V v -#define W w -#define X x -#define Y y -#define Z z - -typedef SDLKey SDL_scancode; -#define SDL_GetKeyboardState SDL_GetKeyState - -#endif - -#define SDL_KEY_VAL(X) X - -enum MOUSE_ACTION { MOUSE_DOWN = 0, MOUSE_UP = 1, MOUSE_MOVE = 2, MOUSE_HOVER = 3 }; - -extern int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointerId); -extern int SDL_ANDROID_isTouchscreenKeyboardUsed; - -#ifndef SDL_ANDROID_KEYCODE_0 -#define SDL_ANDROID_KEYCODE_0 RETURN -#endif -#ifndef SDL_ANDROID_KEYCODE_1 -#define SDL_ANDROID_KEYCODE_1 END -#endif -#ifndef SDL_ANDROID_KEYCODE_2 -#define SDL_ANDROID_KEYCODE_2 NO_REMAP -#endif -#ifndef SDL_ANDROID_KEYCODE_3 -#define SDL_ANDROID_KEYCODE_3 NO_REMAP -#endif -#ifndef SDL_ANDROID_KEYCODE_4 -#define SDL_ANDROID_KEYCODE_4 LCTRL -#endif -#ifndef SDL_ANDROID_KEYCODE_5 -#define SDL_ANDROID_KEYCODE_5 ESCAPE -#endif -#ifndef SDL_ANDROID_KEYCODE_6 -#define SDL_ANDROID_KEYCODE_6 RSHIFT -#endif -#ifndef SDL_ANDROID_KEYCODE_7 -#define SDL_ANDROID_KEYCODE_7 SDL_ANDROID_KEYCODE_1 -#endif -#ifndef SDL_ANDROID_KEYCODE_8 -#define SDL_ANDROID_KEYCODE_8 LALT -#endif -#ifndef SDL_ANDROID_KEYCODE_9 -#define SDL_ANDROID_KEYCODE_9 RALT -#endif - -// Touchscreen keyboard keys + zoom and rotate keycodes -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_0 -#define SDL_ANDROID_SCREENKB_KEYCODE_0 SDL_ANDROID_KEYCODE_0 -#endif -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_1 -#define SDL_ANDROID_SCREENKB_KEYCODE_1 SDL_ANDROID_KEYCODE_1 -#endif -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_2 -#define SDL_ANDROID_SCREENKB_KEYCODE_2 PAGEUP -#endif -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_3 -#define SDL_ANDROID_SCREENKB_KEYCODE_3 PAGEDOWN -#endif -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_4 -#define SDL_ANDROID_SCREENKB_KEYCODE_4 SDL_ANDROID_KEYCODE_6 -#endif -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_5 -#define SDL_ANDROID_SCREENKB_KEYCODE_5 SDL_ANDROID_KEYCODE_7 -#endif -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_6 -#define SDL_ANDROID_SCREENKB_KEYCODE_6 SDL_ANDROID_KEYCODE_4 -#endif -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_7 -#define SDL_ANDROID_SCREENKB_KEYCODE_7 SDL_ANDROID_KEYCODE_5 -#endif -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_8 -#define SDL_ANDROID_SCREENKB_KEYCODE_8 SDL_ANDROID_KEYCODE_8 -#endif -#ifndef SDL_ANDROID_SCREENKB_KEYCODE_9 -#define SDL_ANDROID_SCREENKB_KEYCODE_9 SDL_ANDROID_KEYCODE_9 -#endif - -// Queue events to main thread -extern void SDL_ANDROID_MainThreadPushMouseMotion(int x, int y); -extern void SDL_ANDROID_MainThreadPushMouseButton(int pressed, int button); -extern void SDL_ANDROID_MainThreadPushKeyboardKey(int pressed, SDL_scancode key); -extern void SDL_ANDROID_MainThreadPushMultitouchButton(int id, int pressed, int x, int y, int force); // SDL 1.3 only -extern void SDL_ANDROID_MainThreadPushMultitouchMotion(int id, int x, int y, int force); // SDL 1.3 only -extern void SDL_ANDROID_MainThreadPushJoystickAxis(int joy, int axis, int value); -extern void SDL_ANDROID_MainThreadPushJoystickButton(int joy, int button, int pressed); -extern void SDL_ANDROID_MainThreadPushJoystickBall(int joy, int ball, int x, int y); -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); -#endif diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h new file mode 120000 index 000000000..213a266ff --- /dev/null +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h @@ -0,0 +1 @@ +../../../../sdl-1.2/src/video/android/SDL_androidinput.h \ No newline at end of file diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c deleted file mode 100644 index 1416e064b..000000000 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c +++ /dev/null @@ -1,402 +0,0 @@ -/* - 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 -#include -#include // for memset() - -#include "SDL_config.h" -#include "SDL_version.h" - -#include "SDL_video.h" -#include "SDL_mouse.h" -#include "SDL_mutex.h" -#include "SDL_thread.h" -#include "SDL_android.h" -#include "../SDL_sysvideo.h" -#include "../SDL_pixels_c.h" -#include "../../events/SDL_events_c.h" - -#include "../SDL_sysvideo.h" -#include "SDL_androidvideo.h" -#include "jniwrapperstuff.h" - - -// The device screen dimensions to draw on -int SDL_ANDROID_sWindowWidth = 0; -int SDL_ANDROID_sWindowHeight = 0; - -int SDL_ANDROID_sRealWindowWidth = 0; -int SDL_ANDROID_sRealWindowHeight = 0; - -SDL_Rect SDL_ANDROID_ForceClearScreenRect = { 0, 0, 0, 0 }; - -// Extremely wicked JNI environment to call Java functions from C code -static JNIEnv* JavaEnv = NULL; -static jclass JavaRendererClass = NULL; -static jobject JavaRenderer = NULL; -static jmethodID JavaSwapBuffers = NULL; -static jmethodID JavaShowScreenKeyboard = NULL; -static jmethodID JavaToggleScreenKeyboardWithoutTextInput = NULL; -static jmethodID JavaGetAdvertisementParams = NULL; -static jmethodID JavaSetAdvertisementVisible = NULL; -static jmethodID JavaSetAdvertisementPosition = NULL; -static jmethodID JavaRequestNewAdvertisement = NULL; -static int glContextLost = 0; -static int showScreenKeyboardDeferred = 0; -static const char * showScreenKeyboardOldText = ""; -static int showScreenKeyboardSendBackspace = 0; -int SDL_ANDROID_VideoLinearFilter = 0; -int SDL_ANDROID_VideoMultithreaded = 0; -int SDL_ANDROID_VideoForceSoftwareMode = 0; -int SDL_ANDROID_CompatibilityHacks = 0; -int SDL_ANDROID_BYTESPERPIXEL = 2; -int SDL_ANDROID_BITSPERPIXEL = 16; -int SDL_ANDROID_UseGles2 = 0; -int SDL_ANDROID_ShowMouseCursor = 0; - -static void appPutToBackgroundCallbackDefault(void) -{ - SDL_ANDROID_PauseAudioPlayback(); -} -static void appRestoredCallbackDefault(void) -{ - SDL_ANDROID_ResumeAudioPlayback(); -} - -static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appPutToBackgroundCallback = appPutToBackgroundCallbackDefault; -static SDL_ANDROID_ApplicationPutToBackgroundCallback_t appRestoredCallback = appRestoredCallbackDefault; -static SDL_ANDROID_ApplicationPutToBackgroundCallback_t openALPutToBackgroundCallback = NULL; -static SDL_ANDROID_ApplicationPutToBackgroundCallback_t openALRestoredCallback = NULL; - -int SDL_ANDROID_CallJavaSwapBuffers() -{ - if( !glContextLost ) - { - SDL_ANDROID_drawTouchscreenKeyboard(); - } - - // Clear part of screen not used by SDL - on Android the screen contains garbage after each frame - if( SDL_ANDROID_ForceClearScreenRect.w != 0 && SDL_ANDROID_ForceClearScreenRect.h != 0 ) - { - glPushMatrix(); - glLoadIdentity(); - glOrthox( 0, (SDL_ANDROID_sRealWindowWidth) * 0x10000, SDL_ANDROID_sRealWindowHeight * 0x10000, 0, 0, 1 * 0x10000 ); - glColor4x(0, 0, 0, 0x10000); - glEnableClientState(GL_VERTEX_ARRAY); - - GLshort vertices[] = { SDL_ANDROID_ForceClearScreenRect.x, SDL_ANDROID_ForceClearScreenRect.y, - SDL_ANDROID_ForceClearScreenRect.x + SDL_ANDROID_ForceClearScreenRect.w, SDL_ANDROID_ForceClearScreenRect.y, - SDL_ANDROID_ForceClearScreenRect.x + SDL_ANDROID_ForceClearScreenRect.w, SDL_ANDROID_ForceClearScreenRect.y + SDL_ANDROID_ForceClearScreenRect.h, - SDL_ANDROID_ForceClearScreenRect.x, SDL_ANDROID_ForceClearScreenRect.y + SDL_ANDROID_ForceClearScreenRect.h }; - glVertexPointer(2, GL_SHORT, 0, vertices); - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - - glDisableClientState(GL_VERTEX_ARRAY); - glPopMatrix(); - } - - if( ! (*JavaEnv)->CallIntMethod( JavaEnv, JavaRenderer, JavaSwapBuffers ) ) - return 0; - if( glContextLost ) - { - glContextLost = 0; - __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context recreated, refreshing textures"); - SDL_ANDROID_VideoContextRecreated(); - appRestoredCallback(); - if(openALRestoredCallback) - openALRestoredCallback(); - } - if( showScreenKeyboardDeferred ) - { - showScreenKeyboardDeferred = 0; - (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaShowScreenKeyboard, (*JavaEnv)->NewStringUTF(JavaEnv, showScreenKeyboardOldText), showScreenKeyboardSendBackspace ); - } - SDL_ANDROID_ProcessDeferredEvents(); - return 1; -} - - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoRenderer_nativeResize) ( JNIEnv* env, jobject thiz, jint w, jint h, jint keepRatio ) -{ - if( SDL_ANDROID_sWindowWidth == 0 ) - { - SDL_ANDROID_sRealWindowWidth = w; - SDL_ANDROID_sRealWindowHeight = h; -#if SDL_VERSION_ATLEAST(1,3,0) - // Not supported in SDL 1.3 -#else - if( keepRatio ) - { - // TODO: tweak that parameters when app calls SetVideoMode(), not here - app may request something else than 640x480, it's okay for most apps though - SDL_ANDROID_sWindowWidth = (SDL_ANDROID_sFakeWindowWidth*h)/SDL_ANDROID_sFakeWindowHeight; - SDL_ANDROID_sWindowHeight = h; - SDL_ANDROID_ForceClearScreenRect.x = SDL_ANDROID_sWindowWidth; - SDL_ANDROID_ForceClearScreenRect.y = 0; - SDL_ANDROID_ForceClearScreenRect.w = w - SDL_ANDROID_sWindowWidth; - SDL_ANDROID_ForceClearScreenRect.h = h; - - if(SDL_ANDROID_sWindowWidth >= w) - { - SDL_ANDROID_sWindowWidth = w; - SDL_ANDROID_sWindowHeight = (SDL_ANDROID_sFakeWindowHeight*w)/SDL_ANDROID_sFakeWindowWidth; - SDL_ANDROID_ForceClearScreenRect.x = 0; - SDL_ANDROID_ForceClearScreenRect.y = SDL_ANDROID_sWindowHeight; - SDL_ANDROID_ForceClearScreenRect.w = w; - SDL_ANDROID_ForceClearScreenRect.h = SDL_ANDROID_sWindowHeight - h; // OpenGL vertical coord is inverted - } - } - else -#endif - { - SDL_ANDROID_ForceClearScreenRect.w = 0; - SDL_ANDROID_ForceClearScreenRect.h = 0; - SDL_ANDROID_ForceClearScreenRect.x = 0; - SDL_ANDROID_ForceClearScreenRect.y = 0; - SDL_ANDROID_sWindowWidth = w; - SDL_ANDROID_sWindowHeight = h; - } - __android_log_print(ANDROID_LOG_INFO, "libSDL", "Physical screen resolution is %dx%d, virtual screen %dx%d", w, h, SDL_ANDROID_sWindowWidth, SDL_ANDROID_sWindowHeight ); - SDL_ANDROID_TouchscreenCalibrationWidth = SDL_ANDROID_sWindowWidth; - SDL_ANDROID_TouchscreenCalibrationHeight = SDL_ANDROID_sWindowHeight; - } -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoRenderer_nativeDone) ( JNIEnv* env, jobject thiz ) -{ - __android_log_print(ANDROID_LOG_INFO, "libSDL", "quitting..."); -#if SDL_VERSION_ATLEAST(1,3,0) - SDL_SendQuit(); -#else - SDL_PrivateQuit(); -#endif - __android_log_print(ANDROID_LOG_INFO, "libSDL", "quit OK"); -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextLost) ( JNIEnv* env, jobject thiz ) -{ - __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context lost, waiting for new OpenGL context"); - glContextLost = 1; - appPutToBackgroundCallback(); - if(openALPutToBackgroundCallback) - openALPutToBackgroundCallback(); - - SDL_ANDROID_VideoContextLost(); -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextLostAsyncEvent) ( JNIEnv* env, jobject thiz ) -{ - __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context lost - sending SDL_ACTIVEEVENT"); - SDL_ANDROID_MainThreadPushAppActive(0); -} - - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextRecreated) ( JNIEnv* env, jobject thiz ) -{ - __android_log_print(ANDROID_LOG_INFO, "libSDL", "OpenGL context recreated, sending SDL_ACTIVEEVENT"); -#if SDL_VERSION_ATLEAST(1,3,0) - //if( ANDROID_CurrentWindow ) - // SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_RESTORED, 0, 0); -#else - SDL_PrivateAppActive(1, SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); -#endif -} - -int SDL_ANDROID_ToggleScreenKeyboardWithoutTextInput(void) -{ - (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaToggleScreenKeyboardWithoutTextInput ); - return 1; -} - -volatile static textInputFinished = 0; -void SDL_ANDROID_TextInputFinished() -{ - textInputFinished = 1; -}; - -#if SDL_VERSION_ATLEAST(1,3,0) -#else -extern int SDL_Flip(SDL_Surface *screen); -extern SDL_Surface *SDL_GetVideoSurface(void); -#endif - -void SDL_ANDROID_CallJavaShowScreenKeyboard(const char * oldText, char * outBuf, int outBufLen) -{ - if( !outBuf ) - { - showScreenKeyboardDeferred = 1; - showScreenKeyboardOldText = oldText; - showScreenKeyboardSendBackspace = 1; - // Move mouse by 1 pixel to force screen update - int x, y; - SDL_GetMouseState( &x, &y ); - SDL_ANDROID_MainThreadPushMouseMotion(x > 0 ? x-1 : 0, y); - } - else - { - textInputFinished = 0; - SDL_ANDROID_TextInputInit(outBuf, outBufLen); - - if( SDL_ANDROID_VideoMultithreaded ) - { -#if SDL_VERSION_ATLEAST(1,3,0) -#else - // Dirty hack: we may call (*JavaEnv)->CallVoidMethod(...) only from video thread - showScreenKeyboardDeferred = 1; - showScreenKeyboardOldText = oldText; - showScreenKeyboardSendBackspace = 0; - SDL_Flip(SDL_GetVideoSurface()); -#endif - } - else - (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaShowScreenKeyboard, (*JavaEnv)->NewStringUTF(JavaEnv, oldText), 0 ); - - while( !textInputFinished ) - SDL_Delay(100); - textInputFinished = 0; - } -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(DemoRenderer_nativeInitJavaCallbacks) ( JNIEnv* env, jobject thiz ) -{ - JavaEnv = env; - JavaRenderer = (*JavaEnv)->NewGlobalRef( JavaEnv, thiz ); - - JavaRendererClass = (*JavaEnv)->GetObjectClass(JavaEnv, thiz); - JavaSwapBuffers = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "swapBuffers", "()I"); - JavaShowScreenKeyboard = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "showScreenKeyboard", "(Ljava/lang/String;I)V"); - JavaToggleScreenKeyboardWithoutTextInput = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "showScreenKeyboardWithoutTextInputField", "()V"); - // TODO: implement it - JavaGetAdvertisementParams = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "getAdvertisementParams", "([I)V"); - JavaSetAdvertisementVisible = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "setAdvertisementVisible", "(I)V"); - JavaSetAdvertisementPosition = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "setAdvertisementPosition", "(II)V"); - JavaRequestNewAdvertisement = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "requestNewAdvertisement", "()V"); - - ANDROID_InitOSKeymap(); -} - -int SDL_ANDROID_SetApplicationPutToBackgroundCallback( - SDL_ANDROID_ApplicationPutToBackgroundCallback_t appPutToBackground, - SDL_ANDROID_ApplicationPutToBackgroundCallback_t appRestored ) -{ - appPutToBackgroundCallback = appPutToBackgroundCallbackDefault; - appRestoredCallback = appRestoredCallbackDefault; - - if( appPutToBackground ) - appPutToBackgroundCallback = appPutToBackground; - - if( appRestoredCallback ) - appRestoredCallback = appRestored; -} - -extern int SDL_ANDROID_SetOpenALPutToBackgroundCallback( - SDL_ANDROID_ApplicationPutToBackgroundCallback_t PutToBackground, - SDL_ANDROID_ApplicationPutToBackgroundCallback_t Restored ); - -int SDL_ANDROID_SetOpenALPutToBackgroundCallback( - SDL_ANDROID_ApplicationPutToBackgroundCallback_t PutToBackground, - SDL_ANDROID_ApplicationPutToBackgroundCallback_t Restored ) -{ - openALPutToBackgroundCallback = PutToBackground; - openALRestoredCallback = Restored; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetVideoLinearFilter) (JNIEnv* env, jobject thiz) -{ - SDL_ANDROID_VideoLinearFilter = 1; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetVideoMultithreaded) (JNIEnv* env, jobject thiz) -{ - SDL_ANDROID_VideoMultithreaded = 1; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetVideoForceSoftwareMode) (JNIEnv* env, jobject thiz) -{ - SDL_ANDROID_VideoForceSoftwareMode = 1; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetCompatibilityHacks) (JNIEnv* env, jobject thiz) -{ - SDL_ANDROID_CompatibilityHacks = 1; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetVideoDepth) (JNIEnv* env, jobject thiz, jint bpp, jint UseGles2) -{ - SDL_ANDROID_BITSPERPIXEL = bpp; - SDL_ANDROID_BYTESPERPIXEL = SDL_ANDROID_BITSPERPIXEL / 8; - SDL_ANDROID_UseGles2 = UseGles2; -} - -int SDLCALL SDL_ANDROID_GetAdvertisementParams(int * visible, SDL_Rect * position) -{ - jint arr[5]; - jintArray elemArr = (*JavaEnv)->NewIntArray(JavaEnv, 5); - if (elemArr == NULL) - return 0; - (*JavaEnv)->SetIntArrayRegion(JavaEnv, elemArr, 0, 5, arr); - (*JavaEnv)->CallVoidMethod(JavaEnv, JavaRenderer, JavaGetAdvertisementParams, elemArr); - (*JavaEnv)->GetIntArrayRegion(JavaEnv, elemArr, 0, 5, arr); - (*JavaEnv)->DeleteLocalRef(JavaEnv, elemArr); - if(visible) - *visible = arr[0]; - if(position) - { - position->x = arr[1]; - position->y = arr[2]; - position->w = arr[3]; - position->h = arr[4]; - } - return 1; -} -int SDLCALL SDL_ANDROID_SetAdvertisementVisible(int visible) -{ - (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementVisible, (jint)visible ); - return 1; -} -int SDLCALL SDL_ANDROID_SetAdvertisementPosition(int left, int top) -{ - (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaSetAdvertisementPosition, (jint)left, (jint)top ); - return 1; -} -int SDLCALL SDL_ANDROID_RequestNewAdvertisement(void) -{ - (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaRequestNewAdvertisement ); - return 1; -} diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c new file mode 120000 index 000000000..3dd000ce3 --- /dev/null +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c @@ -0,0 +1 @@ +../../../../sdl-1.2/src/video/android/SDL_androidvideo.c \ No newline at end of file diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h deleted file mode 100644 index c24bc205d..000000000 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - 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 -*/ -#ifndef _SDL_androidvideo_h -#define _SDL_androidvideo_h - -#include "SDL_version.h" -#include "SDL_config.h" -#include "SDL_video.h" -#include "SDL_joystick.h" -#include "SDL_events.h" - -enum ScreenZoom { ZOOM_NONE = 0, ZOOM_MAGNIFIER = 1, ZOOM_SCREEN_TRANSFORM = 2, ZOOM_FULLSCREEN_MAGNIFIER = 3 }; - -extern int SDL_ANDROID_sWindowWidth; -extern int SDL_ANDROID_sWindowHeight; -extern int SDL_ANDROID_sRealWindowWidth; -extern int SDL_ANDROID_sRealWindowHeight; -extern int SDL_ANDROID_sFakeWindowWidth; // SDL 1.2 only -extern int SDL_ANDROID_sFakeWindowHeight; // SDL 1.2 only -extern int SDL_ANDROID_TouchscreenCalibrationWidth; -extern int SDL_ANDROID_TouchscreenCalibrationHeight; -extern int SDL_ANDROID_TouchscreenCalibrationX; -extern int SDL_ANDROID_TouchscreenCalibrationY; -extern int SDL_ANDROID_VideoLinearFilter; -extern int SDL_ANDROID_VideoMultithreaded; -extern int SDL_ANDROID_VideoForceSoftwareMode; -extern int SDL_ANDROID_CompatibilityHacks; -extern int SDL_ANDROID_ShowMouseCursor; -extern int SDL_ANDROID_UseGles2; -extern int SDL_ANDROID_BYTESPERPIXEL; -extern int SDL_ANDROID_BITSPERPIXEL; -extern void SDL_ANDROID_TextInputInit(char * buffer, int len); -extern void SDL_ANDROID_TextInputFinished(); -extern SDL_Surface *SDL_CurrentVideoSurface; -extern SDL_Rect SDL_ANDROID_ForceClearScreenRect; -extern int SDL_ANDROID_ShowScreenUnderFinger; -extern SDL_Rect SDL_ANDROID_ShowScreenUnderFingerRect, SDL_ANDROID_ShowScreenUnderFingerRectSrc; -extern int SDL_ANDROID_CallJavaSwapBuffers(); -extern void SDL_ANDROID_CallJavaShowScreenKeyboard(const char * oldText, char * outBuf, int outBufLen); -extern int SDL_ANDROID_drawTouchscreenKeyboard(); -extern void SDL_ANDROID_VideoContextLost(); -extern void SDL_ANDROID_VideoContextRecreated(); -extern void SDL_ANDROID_processAndroidTrackballDampening(); -extern void SDL_ANDROID_processMoveMouseWithKeyboard(); -extern int SDL_ANDROID_InsideVideoThread(); -extern void SDL_ANDROID_initFakeStdout(); -extern SDL_VideoDevice *ANDROID_CreateDevice_1_3(int devindex); -extern void SDL_ANDROID_ProcessDeferredEvents(); -extern void SDL_ANDROID_WarpMouse(int x, int y); -extern void SDL_ANDROID_DrawMouseCursor(int x, int y, int size, int alpha); -extern void SDL_ANDROID_DrawMouseCursorIfNeeded(); -extern void SDL_ANDROID_CallJavaTogglePlainAndroidSoftKeyboardInput(); - - -#if SDL_VERSION_ATLEAST(1,3,0) -extern SDL_Window * ANDROID_CurrentWindow; -#endif - -// Exports from SDL_androidinput.c - SDL_androidinput.h is too encumbered -enum { MAX_MULTITOUCH_POINTERS = 16 }; -extern void ANDROID_InitOSKeymap(); -extern int SDL_ANDROID_isJoystickUsed; -// Events have to be sent only from main thread from PumpEvents(), so we'll buffer them here -extern void SDL_ANDROID_PumpEvents(); - - -#endif /* _SDL_androidvideo_h */ diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h new file mode 120000 index 000000000..90d543baa --- /dev/null +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h @@ -0,0 +1 @@ +../../../../sdl-1.2/src/video/android/SDL_androidvideo.h \ No newline at end of file diff --git a/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c b/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c deleted file mode 100644 index ca94dd998..000000000 --- a/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c +++ /dev/null @@ -1,1064 +0,0 @@ -/* - 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 -#include -#include - -#include "SDL_config.h" - -#include "SDL_version.h" - -//#include "SDL_opengles.h" -#include "SDL_screenkeyboard.h" -#include "../SDL_sysvideo.h" -#include "SDL_androidvideo.h" -#include "SDL_androidinput.h" -#include "jniwrapperstuff.h" - -// #include "touchscreentheme.h" // Not used yet - -// TODO: this code is a HUGE MESS - -#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) -#define MAX(X, Y) ((X) > (Y) ? (X) : (Y)) - -enum { MAX_BUTTONS = SDL_ANDROID_SCREENKEYBOARD_BUTTON_NUM-1, MAX_BUTTONS_AUTOFIRE = 2, BUTTON_TEXT_INPUT = SDL_ANDROID_SCREENKEYBOARD_BUTTON_TEXT-1, BUTTON_ARROWS = MAX_BUTTONS } ; // Max amount of custom buttons - -int SDL_ANDROID_isTouchscreenKeyboardUsed = 0; -static int touchscreenKeyboardTheme = 0; -static int touchscreenKeyboardShown = 1; -static int AutoFireButtonsNum = 0; -static int buttonsize = 1; -static int buttonDrawSize = 1; -static int transparency = 128; - -static SDL_Rect arrows, arrowsExtended, buttons[MAX_BUTTONS], buttonsAutoFireRect[MAX_BUTTONS_AUTOFIRE]; -static SDL_Rect arrowsDraw, buttonsDraw[MAX_BUTTONS]; -static SDLKey buttonKeysyms[MAX_BUTTONS] = { -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_0)), -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_1)), -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_2)), -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_3)), -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_4)), -SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_SCREENKB_KEYCODE_5)), -0 -}; - -enum { ARROW_LEFT = 1, ARROW_RIGHT = 2, ARROW_UP = 4, ARROW_DOWN = 8 }; -static int oldArrows = 0; -static int ButtonAutoFire[MAX_BUTTONS_AUTOFIRE]; -static int ButtonAutoFireX[MAX_BUTTONS_AUTOFIRE*2]; -static int ButtonAutoFireRot[MAX_BUTTONS_AUTOFIRE]; -static int ButtonAutoFireDecay[MAX_BUTTONS_AUTOFIRE]; - -static int pointerInButtonRect[MAX_BUTTONS + 1]; - -typedef struct -{ - GLuint id; - GLfloat w; - GLfloat h; -} GLTexture_t; - -static GLTexture_t arrowImages[5]; -static GLTexture_t buttonAutoFireImages[MAX_BUTTONS_AUTOFIRE*2]; -static GLTexture_t buttonImages[MAX_BUTTONS*2]; -static GLTexture_t mousePointer; -enum { MOUSE_POINTER_W = 32, MOUSE_POINTER_H = 32, MOUSE_POINTER_X = 5, MOUSE_POINTER_Y = 7 }; // X and Y are offsets of the pointer tip - -static int sunTheme = 0; -static int joystickTouchPoints[2]; - -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 ); -} - -static struct ScreenKbGlState_t -{ - GLboolean texture2d; - GLuint textureId; - GLfloat color[4]; - GLint texEnvMode; - GLboolean blend; - GLenum blend1, blend2; - GLint texFilter1, texFilter2; -} -oldGlState; - -static inline void beginDrawingTex() -{ - // Save OpenGL state - glGetError(); // Clear error flag - // This code does not work on 1.6 emulator, and on some older devices - // However GLES 1.1 spec defines all theese values, so it's a device fault for not implementing them - oldGlState.texture2d = glIsEnabled(GL_TEXTURE_2D); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &oldGlState.textureId); - glGetFloatv(GL_CURRENT_COLOR, &(oldGlState.color[0])); - glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &oldGlState.texEnvMode); - oldGlState.blend = glIsEnabled(GL_BLEND); - glGetIntegerv(GL_BLEND_SRC, &oldGlState.blend1); - glGetIntegerv(GL_BLEND_DST, &oldGlState.blend2); - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, &oldGlState.texFilter1); - glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, &oldGlState.texFilter2); - // It's very unlikely that some app will use GL_TEXTURE_CROP_RECT_OES, so just skip it - if( glGetError() != GL_NO_ERROR ) - { - // Make the video somehow work on emulator - oldGlState.texture2d = GL_FALSE; - oldGlState.textureId = 0; - oldGlState.texEnvMode = GL_MODULATE; - oldGlState.blend = GL_FALSE; - oldGlState.blend1 = GL_SRC_ALPHA; - oldGlState.blend2 = GL_ONE_MINUS_SRC_ALPHA; - oldGlState.texFilter1 = GL_NEAREST; - oldGlState.texFilter2 = GL_NEAREST; - } - - glEnable(GL_TEXTURE_2D); -} - -static inline void endDrawingTex() -{ - // Restore OpenGL state - if( oldGlState.texture2d == GL_FALSE ) - glDisable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, oldGlState.textureId); - glColor4f(oldGlState.color[0], oldGlState.color[1], oldGlState.color[2], oldGlState.color[3]); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, oldGlState.texEnvMode); - if( oldGlState.blend == GL_FALSE ) - glDisable(GL_BLEND); - glBlendFunc(oldGlState.blend1, oldGlState.blend2); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, oldGlState.texFilter1); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, oldGlState.texFilter2); - - /* - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - */ -} - -static inline void drawCharTexFlip(GLTexture_t * tex, SDL_Rect * src, SDL_Rect * dest, int flipX, int flipY, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - GLint cropRect[4]; - - if( !dest->h || !dest->w ) - return; - - glBindTexture(GL_TEXTURE_2D, tex->id); - - glColor4x(r * 0x100, g * 0x100, b * 0x100, a * 0x100 ); - - glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - if( SDL_ANDROID_VideoLinearFilter ) - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - else - { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - } - - if(src) - { - cropRect[0] = src->x; - cropRect[1] = tex->h - src->y; - cropRect[2] = src->w; - cropRect[3] = -src->h; - } - else - { - cropRect[0] = 0; - cropRect[1] = tex->h; - cropRect[2] = tex->w; - cropRect[3] = -tex->h; - } - if(flipX) - { - cropRect[0] += cropRect[2]; - cropRect[2] = -cropRect[2]; - } - if(flipY) - { - cropRect[1] += cropRect[3]; - cropRect[3] = -cropRect[3]; - } - glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect); - glDrawTexiOES(dest->x, SDL_ANDROID_sWindowHeight - dest->y - dest->h, 0, dest->w, dest->h); -} - -static inline void drawCharTex(GLTexture_t * tex, SDL_Rect * src, SDL_Rect * dest, Uint8 r, Uint8 g, Uint8 b, Uint8 a) -{ - drawCharTexFlip(tex, src, dest, 0, 0, r, g, b, a); -} - -static void drawTouchscreenKeyboardLegacy() -{ - int i; - int blendFactor; - - blendFactor = ( SDL_GetKeyboardState(NULL)[SDL_KEY(LEFT)] ? 1 : 0 ) + - ( SDL_GetKeyboardState(NULL)[SDL_KEY(RIGHT)] ? 1 : 0 ) + - ( SDL_GetKeyboardState(NULL)[SDL_KEY(UP)] ? 1 : 0 ) + - ( SDL_GetKeyboardState(NULL)[SDL_KEY(DOWN)] ? 1 : 0 ); - if( blendFactor == 0 ) - drawCharTex( &arrowImages[0], NULL, &arrowsDraw, 255, 255, 255, transparency ); - else - { - if( SDL_GetKeyboardState(NULL)[SDL_KEY(LEFT)] ) - drawCharTex( &arrowImages[1], NULL, &arrowsDraw, 255, 255, 255, transparency / blendFactor ); - if( SDL_GetKeyboardState(NULL)[SDL_KEY(RIGHT)] ) - drawCharTex( &arrowImages[2], NULL, &arrowsDraw, 255, 255, 255, transparency / blendFactor ); - if( SDL_GetKeyboardState(NULL)[SDL_KEY(UP)] ) - drawCharTex( &arrowImages[3], NULL, &arrowsDraw, 255, 255, 255, transparency / blendFactor ); - if( SDL_GetKeyboardState(NULL)[SDL_KEY(DOWN)] ) - drawCharTex( &arrowImages[4], NULL, &arrowsDraw, 255, 255, 255, transparency / blendFactor ); - } - - for( i = 0; i < MAX_BUTTONS; i++ ) - { - if( ! buttons[i].h || ! buttons[i].w ) - continue; - if( i < AutoFireButtonsNum ) - { - if( ButtonAutoFire[i] == 1 && SDL_GetTicks() - ButtonAutoFireDecay[i] > 1000 ) - { - ButtonAutoFire[i] = 0; - } - if( ! ButtonAutoFire[i] && SDL_GetTicks() - ButtonAutoFireDecay[i] > 300 ) - { - if( ButtonAutoFireX[i*2] > 0 ) - ButtonAutoFireX[i*2] --; - if( ButtonAutoFireX[i*2+1] > 0 ) - ButtonAutoFireX[i*2+1] --; - ButtonAutoFireDecay[i] = SDL_GetTicks(); - } - } - - if( i < AutoFireButtonsNum && ! ButtonAutoFire[i] && - ( ButtonAutoFireX[i*2] > 0 || ButtonAutoFireX[i*2+1] > 0 ) ) - { - int pos1src = buttonImages[i*2+1].w / 2 - ButtonAutoFireX[i*2]; - int pos1dst = buttonsDraw[i].w * pos1src / buttonImages[i*2+1].w; - int pos2src = buttonImages[i*2+1].w - ( buttonImages[i*2+1].w / 2 - ButtonAutoFireX[i*2+1] ); - int pos2dst = buttonsDraw[i].w * pos2src / buttonImages[i*2+1].w; - - SDL_Rect autoFireCrop = { 0, 0, pos1src, buttonImages[i*2+1].h }; - SDL_Rect autoFireDest = buttonsDraw[i]; - autoFireDest.w = pos1dst; - - drawCharTex( &buttonImages[i*2+1], - &autoFireCrop, &autoFireDest, 255, 255, 255, transparency ); - - autoFireCrop.x = pos2src; - autoFireCrop.w = buttonImages[i*2+1].w - pos2src; - autoFireDest.x = buttonsDraw[i].x + pos2dst; - autoFireDest.w = buttonsDraw[i].w - pos2dst; - - drawCharTex( &buttonImages[i*2+1], - &autoFireCrop, &autoFireDest, 255, 255, 255, transparency ); - - autoFireCrop.x = pos1src; - autoFireCrop.w = pos2src - pos1src; - autoFireDest.x = buttonsDraw[i].x + pos1dst; - autoFireDest.w = pos2dst - pos1dst; - - drawCharTex( &buttonAutoFireImages[i*2+1], - &autoFireCrop, &autoFireDest, 255, 255, 255, transparency ); - } - else - { - drawCharTex( ( i < AutoFireButtonsNum && ButtonAutoFire[i] ) ? &buttonAutoFireImages[i*2] : - &buttonImages[ SDL_GetKeyboardState(NULL)[buttonKeysyms[i]] ? (i * 2 + 1) : (i * 2) ], - NULL, &buttonsDraw[i], 255, 255, 255, transparency ); - } - } -} - -static void drawTouchscreenKeyboardSun() -{ - int i; - - drawCharTex( &arrowImages[0], NULL, &arrowsDraw, 255, 255, 255, transparency ); - if(pointerInButtonRect[BUTTON_ARROWS] != -1) - { - SDL_Rect touch = arrowsDraw; - touch.w /= 2; - touch.h /= 2; - touch.x = joystickTouchPoints[0] - touch.w / 2; - touch.y = joystickTouchPoints[1] - touch.h / 2; - drawCharTex( &arrowImages[0], NULL, &touch, 255, 255, 255, transparency ); - } - - for( i = 0; i < MAX_BUTTONS; i++ ) - { - int pressed = SDL_GetKeyboardState(NULL)[buttonKeysyms[i]]; - if( ! buttons[i].h || ! buttons[i].w ) - continue; - if( i < AutoFireButtonsNum ) - { - if( ButtonAutoFire[i] == 1 && SDL_GetTicks() - ButtonAutoFireDecay[i] > 1000 ) - { - ButtonAutoFire[i] = 0; - } - if( ! ButtonAutoFire[i] && SDL_GetTicks() - ButtonAutoFireDecay[i] > 300 ) - { - if( ButtonAutoFireX[i*2] > 0 ) - ButtonAutoFireX[i*2] --; - if( ButtonAutoFireX[i*2+1] > 0 ) - ButtonAutoFireX[i*2+1] --; - ButtonAutoFireDecay[i] = SDL_GetTicks(); - } - } - - if( i < AutoFireButtonsNum && ButtonAutoFire[i] ) - drawCharTex( &buttonAutoFireImages[i*2+1], - NULL, &buttonsDraw[i], 255, 255, 255, transparency ); - - drawCharTexFlip( &buttonImages[ pressed ? (i * 2 + 1) : (i * 2) ], - NULL, &buttonsDraw[i], (i >= 2 && pressed), 0, 255, 255, 255, transparency ); - - if( i < AutoFireButtonsNum && ! ButtonAutoFire[i] && - ( ButtonAutoFireX[i*2] > 0 || ButtonAutoFireX[i*2+1] > 0 ) ) - { - int pos1src = buttonImages[i*2+1].w / 2 - ButtonAutoFireX[i*2]; - int pos1dst = buttonsDraw[i].w * pos1src / buttonImages[i*2+1].w; - int pos2src = buttonImages[i*2+1].w - ( buttonImages[i*2+1].w / 2 - ButtonAutoFireX[i*2+1] ); - int pos2dst = buttonsDraw[i].w * pos2src / buttonImages[i*2+1].w; - SDL_Rect autoFireDest; - - autoFireDest.w = pos2dst - pos1dst; - autoFireDest.h = pos2dst - pos1dst; - autoFireDest.x = buttonsDraw[i].x + buttonsDraw[i].w/2 - autoFireDest.w/2; - autoFireDest.y = buttonsDraw[i].y + buttonsDraw[i].h/2 - autoFireDest.h/2; - - drawCharTex( &buttonAutoFireImages[i*2], - NULL, &autoFireDest, 255, 255, 255, transparency ); - } - } -} - -int SDL_ANDROID_drawTouchscreenKeyboard() -{ - if( !SDL_ANDROID_isTouchscreenKeyboardUsed || !touchscreenKeyboardShown ) - return 0; - - beginDrawingTex(); - - if(sunTheme) - drawTouchscreenKeyboardSun(); - else - drawTouchscreenKeyboardLegacy(); - - endDrawingTex(); - - return 1; -}; - -static inline int ArrowKeysPressed(int x, int y) -{ - int ret = 0, dx, dy; - dx = x - arrows.x - arrows.w / 2; - dy = y - arrows.y - arrows.h / 2; - // Single arrow key pressed - if( abs(dy / 2) >= abs(dx) ) - { - if( dy < 0 ) - ret |= ARROW_UP; - else - ret |= ARROW_DOWN; - } - else - if( abs(dx / 2) >= abs(dy) ) - { - if( dx > 0 ) - ret |= ARROW_RIGHT; - else - ret |= ARROW_LEFT; - } - else // Two arrow keys pressed - { - if( dx > 0 ) - ret |= ARROW_RIGHT; - else - ret |= ARROW_LEFT; - - if( dy < 0 ) - ret |= ARROW_UP; - else - ret |= ARROW_DOWN; - } - return ret; -} - -int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointerId) -{ - int i; - int processed = 0; - - - if( !touchscreenKeyboardShown ) - return 0; - - - if( action == MOUSE_DOWN ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "touch %03dx%03d ptr %d action %d", x, y, pointerId, action); - if( InsideRect( &arrows, x, y ) ) - { - processed = 1; - if( pointerInButtonRect[BUTTON_ARROWS] == -1 ) - { - pointerInButtonRect[BUTTON_ARROWS] = pointerId; - joystickTouchPoints[0] = x; - joystickTouchPoints[1] = y; - if( SDL_ANDROID_isJoystickUsed ) - { - SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, (x - arrows.x - arrows.w / 2) * 65534 / arrows.w ); - SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, (y - arrows.y - arrows.h / 2) * 65534 / arrows.h ); - } - else - { - i = ArrowKeysPressed(x, y); - if( i & ARROW_UP ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(UP) ); - if( i & ARROW_DOWN ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(DOWN) ); - if( i & ARROW_LEFT ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(LEFT) ); - if( i & ARROW_RIGHT ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(RIGHT) ); - oldArrows = i; - } - } - } - - for( i = 0; i < MAX_BUTTONS; i++ ) - { - if( ! buttons[i].h || ! buttons[i].w ) - continue; - if( InsideRect( &buttons[i], x, y) ) - { - processed = 1; - if( pointerInButtonRect[i] == -1 ) - { - pointerInButtonRect[i] = pointerId; - if( i == BUTTON_TEXT_INPUT ) - SDL_ANDROID_ToggleScreenKeyboardTextInput(NULL); - else - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, buttonKeysyms[i] ); - if( i < AutoFireButtonsNum ) - { - ButtonAutoFire[i] = 0; - ButtonAutoFireX[i*2] = 0; - ButtonAutoFireX[i*2+1] = 0; - ButtonAutoFireRot[i] = x; - ButtonAutoFireDecay[i] = SDL_GetTicks(); - } - } - } - } - } - else - if( action == MOUSE_UP ) - { - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "touch %03dx%03d ptr %d action %d", x, y, pointerId, action); - if( pointerInButtonRect[BUTTON_ARROWS] == pointerId ) - { - processed = 1; - pointerInButtonRect[BUTTON_ARROWS] = -1; - if( SDL_ANDROID_isJoystickUsed ) - { - SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, 0 ); - SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, 0 ); - } - else - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(UP) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(DOWN) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(LEFT) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(RIGHT) ); - oldArrows = 0; - } - } - for( i = 0; i < MAX_BUTTONS; i++ ) - { - if( ! buttons[i].h || ! buttons[i].w ) - continue; - if( pointerInButtonRect[i] == pointerId ) - { - processed = 1; - pointerInButtonRect[i] = -1; - if( i < AutoFireButtonsNum && ButtonAutoFire[i] ) - { - ButtonAutoFire[i] = 2; - } - else - { - if( i != BUTTON_TEXT_INPUT ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, buttonKeysyms[i] ); - } - if( i < AutoFireButtonsNum ) - { - ButtonAutoFireX[i*2] = 0; - ButtonAutoFireX[i*2+1] = 0; - } - } - } - } - else - if( action == MOUSE_MOVE ) - { - // Process cases when pointer enters button area (it won't send keypress twice if button already pressed) - processed = SDL_ANDROID_processTouchscreenKeyboard(x, y, MOUSE_DOWN, pointerId); - - // Process cases when pointer leaves button area - // TODO: huge code size, split it or somehow make it more readable - if( pointerInButtonRect[BUTTON_ARROWS] == pointerId ) - { - processed = 1; - if( ! InsideRect( &arrowsExtended, x, y ) ) - { - pointerInButtonRect[BUTTON_ARROWS] = -1; - if( SDL_ANDROID_isJoystickUsed ) - { - SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, 0 ); - SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, 0 ); - } - else - { - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(UP) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(DOWN) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(LEFT) ); - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(RIGHT) ); - oldArrows = 0; - } - } - else - { - joystickTouchPoints[0] = x; - joystickTouchPoints[1] = y; - if( SDL_ANDROID_isJoystickUsed ) - { - SDL_ANDROID_MainThreadPushJoystickAxis(0, 0, (x - arrows.x - arrows.w / 2) * 65534 / arrows.w ); - SDL_ANDROID_MainThreadPushJoystickAxis(0, 1, (y - arrows.y - arrows.h / 2) * 65534 / arrows.h ); - } - else - { - i = ArrowKeysPressed(x, y); - if( i != oldArrows ) - { - if( oldArrows & ARROW_UP && ! (i & ARROW_UP) ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(UP) ); - if( oldArrows & ARROW_DOWN && ! (i & ARROW_DOWN) ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(DOWN) ); - if( oldArrows & ARROW_LEFT && ! (i & ARROW_LEFT) ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(LEFT) ); - if( oldArrows & ARROW_RIGHT && ! (i & ARROW_RIGHT) ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, SDL_KEY(RIGHT) ); - if( i & ARROW_UP ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(UP) ); - if( i & ARROW_DOWN ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(DOWN) ); - if( i & ARROW_LEFT ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(LEFT) ); - if( i & ARROW_RIGHT ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_PRESSED, SDL_KEY(RIGHT) ); - } - oldArrows = i; - } - } - } - for( i = 0; i < AutoFireButtonsNum; i++ ) - { - if( pointerInButtonRect[i] == pointerId ) - { - processed = 1; - if( ! InsideRect( &buttonsAutoFireRect[i], x, y ) ) - { - pointerInButtonRect[i] = -1; - if( !ButtonAutoFire[i] ) - { - if( i != BUTTON_TEXT_INPUT ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, buttonKeysyms[i] ); - } - else - { - ButtonAutoFire[i] = 2; - } - ButtonAutoFireX[i*2] = 0; - ButtonAutoFireX[i*2+1] = 0; - } - else - { - int coeff = (buttonAutoFireImages[i*2+1].w > buttons[i].w) ? buttonAutoFireImages[i*2+1].w / buttons[i].w + 1 : 1; - if( ButtonAutoFireRot[i] < x ) - ButtonAutoFireX[i*2+1] += (x - ButtonAutoFireRot[i]) * coeff; - if( ButtonAutoFireRot[i] > x ) - ButtonAutoFireX[i*2] += (ButtonAutoFireRot[i] - x) * coeff; - - ButtonAutoFireRot[i] = x; - - if( ButtonAutoFireX[i*2] < 0 ) - ButtonAutoFireX[i*2] = 0; - if( ButtonAutoFireX[i*2+1] < 0 ) - ButtonAutoFireX[i*2+1] = 0; - if( ButtonAutoFireX[i*2] > buttonAutoFireImages[i*2+1].w / 2 ) - ButtonAutoFireX[i*2] = buttonAutoFireImages[i*2+1].w / 2; - if( ButtonAutoFireX[i*2+1] > buttonAutoFireImages[i*2+1].w / 2 ) - ButtonAutoFireX[i*2+1] = buttonAutoFireImages[i*2+1].w / 2; - - if( ButtonAutoFireX[i*2] == buttonAutoFireImages[i*2+1].w / 2 && - ButtonAutoFireX[i*2+1] == buttonAutoFireImages[i*2+1].w / 2 ) - { - if( ! ButtonAutoFire[i] ) - ButtonAutoFireDecay[i] = SDL_GetTicks(); - ButtonAutoFire[i] = 1; - } - } - } - } - for( i = AutoFireButtonsNum; i < MAX_BUTTONS; i++ ) - { - if( ! buttons[i].h || ! buttons[i].w ) - continue; - if( pointerInButtonRect[i] == pointerId ) - { - processed = 1; - if( ! InsideRect( &buttons[i], x, y ) ) - { - pointerInButtonRect[i] = -1; - if( i != BUTTON_TEXT_INPUT ) - SDL_ANDROID_MainThreadPushKeyboardKey( SDL_RELEASED, buttonKeysyms[i] ); - } - } - } - } - - return processed; -}; - -void shrinkButtonRect(SDL_Rect s, SDL_Rect * d) -{ - int i; - - if( !buttonDrawSize ) - { - memcpy(d, &s, sizeof(s)); - return; - } - - d->w = s.w * 2 / (buttonDrawSize+2); - d->h = s.h * 2 / (buttonDrawSize+2); - d->x = s.x + s.w / 2 - d->w / 2; - d->y = s.y + s.h / 2 - d->h / 2; -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thiz, jint size, jint drawsize, jint theme, jint nbuttonsAutoFire, jint _transparency ) -{ - int i, ii; - int nbuttons1row, nbuttons2row; - int _nbuttons = MAX_BUTTONS; - SDL_Rect * r; - touchscreenKeyboardTheme = theme; - AutoFireButtonsNum = nbuttonsAutoFire; - if( AutoFireButtonsNum > MAX_BUTTONS_AUTOFIRE ) - AutoFireButtonsNum = MAX_BUTTONS_AUTOFIRE; - // TODO: works for horizontal screen orientation only! - buttonsize = size; - buttonDrawSize = drawsize; - switch(_transparency) - { - case 0: transparency = 32; break; - case 1: transparency = 64; break; - case 2: transparency = 128; break; - case 3: transparency = 192; break; - case 4: transparency = 255; break; - default: transparency = 192; break; - } - - // Arrows to the lower-left part of screen - arrows.w = SDL_ANDROID_sWindowWidth / (size + 2) * 2 / 3; - arrows.h = arrows.w; - // Move to the screen edge - arrows.x = 0; - arrows.y = SDL_ANDROID_sWindowHeight - arrows.h; - - arrowsExtended.w = arrows.w * 2; - arrowsExtended.h = arrows.h * 2; - arrowsExtended.x = arrows.x + arrows.w / 2 - arrowsExtended.w / 2; - arrowsExtended.y = arrows.y + arrows.h / 2 - arrowsExtended.h / 2; - /* - // This will leave some unused space near the edge - arrows.x = SDL_ANDROID_sWindowWidth / 4; - arrows.y = SDL_ANDROID_sWindowHeight - SDL_ANDROID_sWindowWidth / 4; - arrows.x -= arrows.w/2; - arrows.y -= arrows.h/2; - // Move arrows from the center of the screen - arrows.x -= size * SDL_ANDROID_sWindowWidth / 32; - arrows.y += size * SDL_ANDROID_sWindowWidth / 32; - */ - - // Buttons to the lower-right in 2 rows - for(i = 0; i < 3; i++) - for(ii = 0; ii < 2; ii++) - { - // Custom button ordering - int iii = ii + i*2; - buttons[iii].w = SDL_ANDROID_sWindowWidth / (size + 2) / 3; - buttons[iii].h = buttons[iii].w; - // Move to the screen edge - buttons[iii].x = SDL_ANDROID_sWindowWidth - buttons[iii].w * (ii + 1); - buttons[iii].y = SDL_ANDROID_sWindowHeight - buttons[iii].h * (i + 1); - /* - // This will leave some unused space near the edge and between buttons - buttons[iii].x = SDL_ANDROID_sWindowWidth - SDL_ANDROID_sWindowWidth / 12 - (SDL_ANDROID_sWindowWidth * ii / 6); - buttons[iii].y = SDL_ANDROID_sWindowHeight - SDL_ANDROID_sWindowHeight / 8 - (SDL_ANDROID_sWindowHeight * i / 4); - buttons[iii].x -= buttons[iii].w/2; - buttons[iii].y -= buttons[iii].h/2; - */ - } - buttons[6].x = 0; - buttons[6].y = 0; - buttons[6].w = SDL_ANDROID_sWindowHeight/10; - buttons[6].h = SDL_ANDROID_sWindowHeight/10; - - for( i = 0; i < sizeof(pointerInButtonRect)/sizeof(pointerInButtonRect[0]); i++ ) - { - pointerInButtonRect[i] = -1; - } - for( i = 0; i < nbuttonsAutoFire; i++ ) - { - buttonsAutoFireRect[i].w = buttons[i].w * 2; - buttonsAutoFireRect[i].h = buttons[i].h * 2; - buttonsAutoFireRect[i].x = buttons[i].x - buttons[i].w / 2; - buttonsAutoFireRect[i].y = buttons[i].y - buttons[i].h / 2; - } - shrinkButtonRect(arrows, &arrowsDraw); - for(i = 0; i < MAX_BUTTONS; i++) - { - shrinkButtonRect(buttons[i], &buttonsDraw[i]); - } -}; - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetTouchscreenKeyboardUsed) ( JNIEnv* env, jobject thiz) -{ - SDL_ANDROID_isTouchscreenKeyboardUsed = 1; -} - -void SDL_ANDROID_DrawMouseCursor(int x, int y, int size, int alpha) -{ - SDL_Rect r; - // I've failed with size calcualtions, so leaving it as-is - r.x = x - MOUSE_POINTER_X; - r.y = y - MOUSE_POINTER_Y; - r.w = MOUSE_POINTER_W; - r.h = MOUSE_POINTER_H; - beginDrawingTex(); - drawCharTex( &mousePointer, NULL, &r, 255, 255, 255, alpha ); - endDrawingTex(); -} - -static int -power_of_2(int input) -{ - int value = 1; - - while (value < input) { - value <<= 1; - } - return value; -} - -static int setupScreenKeyboardButtonTexture( GLTexture_t * data, Uint8 * charBuf ) -{ - int w, h, format, bpp; - int texture_w, texture_h; - - memcpy(&w, charBuf, sizeof(int)); - memcpy(&h, charBuf + sizeof(int), sizeof(int)); - memcpy(&format, charBuf + 2*sizeof(int), sizeof(int)); - w = ntohl(w); - h = ntohl(h); - format = ntohl(format); - bpp = 2; - if(format == 2) - bpp = 4; - - texture_w = power_of_2(w); - texture_h = power_of_2(h); - data->w = w; - data->h = h; - - glEnable(GL_TEXTURE_2D); - - glGenTextures(1, &data->id); - glBindTexture(GL_TEXTURE_2D, data->id); - //__android_log_print(ANDROID_LOG_INFO, "libSDL", "On-screen keyboard generated OpenGL texture ID %d", data->id); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_w, texture_h, 0, GL_RGBA, - bpp == 4 ? GL_UNSIGNED_BYTE : (format ? GL_UNSIGNED_SHORT_4_4_4_4 : GL_UNSIGNED_SHORT_5_5_5_1), NULL); - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, GL_RGBA, - bpp == 4 ? GL_UNSIGNED_BYTE : (format ? GL_UNSIGNED_SHORT_4_4_4_4 : GL_UNSIGNED_SHORT_5_5_5_1), - charBuf + 3*sizeof(int) ); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glDisable(GL_TEXTURE_2D); - - return 3*sizeof(int) + w * h * bpp; -} - -static int setupScreenKeyboardButtonLegacy( int buttonID, Uint8 * charBuf ) -{ - GLTexture_t * data = NULL; - - if( buttonID < 5 ) - data = &(arrowImages[buttonID]); - else - if( buttonID < 9 ) - data = &(buttonAutoFireImages[buttonID-5]); - else - data = &(buttonImages[buttonID-9]); - - if( buttonID == 23 ) - data = &mousePointer; - else if( buttonID > 22 ) // Error, array too big - return 12; // Return value bigger than zero to iterate it - - return setupScreenKeyboardButtonTexture(data, charBuf); -} - -static int setupScreenKeyboardButtonSun( int buttonID, Uint8 * charBuf ) -{ - GLTexture_t * data = NULL; - int i, ret; - - if( buttonID == 0 ) - data = &(arrowImages[0]); - if( buttonID >= 1 && buttonID <= 4 ) - data = &(buttonImages[buttonID-1]); - if( buttonID >= 5 && buttonID <= 8 ) - data = &(buttonImages[4+(buttonID-5)*2]); - if( buttonID == 9 ) - data = &mousePointer; - else if( buttonID > 9 ) // Error, array too big - return 12; // Return value bigger than zero to iterate it - - ret = setupScreenKeyboardButtonTexture(data, charBuf); - - for( i = 1; i <=4; i++ ) - arrowImages[i] = arrowImages[0]; - - for( i = 2; i < MAX_BUTTONS; i++ ) - buttonImages[i * 2 + 1] = buttonImages[i * 2]; - - for( i = 0; i < MAX_BUTTONS_AUTOFIRE*2; i++ ) - buttonAutoFireImages[i] = arrowImages[0]; - - buttonImages[BUTTON_TEXT_INPUT*2] = buttonImages[10]; - buttonImages[BUTTON_TEXT_INPUT*2+1] = buttonImages[10]; - - return ret; -} - -static int setupScreenKeyboardButton( int buttonID, Uint8 * charBuf, int count ) -{ - if(count == 24) - { - sunTheme = 0; - return setupScreenKeyboardButtonLegacy(buttonID, charBuf); - } - else if(count == 10) - { - sunTheme = 1; - return setupScreenKeyboardButtonSun(buttonID, charBuf); - } - else - { - __android_log_print(ANDROID_LOG_FATAL, "libSDL", "On-screen keyboard buton img count = %d, should be 10 or 24", count); - return 12; // Return value bigger than zero to iterate it - } -} - - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboardButtons) ( JNIEnv* env, jobject thiz, jbyteArray charBufJava ) -{ - jboolean isCopy = JNI_TRUE; - int len = (*env)->GetArrayLength(env, charBufJava); - Uint8 * charBuf = (Uint8 *) (*env)->GetByteArrayElements(env, charBufJava, &isCopy); - int but, pos, count; - memcpy(&count, charBuf, sizeof(int)); - count = ntohl(count); - - for( but = 0, pos = sizeof(int); pos < len; but ++ ) - pos += setupScreenKeyboardButton( but, charBuf + pos, count ); - - (*env)->ReleaseByteArrayElements(env, charBufJava, (jbyte *)charBuf, 0); -} - - -int SDL_ANDROID_SetScreenKeyboardButtonPos(int buttonId, SDL_Rect * pos) -{ - if( buttonId < 0 || buttonId >= SDL_ANDROID_SCREENKEYBOARD_BUTTON_NUM || ! pos ) - return 0; - - if( buttonId == SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD ) - { - arrows = *pos; - arrowsExtended.w = arrows.w * 2; - arrowsExtended.h = arrows.h * 2; - arrowsExtended.x = arrows.x + arrows.w / 2 - arrowsExtended.w / 2; - arrowsExtended.y = arrows.y + arrows.h / 2 - arrowsExtended.h / 2; - shrinkButtonRect(arrows, &arrowsDraw); - } - else - { - int i = buttonId - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0; - buttons[i] = *pos; - shrinkButtonRect(buttons[i], &buttonsDraw[i]); - if( i < AutoFireButtonsNum ) - { - buttonsAutoFireRect[i].w = buttons[i].w * 3 / 2; - buttonsAutoFireRect[i].h = buttons[i].h * 3 / 2; - buttonsAutoFireRect[i].x = buttons[i].x + buttons[i].w / 2 - buttonsAutoFireRect[i].w / 2; - buttonsAutoFireRect[i].y = buttons[i].y + buttons[i].h / 2 - buttonsAutoFireRect[i].h / 2; - } - } - return 1; -}; - -int SDL_ANDROID_GetScreenKeyboardButtonPos(int buttonId, SDL_Rect * pos) -{ - if( buttonId < 0 || buttonId >= SDL_ANDROID_SCREENKEYBOARD_BUTTON_NUM || ! pos ) - return 0; - - if( buttonId == SDL_ANDROID_SCREENKEYBOARD_BUTTON_DPAD ) - { - *pos = arrows; - } - else - { - *pos = buttons[buttonId - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0]; - } - return 1; -}; - -int SDL_ANDROID_SetScreenKeyboardButtonKey(int buttonId, SDLKey key) -{ - if( buttonId < SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 || buttonId > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 || ! key ) - return 0; - buttonKeysyms[buttonId - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0] = key; - return 1; -}; - -SDLKey SDL_ANDROID_GetScreenKeyboardButtonKey(int buttonId) -{ - if( buttonId < SDL_ANDROID_SCREENKEYBOARD_BUTTON_0 || buttonId > SDL_ANDROID_SCREENKEYBOARD_BUTTON_5 ) - return SDLK_UNKNOWN; - return buttonKeysyms[buttonId - SDL_ANDROID_SCREENKEYBOARD_BUTTON_0]; -}; - -int SDL_ANDROID_SetScreenKeyboardAutoFireButtonsAmount(int nbuttons) -{ - if( nbuttons < 0 || nbuttons >= MAX_BUTTONS_AUTOFIRE ) - return 0; - AutoFireButtonsNum = nbuttons; - return 1; -}; - -int SDL_ANDROID_GetScreenKeyboardAutoFireButtonsAmount(void) -{ - return AutoFireButtonsNum; -}; - -int SDL_ANDROID_SetScreenKeyboardShown(int shown) -{ - touchscreenKeyboardShown = shown; -}; - -int SDL_ANDROID_GetScreenKeyboardShown(void) -{ - return touchscreenKeyboardShown; -}; - -int SDL_ANDROID_GetScreenKeyboardSize(void) -{ - return buttonsize; -}; - -int SDL_ANDROID_ToggleScreenKeyboardTextInput(const char * previousText) -{ - static char textIn[255]; - if( previousText == NULL ) - previousText = ""; - strncpy(textIn, previousText, sizeof(textIn)); - textIn[sizeof(textIn)-1] = 0; - SDL_ANDROID_CallJavaShowScreenKeyboard(textIn, NULL, 0); - return 1; -}; - -int SDLCALL SDL_ANDROID_GetScreenKeyboardTextInput(char * textBuf, int textBufSize) -{ - SDL_ANDROID_CallJavaShowScreenKeyboard(textBuf, textBuf, textBufSize); - return 1; -}; - -// That's probably not the right file to put this func -JNIEXPORT jint JNICALL -JAVA_EXPORT_NAME(Settings_nativeChmod) ( JNIEnv* env, jobject thiz, jstring j_name, jint mode ) -{ - jboolean iscopy; - const char *name = (*env)->GetStringUTFChars(env, j_name, &iscopy); - int ret = chmod(name, mode); - (*env)->ReleaseStringUTFChars(env, j_name, name); - return (ret == 0); -} - -JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetEnv) ( JNIEnv* env, jobject thiz, jstring j_name, jstring j_value ) -{ - jboolean iscopy; - const char *name = (*env)->GetStringUTFChars(env, j_name, &iscopy); - const char *value = (*env)->GetStringUTFChars(env, j_value, &iscopy); - setenv(name, value, 1); - (*env)->ReleaseStringUTFChars(env, j_name, name); - (*env)->ReleaseStringUTFChars(env, j_value, value); -} diff --git a/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c b/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c new file mode 120000 index 000000000..a2b4900b2 --- /dev/null +++ b/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c @@ -0,0 +1 @@ +../../../../sdl-1.2/src/video/android/SDL_touchscreenkeyboard.c \ No newline at end of file diff --git a/project/jni/sdl-1.3/src/video/android/atan2i.h b/project/jni/sdl-1.3/src/video/android/atan2i.h deleted file mode 100644 index e7111a618..000000000 --- a/project/jni/sdl-1.3/src/video/android/atan2i.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __ATAN2I_H__ -#define __ATAN2I_H__ -#include - -// Fast arctan2, returns angle in radians as integer, with fractional part in lower 16 bits -// Stolen from http://www.dspguru.com/dsp/tricks/fixed-point-atan2-with-self-normalization , precision is said to be 0.07 rads - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif -enum { atan2i_coeff_1 = ((int)(M_PI*65536.0/4)), atan2i_coeff_2 = (3*atan2i_coeff_1), atan2i_PI = (int)(M_PI * 65536.0) }; - -static inline int atan2i(int y, int x) -{ - int angle; - int abs_y = abs(y); - if( abs_y == 0 ) - abs_y = 1; - if (x>=0) - { - angle = atan2i_coeff_1 - atan2i_coeff_1 * (x - abs_y) / (x + abs_y); - } - else - { - angle = atan2i_coeff_2 - atan2i_coeff_1 * (x + abs_y) / (abs_y - x); - } - if (y < 0) - return(-angle); // negate if in quad III or IV - else - return(angle); -}; - -#endif diff --git a/project/jni/sdl-1.3/src/video/android/atan2i.h b/project/jni/sdl-1.3/src/video/android/atan2i.h new file mode 120000 index 000000000..2da4a0e8f --- /dev/null +++ b/project/jni/sdl-1.3/src/video/android/atan2i.h @@ -0,0 +1 @@ +../../../../sdl-1.2/src/video/android/atan2i.h \ No newline at end of file diff --git a/project/jni/sdl-1.3/src/video/android/javakeycodes.h b/project/jni/sdl-1.3/src/video/android/javakeycodes.h deleted file mode 100644 index 4c07fc397..000000000 --- a/project/jni/sdl-1.3/src/video/android/javakeycodes.h +++ /dev/null @@ -1,215 +0,0 @@ -#ifndef _JAVA_KEY_CODES_H_ -#define _JAVA_KEY_CODES_H_ - -// Keycodes ripped from Java SDK -enum KEYCODES_ANDROID -{ -KEYCODE_UNKNOWN = 0, -KEYCODE_SOFT_LEFT = 1, -KEYCODE_SOFT_RIGHT = 2, -KEYCODE_HOME = 3, -KEYCODE_BACK = 4, -KEYCODE_CALL = 5, -KEYCODE_ENDCALL = 6, -KEYCODE_0 = 7, -KEYCODE_1 = 8, -KEYCODE_2 = 9, -KEYCODE_3 = 10, -KEYCODE_4 = 11, -KEYCODE_5 = 12, -KEYCODE_6 = 13, -KEYCODE_7 = 14, -KEYCODE_8 = 15, -KEYCODE_9 = 16, -KEYCODE_STAR = 17, -KEYCODE_POUND = 18, -KEYCODE_DPAD_UP = 19, -KEYCODE_DPAD_DOWN = 20, -KEYCODE_DPAD_LEFT = 21, -KEYCODE_DPAD_RIGHT = 22, -KEYCODE_DPAD_CENTER = 23, -KEYCODE_VOLUME_UP = 24, -KEYCODE_VOLUME_DOWN = 25, -KEYCODE_POWER = 26, -KEYCODE_CAMERA = 27, -KEYCODE_CLEAR = 28, -KEYCODE_A = 29, -KEYCODE_B = 30, -KEYCODE_C = 31, -KEYCODE_D = 32, -KEYCODE_E = 33, -KEYCODE_F = 34, -KEYCODE_G = 35, -KEYCODE_H = 36, -KEYCODE_I = 37, -KEYCODE_J = 38, -KEYCODE_K = 39, -KEYCODE_L = 40, -KEYCODE_M = 41, -KEYCODE_N = 42, -KEYCODE_O = 43, -KEYCODE_P = 44, -KEYCODE_Q = 45, -KEYCODE_R = 46, -KEYCODE_S = 47, -KEYCODE_T = 48, -KEYCODE_U = 49, -KEYCODE_V = 50, -KEYCODE_W = 51, -KEYCODE_X = 52, -KEYCODE_Y = 53, -KEYCODE_Z = 54, -KEYCODE_COMMA = 55, -KEYCODE_PERIOD = 56, -KEYCODE_ALT_LEFT = 57, -KEYCODE_ALT_RIGHT = 58, -KEYCODE_SHIFT_LEFT = 59, -KEYCODE_SHIFT_RIGHT = 60, -KEYCODE_TAB = 61, -KEYCODE_SPACE = 62, -KEYCODE_SYM = 63, -KEYCODE_EXPLORER = 64, -KEYCODE_ENVELOPE = 65, -KEYCODE_ENTER = 66, -KEYCODE_DEL = 67, -KEYCODE_GRAVE = 68, -KEYCODE_MINUS = 69, -KEYCODE_EQUALS = 70, -KEYCODE_LEFT_BRACKET = 71, -KEYCODE_RIGHT_BRACKET = 72, -KEYCODE_BACKSLASH = 73, -KEYCODE_SEMICOLON = 74, -KEYCODE_APOSTROPHE = 75, -KEYCODE_SLASH = 76, -KEYCODE_AT = 77, -KEYCODE_NUM = 78, -KEYCODE_HEADSETHOOK = 79, -KEYCODE_FOCUS = 80, -KEYCODE_PLUS = 81, -KEYCODE_MENU = 82, -KEYCODE_NOTIFICATION = 83, -KEYCODE_SEARCH = 84, -KEYCODE_MEDIA_PLAY_PAUSE= 85, -KEYCODE_MEDIA_STOP = 86, -KEYCODE_MEDIA_NEXT = 87, -KEYCODE_MEDIA_PREVIOUS = 88, -KEYCODE_MEDIA_REWIND = 89, -KEYCODE_MEDIA_FAST_FORWARD = 90, -KEYCODE_MUTE = 91, -KEYCODE_PAGE_UP = 92, -KEYCODE_PAGE_DOWN = 93, -KEYCODE_PICTSYMBOLS = 94, -KEYCODE_SWITCH_CHARSET = 95, -KEYCODE_BUTTON_A = 96, -KEYCODE_BUTTON_B = 97, -KEYCODE_BUTTON_C = 98, -KEYCODE_BUTTON_X = 99, -KEYCODE_BUTTON_Y = 100, -KEYCODE_BUTTON_Z = 101, -KEYCODE_BUTTON_L1 = 102, -KEYCODE_BUTTON_R1 = 103, -KEYCODE_BUTTON_L2 = 104, -KEYCODE_BUTTON_R2 = 105, -KEYCODE_BUTTON_THUMBL = 106, -KEYCODE_BUTTON_THUMBR = 107, -KEYCODE_BUTTON_START = 108, -KEYCODE_BUTTON_SELECT = 109, -KEYCODE_BUTTON_MODE = 110, -KEYCODE_ESCAPE = 111, -KEYCODE_FORWARD_DEL = 112, -KEYCODE_CTRL_LEFT = 113, -KEYCODE_CTRL_RIGHT = 114, -KEYCODE_CAPS_LOCK = 115, -KEYCODE_SCROLL_LOCK = 116, -KEYCODE_META_LEFT = 117, -KEYCODE_META_RIGHT = 118, -KEYCODE_FUNCTION = 119, -KEYCODE_SYSRQ = 120, -KEYCODE_BREAK = 121, -KEYCODE_MOVE_HOME = 122, -KEYCODE_MOVE_END = 123, -KEYCODE_INSERT = 124, -KEYCODE_FORWARD = 125, -KEYCODE_MEDIA_PLAY = 126, -KEYCODE_MEDIA_PAUSE = 127, -KEYCODE_MEDIA_CLOSE = 128, -KEYCODE_MEDIA_EJECT = 129, -KEYCODE_MEDIA_RECORD = 130, -KEYCODE_F1 = 131, -KEYCODE_F2 = 132, -KEYCODE_F3 = 133, -KEYCODE_F4 = 134, -KEYCODE_F5 = 135, -KEYCODE_F6 = 136, -KEYCODE_F7 = 137, -KEYCODE_F8 = 138, -KEYCODE_F9 = 139, -KEYCODE_F10 = 140, -KEYCODE_F11 = 141, -KEYCODE_F12 = 142, -KEYCODE_NUM_LOCK = 143, -KEYCODE_NUMPAD_0 = 144, -KEYCODE_NUMPAD_1 = 145, -KEYCODE_NUMPAD_2 = 146, -KEYCODE_NUMPAD_3 = 147, -KEYCODE_NUMPAD_4 = 148, -KEYCODE_NUMPAD_5 = 149, -KEYCODE_NUMPAD_6 = 150, -KEYCODE_NUMPAD_7 = 151, -KEYCODE_NUMPAD_8 = 152, -KEYCODE_NUMPAD_9 = 153, -KEYCODE_NUMPAD_DIVIDE = 154, -KEYCODE_NUMPAD_MULTIPLY = 155, -KEYCODE_NUMPAD_SUBTRACT = 156, -KEYCODE_NUMPAD_ADD = 157, -KEYCODE_NUMPAD_DOT = 158, -KEYCODE_NUMPAD_COMMA = 159, -KEYCODE_NUMPAD_ENTER = 160, -KEYCODE_NUMPAD_EQUALS = 161, -KEYCODE_NUMPAD_LEFT_PAREN = 162, -KEYCODE_NUMPAD_RIGHT_PAREN = 163, -KEYCODE_VOLUME_MUTE = 164, -KEYCODE_INFO = 165, -KEYCODE_CHANNEL_UP = 166, -KEYCODE_CHANNEL_DOWN = 167, -KEYCODE_ZOOM_IN = 168, -KEYCODE_ZOOM_OUT = 169, -KEYCODE_TV = 170, -KEYCODE_WINDOW = 171, -KEYCODE_GUIDE = 172, -KEYCODE_DVR = 173, -KEYCODE_BOOKMARK = 174, -KEYCODE_CAPTIONS = 175, -KEYCODE_SETTINGS = 176, -KEYCODE_TV_POWER = 177, -KEYCODE_TV_INPUT = 178, -KEYCODE_STB_POWER = 179, -KEYCODE_STB_INPUT = 180, -KEYCODE_AVR_POWER = 181, -KEYCODE_AVR_INPUT = 182, -KEYCODE_PROG_RED = 183, -KEYCODE_PROG_GREEN = 184, -KEYCODE_PROG_YELLOW = 185, -KEYCODE_PROG_BLUE = 186, -KEYCODE_APP_SWITCH = 187, -KEYCODE_BUTTON_1 = 188, -KEYCODE_BUTTON_2 = 189, -KEYCODE_BUTTON_3 = 190, -KEYCODE_BUTTON_4 = 191, -KEYCODE_BUTTON_5 = 192, -KEYCODE_BUTTON_6 = 193, -KEYCODE_BUTTON_7 = 194, -KEYCODE_BUTTON_8 = 195, -KEYCODE_BUTTON_9 = 196, -KEYCODE_BUTTON_10 = 197, -KEYCODE_BUTTON_11 = 198, -KEYCODE_BUTTON_12 = 199, -KEYCODE_BUTTON_13 = 200, -KEYCODE_BUTTON_14 = 201, -KEYCODE_BUTTON_15 = 202, -KEYCODE_BUTTON_16 = 203, - -KEYCODE_LAST = 255 // Android 2.3 added several new gaming keys, Android 3.1 added even more - plz keep in sync with Keycodes.java -}; - -#endif diff --git a/project/jni/sdl-1.3/src/video/android/javakeycodes.h b/project/jni/sdl-1.3/src/video/android/javakeycodes.h new file mode 120000 index 000000000..b273cfdfc --- /dev/null +++ b/project/jni/sdl-1.3/src/video/android/javakeycodes.h @@ -0,0 +1 @@ +../../../../sdl-1.2/src/video/android/javakeycodes.h \ No newline at end of file diff --git a/project/jni/sdl-1.3/src/video/android/jniwrapperstuff.h b/project/jni/sdl-1.3/src/video/android/jniwrapperstuff.h deleted file mode 100644 index 6a37980aa..000000000 --- a/project/jni/sdl-1.3/src/video/android/jniwrapperstuff.h +++ /dev/null @@ -1,13 +0,0 @@ - -/* JNI-C++ wrapper stuff */ -#ifndef _JNI_WRAPPER_STUFF_H_ -#define _JNI_WRAPPER_STUFF_H_ - -#ifndef SDL_JAVA_PACKAGE_PATH -#error You have to define SDL_JAVA_PACKAGE_PATH to your package path with dots replaced with underscores, for example "com_example_SanAngeles" -#endif -#define JAVA_EXPORT_NAME2(name,package) Java_##package##_##name -#define JAVA_EXPORT_NAME1(name,package) JAVA_EXPORT_NAME2(name,package) -#define JAVA_EXPORT_NAME(name) JAVA_EXPORT_NAME1(name,SDL_JAVA_PACKAGE_PATH) - -#endif diff --git a/project/jni/sdl-1.3/src/video/android/jniwrapperstuff.h b/project/jni/sdl-1.3/src/video/android/jniwrapperstuff.h new file mode 120000 index 000000000..f7ad13ff1 --- /dev/null +++ b/project/jni/sdl-1.3/src/video/android/jniwrapperstuff.h @@ -0,0 +1 @@ +../../../../sdl-1.2/src/video/android/jniwrapperstuff.h \ No newline at end of file diff --git a/project/jni/sdl-1.3/src/video/android/keymap.c b/project/jni/sdl-1.3/src/video/android/keymap.c deleted file mode 100644 index eb0eb69bc..000000000 --- a/project/jni/sdl-1.3/src/video/android/keymap.c +++ /dev/null @@ -1,242 +0,0 @@ -#include "SDL_config.h" - -#include "SDL_version.h" -#include "SDL_androidinput.h" -#include "SDL_screenkeyboard.h" - -void SDL_android_init_keymap(SDLKey *SDL_android_keymap) -{ - int i; - SDLKey * keymap = SDL_android_keymap; - - for (i=0; i