Navigation Menu

Skip to content

Commit

Permalink
Support vibration magnitude on Android 8.0 (thanks Rachel!)
Browse files Browse the repository at this point in the history
  • Loading branch information
slouken committed Oct 16, 2018
1 parent 7be4fca commit b0c48dd
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 9 deletions.
@@ -1,5 +1,6 @@
package org.libsdl.app;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
Expand Down Expand Up @@ -77,8 +78,8 @@ public static void pollHapticDevices() {
/**
* This method is called by SDL using JNI.
*/
public static void hapticRun(int device_id, int length) {
mHapticHandler.run(device_id, length);
public static void hapticRun(int device_id, float intensity, int length) {
mHapticHandler.run(device_id, intensity, length);
}

/**
Expand Down Expand Up @@ -423,10 +424,50 @@ public SDLHapticHandler() {
mHaptics = new ArrayList<SDLHaptic>();
}

public void run(int device_id, int length) {
public void run(int device_id, float intensity, int length) {
SDLHaptic haptic = getHaptic(device_id);
if (haptic != null) {
haptic.vib.vibrate (length);

Log.d("SDL", "Rtest: Vibe with intensity " + intensity + " for " + length);
if (intensity == 0.0f) {
stop(device_id);
return;
}

if (Build.VERSION.SDK_INT >= 26) {
// We have to do this dynamically to avoid issues on earlier SDKs.
// But we want to use the VibrationEffect so we can set amplitude.

try {
int vibeValue = Math.round(intensity * 255);

if (vibeValue > 255) {
vibeValue = 255;
}
if (vibeValue < 1) {
stop(device_id);
return;
}

long longLength = length;
Class vibrationEffectClass = Class.forName("android.os.VibrationEffect");
Method oneShotMethod = vibrationEffectClass.getMethod("createOneShot", long.class, int.class);
Object effect = oneShotMethod.invoke(null, longLength, vibeValue);
Method vibeEffect = android.os.Vibrator.class.getMethod("vibrate", vibrationEffectClass);
vibeEffect.invoke(haptic.vib, vibrationEffectClass.cast(effect));
}
catch (Exception e) {
// Fall back to the generic method, which uses DEFAULT_AMPLITUDE, but works even if
// something went horribly wrong with the Android 8.0 APIs.
haptic.vib.vibrate(length);
}
}
else {
// Fall back to the generic method, which uses DEFAULT_AMPLITUDE, but exists
// on earlier SDKs.

haptic.vib.vibrate (length);
}
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/core/android/SDL_android.c
Expand Up @@ -445,7 +445,7 @@ 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");

Expand Down Expand Up @@ -2005,10 +2005,10 @@ 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)
Expand Down
2 changes: 1 addition & 1 deletion src/core/android/SDL_android.h
Expand Up @@ -84,7 +84,7 @@ 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 */
Expand Down
7 changes: 6 additions & 1 deletion src/haptic/android/SDL_syshaptic.c
Expand Up @@ -235,7 +235,12 @@ int
SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
Uint32 iterations)
{
Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, effect->effect.leftright.length);
float large = effect->effect.leftright.large_magnitude / 32767.0f;
float small = effect->effect.leftright.small_magnitude / 32767.0f;

float total = (large * 0.6f) + (small * 0.4f);

Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, total, effect->effect.leftright.length);
return 0;
}

Expand Down

0 comments on commit b0c48dd

Please sign in to comment.