diff options
author | chai <chaifix@163.com> | 2019-01-31 18:38:35 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-01-31 18:38:35 +0800 |
commit | 2ec55fd974a63b705a4777c256d2222c874fa043 (patch) | |
tree | 48f1fea59ee9fc713a28a9aac3f05b98dc5ae66f /Source/3rdParty/SDL2/src/core/android | |
parent | c581dfbf1e849f393861d15e82aa6446c0c1c310 (diff) |
*SDL project
Diffstat (limited to 'Source/3rdParty/SDL2/src/core/android')
-rw-r--r-- | Source/3rdParty/SDL2/src/core/android/SDL_android.c | 426 | ||||
-rw-r--r-- | Source/3rdParty/SDL2/src/core/android/SDL_android.h | 29 |
2 files changed, 354 insertions, 101 deletions
diff --git a/Source/3rdParty/SDL2/src/core/android/SDL_android.c b/Source/3rdParty/SDL2/src/core/android/SDL_android.c index c40c676..a56575e 100644 --- a/Source/3rdParty/SDL2/src/core/android/SDL_android.c +++ b/Source/3rdParty/SDL2/src/core/android/SDL_android.c @@ -61,6 +61,10 @@ #define SDL_JAVA_CONTROLLER_INTERFACE(function) CONCAT1(SDL_JAVA_PREFIX, SDLControllerManager, function) #define SDL_JAVA_INTERFACE_INPUT_CONNECTION(function) CONCAT1(SDL_JAVA_PREFIX, SDLInputConnection, function) +/* Audio encoding definitions */ +#define ENCODING_PCM_8BIT 3 +#define ENCODING_PCM_16BIT 2 +#define ENCODING_PCM_FLOAT 4 /* Java class SDLActivity */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)( @@ -76,7 +80,8 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( JNIEnv* env, jclass jcls, - jint width, jint height, jint format, jfloat rate); + jint surfaceWidth, jint surfaceHeight, + jint deviceWidth, jint deviceHeight, jint format, jfloat rate); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeSurfaceChanged)( JNIEnv* env, jclass jcls); @@ -102,7 +107,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( JNIEnv* env, jclass jcls, - jint button, jint action, jfloat x, jfloat y); + jint button, jint action, jfloat x, jfloat y, jboolean relative); JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeAccel)( JNIEnv* env, jclass jcls, @@ -134,11 +139,19 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetenv)( JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeEnvironmentVariablesSet)( JNIEnv* env, jclass cls); +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)( + JNIEnv* env, jclass cls, + jint orientation); + /* Java class SDLInputConnection */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeCommitText)( JNIEnv* env, jclass cls, jstring text, jint newCursorPosition); +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeGenerateScancodeForUnichar)( + JNIEnv* env, jclass cls, + jchar chUnicode); + JNIEXPORT void JNICALL SDL_JAVA_INTERFACE_INPUT_CONNECTION(nativeSetComposingText)( JNIEnv* env, jclass cls, jstring text, jint newCursorPosition); @@ -169,8 +182,8 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( JNIEnv* env, jclass jcls, - jint device_id, jstring device_name, jstring device_desc, jint is_accelerometer, - jint nbuttons, jint naxes, jint nhats, jint nballs); + jint device_id, jstring device_name, jstring device_desc, jint vendor_id, jint product_id, + jboolean is_accelerometer, jint button_mask, jint naxes, jint nhats, jint nballs); JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveJoystick)( JNIEnv* env, jclass jcls, @@ -190,6 +203,7 @@ JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeRemoveHaptic)( /* #define DEBUG_JNI */ static void Android_JNI_ThreadDestroyed(void*); +static void checkJNIReady(void); /******************************************************************************* This file links the Java side of Android with libsdl @@ -212,7 +226,11 @@ static jmethodID midSetActivityTitle; static jmethodID midSetWindowStyle; static jmethodID midSetOrientation; static jmethodID midGetContext; +static jmethodID midIsTablet; static jmethodID midIsAndroidTV; +static jmethodID midIsChromebook; +static jmethodID midIsDeXMode; +static jmethodID midManualBackButton; static jmethodID midInputGetInputDeviceIds; static jmethodID midSendMessage; static jmethodID midShowTextInput; @@ -223,18 +241,25 @@ static jmethodID midClipboardHasText; static jmethodID midOpenAPKExpansionInputStream; static jmethodID midGetManifestEnvironmentVariables; static jmethodID midGetDisplayDPI; +static jmethodID midCreateCustomCursor; +static jmethodID midSetCustomCursor; +static jmethodID midSetSystemCursor; +static jmethodID midSupportsRelativeMouse; +static jmethodID midSetRelativeMouseEnabled; /* audio manager */ static jclass mAudioManagerClass; /* method signatures */ static jmethodID midAudioOpen; -static jmethodID midAudioWriteShortBuffer; static jmethodID midAudioWriteByteBuffer; +static jmethodID midAudioWriteShortBuffer; +static jmethodID midAudioWriteFloatBuffer; static jmethodID midAudioClose; static jmethodID midCaptureOpen; -static jmethodID midCaptureReadShortBuffer; static jmethodID midCaptureReadByteBuffer; +static jmethodID midCaptureReadShortBuffer; +static jmethodID midCaptureReadFloatBuffer; static jmethodID midCaptureClose; /* controller manager */ @@ -244,6 +269,7 @@ static jclass mControllerManagerClass; static jmethodID midPollInputDevices; static jmethodID midPollHapticDevices; static jmethodID midHapticRun; +static jmethodID midHapticStop; /* static fields */ static jfieldID fidSeparateMouseAndTouch; @@ -309,8 +335,16 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c "setOrientation","(IIZLjava/lang/String;)V"); midGetContext = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getContext","()Landroid/content/Context;"); + midIsTablet = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "isTablet", "()Z"); midIsAndroidTV = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "isAndroidTV","()Z"); + midIsChromebook = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "isChromebook", "()Z"); + midIsDeXMode = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "isDeXMode", "()Z"); + midManualBackButton = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, + "manualBackButton", "()V"); midInputGetInputDeviceIds = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "inputGetInputDeviceIds", "(I)[I"); midSendMessage = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, @@ -332,13 +366,21 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jclass c "getManifestEnvironmentVariables", "()Z"); midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;"); - midGetDisplayDPI = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "getDisplayDPI", "()Landroid/util/DisplayMetrics;"); + midCreateCustomCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "createCustomCursor", "([IIIII)I"); + midSetCustomCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setCustomCursor", "(I)Z"); + midSetSystemCursor = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setSystemCursor", "(I)Z"); + + midSupportsRelativeMouse = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "supportsRelativeMouse", "()Z"); + midSetRelativeMouseEnabled = (*mEnv)->GetStaticMethodID(mEnv, mActivityClass, "setRelativeMouseEnabled", "(Z)Z"); + if (!midGetNativeSurface || - !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsAndroidTV || !midInputGetInputDeviceIds || + !midSetActivityTitle || !midSetWindowStyle || !midSetOrientation || !midGetContext || !midIsTablet || !midIsAndroidTV || !midInputGetInputDeviceIds || !midSendMessage || !midShowTextInput || !midIsScreenKeyboardShown || !midClipboardSetText || !midClipboardGetText || !midClipboardHasText || - !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables|| !midGetDisplayDPI) { + !midOpenAPKExpansionInputStream || !midGetManifestEnvironmentVariables || !midGetDisplayDPI || + !midCreateCustomCursor || !midSetCustomCursor || !midSetSystemCursor || !midSupportsRelativeMouse || !midSetRelativeMouseEnabled || + !midIsChromebook || !midIsDeXMode || !midManualBackButton) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLActivity.java?"); } @@ -361,24 +403,28 @@ JNIEXPORT void JNICALL SDL_JAVA_AUDIO_INTERFACE(nativeSetupJNI)(JNIEnv* mEnv, jc mAudioManagerClass = (jclass)((*mEnv)->NewGlobalRef(mEnv, cls)); midAudioOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "audioOpen", "(IZZI)I"); - midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "audioWriteShortBuffer", "([S)V"); + "audioOpen", "(IIII)[I"); midAudioWriteByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, "audioWriteByteBuffer", "([B)V"); + midAudioWriteShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "audioWriteShortBuffer", "([S)V"); + midAudioWriteFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "audioWriteFloatBuffer", "([F)V"); midAudioClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, "audioClose", "()V"); midCaptureOpen = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "captureOpen", "(IZZI)I"); - midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, - "captureReadShortBuffer", "([SZ)I"); + "captureOpen", "(IIII)[I"); midCaptureReadByteBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, "captureReadByteBuffer", "([BZ)I"); + midCaptureReadShortBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "captureReadShortBuffer", "([SZ)I"); + midCaptureReadFloatBuffer = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, + "captureReadFloatBuffer", "([FZ)I"); midCaptureClose = (*mEnv)->GetStaticMethodID(mEnv, mAudioManagerClass, "captureClose", "()V"); - if (!midAudioOpen || !midAudioWriteShortBuffer || !midAudioWriteByteBuffer || !midAudioClose || - !midCaptureOpen || !midCaptureReadShortBuffer || !midCaptureReadByteBuffer || !midCaptureClose) { + if (!midAudioOpen || !midAudioWriteByteBuffer || !midAudioWriteShortBuffer || !midAudioWriteFloatBuffer || !midAudioClose || + !midCaptureOpen || !midCaptureReadByteBuffer || !midCaptureReadShortBuffer || !midCaptureReadFloatBuffer || !midCaptureClose) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLAudioManager.java?"); } @@ -399,9 +445,11 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeSetupJNI)(JNIEnv* mEn midPollHapticDevices = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, "pollHapticDevices", "()V"); midHapticRun = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, - "hapticRun", "(II)V"); + "hapticRun", "(IFI)V"); + midHapticStop = (*mEnv)->GetStaticMethodID(mEnv, mControllerManagerClass, + "hapticStop", "(I)V"); - if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun) { + if (!midPollInputDevices || !midPollHapticDevices || !midHapticRun || !midHapticStop) { __android_log_print(ANDROID_LOG_WARN, "SDL", "Missing some Java callbacks, do you have the latest version of SDLControllerManager.java?"); } @@ -503,9 +551,18 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( /* Resize */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeResize)( JNIEnv* env, jclass jcls, - jint width, jint height, jint format, jfloat rate) + jint surfaceWidth, jint surfaceHeight, + jint deviceWidth, jint deviceHeight, jint format, jfloat rate) { - Android_SetScreenResolution(width, height, format, rate); + Android_SetScreenResolution(surfaceWidth, surfaceHeight, deviceWidth, deviceHeight, format, rate); +} + +JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeOrientationChanged)( + JNIEnv *env, jclass jcls, + jint orientation) +{ + SDL_VideoDisplay *display = SDL_GetDisplay(0); + SDL_SendDisplayEvent(display, SDL_DISPLAYEVENT_ORIENTATION, orientation); } /* Paddown */ @@ -543,14 +600,15 @@ JNIEXPORT void JNICALL SDL_JAVA_CONTROLLER_INTERFACE(onNativeHat)( JNIEXPORT jint JNICALL SDL_JAVA_CONTROLLER_INTERFACE(nativeAddJoystick)( JNIEnv* env, jclass jcls, - jint device_id, jstring device_name, jstring device_desc, jint is_accelerometer, - jint nbuttons, jint naxes, jint nhats, jint nballs) + jint device_id, jstring device_name, jstring device_desc, + jint vendor_id, jint product_id, jboolean is_accelerometer, + jint button_mask, jint naxes, jint nhats, jint nballs) { int retval; const char *name = (*env)->GetStringUTFChars(env, device_name, NULL); const char *desc = (*env)->GetStringUTFChars(env, device_desc, NULL); - retval = Android_AddJoystick(device_id, name, desc, (SDL_bool) is_accelerometer, nbuttons, naxes, nhats, nballs); + retval = Android_AddJoystick(device_id, name, desc, vendor_id, product_id, is_accelerometer ? SDL_TRUE : SDL_FALSE, button_mask, naxes, nhats, nballs); (*env)->ReleaseStringUTFChars(env, device_name, name); (*env)->ReleaseStringUTFChars(env, device_desc, desc); @@ -675,9 +733,9 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeTouch)( /* Mouse */ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeMouse)( JNIEnv* env, jclass jcls, - jint button, jint action, jfloat x, jfloat y) + jint button, jint action, jfloat x, jfloat y, jboolean relative) { - Android_OnMouse(button, action, x, y); + Android_OnMouse(button, action, x, y, relative); } /* Accelerometer */ @@ -995,17 +1053,19 @@ int Android_JNI_SetupThread(void) /* * Audio support */ -static jboolean audioBuffer16Bit = JNI_FALSE; +static int audioBufferFormat = 0; static jobject audioBuffer = NULL; static void* audioBufferPinned = NULL; -static jboolean captureBuffer16Bit = JNI_FALSE; +static int captureBufferFormat = 0; static jobject captureBuffer = NULL; -int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames) +int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec) { - jboolean audioBufferStereo; - int audioBufferFrames; + int audioformat; + int numBufferFrames; jobject jbufobj = NULL; + jobject result; + int *resultElements; jboolean isCopy; JNIEnv *env = Android_JNI_GetEnv(); @@ -1015,74 +1075,123 @@ int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int } Android_JNI_SetupThread(); - audioBufferStereo = channelCount > 1; + switch (spec->format) { + case AUDIO_U8: + audioformat = ENCODING_PCM_8BIT; + break; + case AUDIO_S16: + audioformat = ENCODING_PCM_16BIT; + break; + case AUDIO_F32: + audioformat = ENCODING_PCM_FLOAT; + break; + default: + return SDL_SetError("Unsupported audio format: 0x%x", spec->format); + } if (iscapture) { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for capture"); - captureBuffer16Bit = is16Bit; - if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { - /* Error during audio initialization */ - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioRecord initialization!"); - return 0; - } + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midCaptureOpen, spec->freq, audioformat, spec->channels, spec->samples); } else { __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device for output"); - audioBuffer16Bit = is16Bit; - if ((*env)->CallStaticIntMethod(env, mAudioManagerClass, midAudioOpen, sampleRate, audioBuffer16Bit, audioBufferStereo, desiredBufferFrames) != 0) { - /* Error during audio initialization */ - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: error on AudioTrack initialization!"); - return 0; - } + result = (*env)->CallStaticObjectMethod(env, mAudioManagerClass, midAudioOpen, spec->freq, audioformat, spec->channels, spec->samples); + } + if (result == NULL) { + /* Error during audio initialization, error printed from Java */ + return SDL_SetError("Java-side initialization failed"); } + if ((*env)->GetArrayLength(env, (jintArray)result) != 4) { + return SDL_SetError("Unexpected results from Java, expected 4, got %d", (*env)->GetArrayLength(env, (jintArray)result)); + } + isCopy = JNI_FALSE; + resultElements = (*env)->GetIntArrayElements(env, (jintArray)result, &isCopy); + spec->freq = resultElements[0]; + audioformat = resultElements[1]; + switch (audioformat) { + case ENCODING_PCM_8BIT: + spec->format = AUDIO_U8; + break; + case ENCODING_PCM_16BIT: + spec->format = AUDIO_S16; + break; + case ENCODING_PCM_FLOAT: + spec->format = AUDIO_F32; + break; + default: + return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); + } + spec->channels = resultElements[2]; + spec->samples = resultElements[3]; + (*env)->ReleaseIntArrayElements(env, (jintArray)result, resultElements, JNI_ABORT); + (*env)->DeleteLocalRef(env, result); + /* Allocating the audio buffer from the Java side and passing it as the return value for audioInit no longer works on * Android >= 4.2 due to a "stale global reference" error. So now we allocate this buffer directly from this side. */ - - if (is16Bit) { - jshortArray audioBufferLocal = (*env)->NewShortArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1)); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); + switch (audioformat) { + case ENCODING_PCM_8BIT: + { + jbyteArray audioBufferLocal = (*env)->NewByteArray(env, spec->samples * spec->channels); + if (audioBufferLocal) { + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); + (*env)->DeleteLocalRef(env, audioBufferLocal); + } } - } - else { - jbyteArray audioBufferLocal = (*env)->NewByteArray(env, desiredBufferFrames * (audioBufferStereo ? 2 : 1)); - if (audioBufferLocal) { - jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); - (*env)->DeleteLocalRef(env, audioBufferLocal); + break; + case ENCODING_PCM_16BIT: + { + jshortArray audioBufferLocal = (*env)->NewShortArray(env, spec->samples * spec->channels); + if (audioBufferLocal) { + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); + (*env)->DeleteLocalRef(env, audioBufferLocal); + } } + break; + case ENCODING_PCM_FLOAT: + { + jfloatArray audioBufferLocal = (*env)->NewFloatArray(env, spec->samples * spec->channels); + if (audioBufferLocal) { + jbufobj = (*env)->NewGlobalRef(env, audioBufferLocal); + (*env)->DeleteLocalRef(env, audioBufferLocal); + } + } + break; + default: + return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); } if (jbufobj == NULL) { - __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer!"); - return 0; + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: could not allocate an audio buffer"); + return SDL_OutOfMemory(); } if (iscapture) { + captureBufferFormat = audioformat; captureBuffer = jbufobj; } else { + audioBufferFormat = audioformat; audioBuffer = jbufobj; } + numBufferFrames = (*env)->GetArrayLength(env, (jarray)jbufobj); - isCopy = JNI_FALSE; + if (!iscapture) { + isCopy = JNI_FALSE; - if (is16Bit) { - if (!iscapture) { - audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy); - } - audioBufferFrames = (*env)->GetArrayLength(env, (jshortArray)audioBuffer); - } else { - if (!iscapture) { + switch (audioformat) { + case ENCODING_PCM_8BIT: audioBufferPinned = (*env)->GetByteArrayElements(env, (jbyteArray)audioBuffer, &isCopy); + break; + case ENCODING_PCM_16BIT: + audioBufferPinned = (*env)->GetShortArrayElements(env, (jshortArray)audioBuffer, &isCopy); + break; + case ENCODING_PCM_FLOAT: + audioBufferPinned = (*env)->GetFloatArrayElements(env, (jfloatArray)audioBuffer, &isCopy); + break; + default: + return SDL_SetError("Unexpected audio format from Java: %d\n", audioformat); } - audioBufferFrames = (*env)->GetArrayLength(env, (jbyteArray)audioBuffer); - } - - if (audioBufferStereo) { - audioBufferFrames /= 2; } - - return audioBufferFrames; + return 0; } int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi) @@ -1126,12 +1235,22 @@ void Android_JNI_WriteAudioBuffer(void) { JNIEnv *mAudioEnv = Android_JNI_GetEnv(); - if (audioBuffer16Bit) { - (*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT); - (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer); - } else { + switch (audioBufferFormat) { + case ENCODING_PCM_8BIT: (*mAudioEnv)->ReleaseByteArrayElements(mAudioEnv, (jbyteArray)audioBuffer, (jbyte *)audioBufferPinned, JNI_COMMIT); (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteByteBuffer, (jbyteArray)audioBuffer); + break; + case ENCODING_PCM_16BIT: + (*mAudioEnv)->ReleaseShortArrayElements(mAudioEnv, (jshortArray)audioBuffer, (jshort *)audioBufferPinned, JNI_COMMIT); + (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteShortBuffer, (jshortArray)audioBuffer); + break; + case ENCODING_PCM_FLOAT: + (*mAudioEnv)->ReleaseFloatArrayElements(mAudioEnv, (jfloatArray)audioBuffer, (jfloat *)audioBufferPinned, JNI_COMMIT); + (*mAudioEnv)->CallStaticVoidMethod(mAudioEnv, mAudioManagerClass, midAudioWriteFloatBuffer, (jfloatArray)audioBuffer); + break; + default: + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled audio buffer format"); + break; } /* JNI_COMMIT means the changes are committed to the VM but the buffer remains pinned */ @@ -1143,44 +1262,84 @@ int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen) jboolean isCopy = JNI_FALSE; jint br; - if (captureBuffer16Bit) { - SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / 2)); + switch (captureBufferFormat) { + case ENCODING_PCM_8BIT: + SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen); + br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE); + if (br > 0) { + jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy); + SDL_memcpy(buffer, ptr, br); + (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT); + } + break; + case ENCODING_PCM_16BIT: + SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == (buflen / sizeof(Sint16))); br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_TRUE); if (br > 0) { jshort *ptr = (*env)->GetShortArrayElements(env, (jshortArray)captureBuffer, &isCopy); - br *= 2; + br *= sizeof(Sint16); SDL_memcpy(buffer, ptr, br); (*env)->ReleaseShortArrayElements(env, (jshortArray)captureBuffer, (jshort *)ptr, JNI_ABORT); } - } else { - SDL_assert((*env)->GetArrayLength(env, (jshortArray)captureBuffer) == buflen); - br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_TRUE); + break; + case ENCODING_PCM_FLOAT: + SDL_assert((*env)->GetArrayLength(env, (jfloatArray)captureBuffer) == (buflen / sizeof(float))); + br = (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_TRUE); if (br > 0) { - jbyte *ptr = (*env)->GetByteArrayElements(env, (jbyteArray)captureBuffer, &isCopy); + jfloat *ptr = (*env)->GetFloatArrayElements(env, (jfloatArray)captureBuffer, &isCopy); + br *= sizeof(float); SDL_memcpy(buffer, ptr, br); - (*env)->ReleaseByteArrayElements(env, (jbyteArray)captureBuffer, (jbyte *)ptr, JNI_ABORT); + (*env)->ReleaseFloatArrayElements(env, (jfloatArray)captureBuffer, (jfloat *)ptr, JNI_ABORT); } + break; + default: + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: unhandled capture buffer format"); + break; } - - return (int) br; + return br; } void Android_JNI_FlushCapturedAudio(void) { JNIEnv *env = Android_JNI_GetEnv(); #if 0 /* !!! FIXME: this needs API 23, or it'll do blocking reads and never end. */ - if (captureBuffer16Bit) { - const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer); - while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } - } else { - const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer); - while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + switch (captureBufferFormat) { + case ENCODING_PCM_8BIT: + { + const jint len = (*env)->GetArrayLength(env, (jbyteArray)captureBuffer); + while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + } + break; + case ENCODING_PCM_16BIT: + { + const jint len = (*env)->GetArrayLength(env, (jshortArray)captureBuffer); + while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + } + break; + case ENCODING_PCM_FLOAT: + { + const jint len = (*env)->GetArrayLength(env, (jfloatArray)captureBuffer); + while ((*env)->CallStaticIntMethod(env, mActivityClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE) == len) { /* spin */ } + } + break; + default: + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format"); + break; } #else - if (captureBuffer16Bit) { - (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE); - } else { + switch (captureBufferFormat) { + case ENCODING_PCM_8BIT: (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadByteBuffer, (jbyteArray)captureBuffer, JNI_FALSE); + break; + case ENCODING_PCM_16BIT: + (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadShortBuffer, (jshortArray)captureBuffer, JNI_FALSE); + break; + case ENCODING_PCM_FLOAT: + (*env)->CallStaticIntMethod(env, mAudioManagerClass, midCaptureReadFloatBuffer, (jfloatArray)captureBuffer, JNI_FALSE); + break; + default: + __android_log_print(ANDROID_LOG_WARN, "SDL", "SDL audio: flushing unhandled capture buffer format"); + break; } #endif } @@ -1846,12 +2005,17 @@ void Android_JNI_PollHapticDevices(void) (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midPollHapticDevices); } -void Android_JNI_HapticRun(int device_id, int length) +void Android_JNI_HapticRun(int device_id, float intensity, int length) { JNIEnv *env = Android_JNI_GetEnv(); - (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, length); + (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticRun, device_id, intensity, length); } +void Android_JNI_HapticStop(int device_id) +{ + JNIEnv *env = Android_JNI_GetEnv(); + (*env)->CallStaticVoidMethod(env, mControllerManagerClass, midHapticStop, device_id); +} /* See SDLActivity.java for constants. */ #define COMMAND_SET_KEEP_SCREEN_ON 5 @@ -2006,12 +2170,36 @@ void *SDL_AndroidGetActivity(void) return (*env)->CallStaticObjectMethod(env, mActivityClass, midGetContext); } +SDL_bool SDL_IsAndroidTablet(void) +{ + JNIEnv *env = Android_JNI_GetEnv(); + return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsTablet); +} + SDL_bool SDL_IsAndroidTV(void) { JNIEnv *env = Android_JNI_GetEnv(); return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsAndroidTV); } +SDL_bool SDL_IsChromebook(void) +{ + JNIEnv *env = Android_JNI_GetEnv(); + return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsChromebook); +} + +SDL_bool SDL_IsDeXMode(void) +{ + JNIEnv *env = Android_JNI_GetEnv(); + return (*env)->CallStaticBooleanMethod(env, mActivityClass, midIsDeXMode); +} + +void SDL_AndroidBackButton(void) +{ + JNIEnv *env = Android_JNI_GetEnv(); + return (*env)->CallStaticVoidMethod(env, mActivityClass, midManualBackButton); +} + const char * SDL_AndroidGetInternalStoragePath(void) { static char *s_AndroidInternalFilesPath = NULL; @@ -2166,6 +2354,48 @@ void Android_JNI_GetManifestEnvironmentVariables(void) } } +int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + int custom_cursor = 0; + jintArray pixels; + pixels = (*mEnv)->NewIntArray(mEnv, surface->w * surface->h); + if (pixels) { + (*mEnv)->SetIntArrayRegion(mEnv, pixels, 0, surface->w * surface->h, (int *)surface->pixels); + custom_cursor = (*mEnv)->CallStaticIntMethod(mEnv, mActivityClass, midCreateCustomCursor, pixels, surface->w, surface->h, hot_x, hot_y); + (*mEnv)->DeleteLocalRef(mEnv, pixels); + } else { + SDL_OutOfMemory(); + } + return custom_cursor; +} + + +SDL_bool Android_JNI_SetCustomCursor(int cursorID) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetCustomCursor, cursorID); +} + +SDL_bool Android_JNI_SetSystemCursor(int cursorID) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetSystemCursor, cursorID); +} + +SDL_bool Android_JNI_SupportsRelativeMouse() +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSupportsRelativeMouse); +} + +SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled) +{ + JNIEnv *mEnv = Android_JNI_GetEnv(); + return (*mEnv)->CallStaticBooleanMethod(mEnv, mActivityClass, midSetRelativeMouseEnabled, (enabled == 1)); +} + + #endif /* __ANDROID__ */ /* vi: set ts=4 sw=4 expandtab: */ diff --git a/Source/3rdParty/SDL2/src/core/android/SDL_android.h b/Source/3rdParty/SDL2/src/core/android/SDL_android.h index c800dc6..b2ff32e 100644 --- a/Source/3rdParty/SDL2/src/core/android/SDL_android.h +++ b/Source/3rdParty/SDL2/src/core/android/SDL_android.h @@ -19,6 +19,7 @@ 3. This notice may not be removed or altered from any source distribution. */ #include "../../SDL_internal.h" +#include "SDL_system.h" /* Set up for C function definitions, even when using C++ */ #ifdef __cplusplus @@ -30,6 +31,7 @@ extern "C" { #include <EGL/eglplatform.h> #include <android/native_window_jni.h> +#include "SDL_audio.h" #include "SDL_rect.h" /* Interface from the SDL library into the Android Java activity */ @@ -46,13 +48,17 @@ extern ANativeWindow* Android_JNI_GetNativeWindow(void); extern int Android_JNI_GetDisplayDPI(float *ddpi, float *xdpi, float *ydpi); /* Audio support */ -extern int Android_JNI_OpenAudioDevice(int iscapture, int sampleRate, int is16Bit, int channelCount, int desiredBufferFrames); +extern int Android_JNI_OpenAudioDevice(int iscapture, SDL_AudioSpec *spec); extern void* Android_JNI_GetAudioBuffer(void); extern void Android_JNI_WriteAudioBuffer(void); extern int Android_JNI_CaptureAudioBuffer(void *buffer, int buflen); extern void Android_JNI_FlushCapturedAudio(void); extern void Android_JNI_CloseAudioDevice(const int iscapture); +/* Detecting device type */ +extern SDL_bool Android_IsDeXMode(); +extern SDL_bool Android_IsChromebook(); + #include "SDL_rwops.h" int Android_JNI_FileOpen(SDL_RWops* ctx, const char* fileName, const char* mode); @@ -78,14 +84,16 @@ void Android_JNI_PollInputDevices(void); /* Haptic support */ void Android_JNI_PollHapticDevices(void); -void Android_JNI_HapticRun(int device_id, int length); +void Android_JNI_HapticRun(int device_id, float intensity, int length); +void Android_JNI_HapticStop(int device_id); /* Video */ void Android_JNI_SuspendScreenSaver(SDL_bool suspend); /* Touch support */ -int Android_JNI_GetTouchDeviceIds(int **ids); +int Android_JNI_InitTouch(void); void Android_JNI_SetSeparateMouseAndTouch(SDL_bool new_value); +int Android_JNI_GetTouchDeviceIds(int **ids); /* Threads */ #include <jni.h> @@ -102,6 +110,21 @@ JNIEXPORT void JNICALL SDL_Android_Init(JNIEnv* mEnv, jclass cls); #include "SDL_messagebox.h" int Android_JNI_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid); +/* Cursor support */ +int Android_JNI_CreateCustomCursor(SDL_Surface *surface, int hot_x, int hot_y); +SDL_bool Android_JNI_SetCustomCursor(int cursorID); +SDL_bool Android_JNI_SetSystemCursor(int cursorID); + +/* Relative mouse support */ +SDL_bool Android_JNI_SupportsRelativeMouse(void); +SDL_bool Android_JNI_SetRelativeMouseEnabled(SDL_bool enabled); + + +SDL_bool SDL_IsAndroidTablet(void); +SDL_bool SDL_IsAndroidTV(void); +SDL_bool SDL_IsChromebook(void); +SDL_bool SDL_IsDeXMode(void); + /* Ends C function definitions when using C++ */ #ifdef __cplusplus /* *INDENT-OFF* */ |