diff --git a/app/src/main/java/com/limelight/binding/input/ControllerHandler.java b/app/src/main/java/com/limelight/binding/input/ControllerHandler.java
index 7ea824bf..afe989f3 100644
--- a/app/src/main/java/com/limelight/binding/input/ControllerHandler.java
+++ b/app/src/main/java/com/limelight/binding/input/ControllerHandler.java
@@ -2121,7 +2121,16 @@ public class ControllerHandler implements InputManager.InputDeviceListener, UsbD
else if (foundMatchingDevice && !vibrated && prefConfig.vibrateFallbackToDevice) {
// We found a device to vibrate but it didn't have rumble support. The user
// has requested us to vibrate the device in this case.
- rumbleSingleVibrator(deviceVibrator, lowFreqMotor, highFreqMotor);
+
+ // We cast the unsigned short value to a signed int before multiplying by
+ // the preferred strength. The resulting value is capped at 65534 before
+ // we cast it back to a short so it doesn't go above 100%.
+ short lowFreqMotorAdjusted = (short)(Math.min((((lowFreqMotor & 0xffff)
+ * prefConfig.vibrateFallbackToDeviceStrength) / 100), Short.MAX_VALUE*2));
+ short highFreqMotorAdjusted = (short)(Math.min((((highFreqMotor & 0xffff)
+ * prefConfig.vibrateFallbackToDeviceStrength) / 100), Short.MAX_VALUE*2));
+
+ rumbleSingleVibrator(deviceVibrator, lowFreqMotorAdjusted, highFreqMotorAdjusted);
}
}
}
diff --git a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java
index f5bbf709..e0ba76e5 100644
--- a/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java
+++ b/app/src/main/java/com/limelight/preferences/PreferenceConfiguration.java
@@ -55,6 +55,7 @@ public class PreferenceConfiguration {
static final String UNLOCK_FPS_STRING = "checkbox_unlock_fps";
private static final String VIBRATE_OSC_PREF_STRING = "checkbox_vibrate_osc";
private static final String VIBRATE_FALLBACK_PREF_STRING = "checkbox_vibrate_fallback";
+ private static final String VIBRATE_FALLBACK_STRENGTH_PREF_STRING = "seekbar_vibrate_fallback_strength";
private static final String FLIP_FACE_BUTTONS_PREF_STRING = "checkbox_flip_face_buttons";
private static final String TOUCHSCREEN_TRACKPAD_PREF_STRING = "checkbox_touchscreen_trackpad";
private static final String LATENCY_TOAST_PREF_STRING = "checkbox_enable_post_stream_toast";
@@ -92,6 +93,7 @@ public class PreferenceConfiguration {
private static final boolean DEFAULT_UNLOCK_FPS = false;
private static final boolean DEFAULT_VIBRATE_OSC = true;
private static final boolean DEFAULT_VIBRATE_FALLBACK = false;
+ private static final int DEFAULT_VIBRATE_FALLBACK_STRENGTH = 100;
private static final boolean DEFAULT_FLIP_FACE_BUTTONS = false;
private static final boolean DEFAULT_TOUCHSCREEN_TRACKPAD = true;
private static final String DEFAULT_AUDIO_CONFIG = "2"; // Stereo
@@ -139,6 +141,7 @@ public class PreferenceConfiguration {
public boolean unlockFps;
public boolean vibrateOsc;
public boolean vibrateFallbackToDevice;
+ public int vibrateFallbackToDeviceStrength;
public boolean touchscreenTrackpad;
public MoonBridge.AudioConfiguration audioConfiguration;
public int framePacing;
@@ -583,6 +586,7 @@ public class PreferenceConfiguration {
config.unlockFps = prefs.getBoolean(UNLOCK_FPS_STRING, DEFAULT_UNLOCK_FPS);
config.vibrateOsc = prefs.getBoolean(VIBRATE_OSC_PREF_STRING, DEFAULT_VIBRATE_OSC);
config.vibrateFallbackToDevice = prefs.getBoolean(VIBRATE_FALLBACK_PREF_STRING, DEFAULT_VIBRATE_FALLBACK);
+ config.vibrateFallbackToDeviceStrength = prefs.getInt(VIBRATE_FALLBACK_STRENGTH_PREF_STRING, DEFAULT_VIBRATE_FALLBACK_STRENGTH);
config.flipFaceButtons = prefs.getBoolean(FLIP_FACE_BUTTONS_PREF_STRING, DEFAULT_FLIP_FACE_BUTTONS);
config.touchscreenTrackpad = prefs.getBoolean(TOUCHSCREEN_TRACKPAD_PREF_STRING, DEFAULT_TOUCHSCREEN_TRACKPAD);
config.enableLatencyToast = prefs.getBoolean(LATENCY_TOAST_PREF_STRING, DEFAULT_LATENCY_TOAST);
diff --git a/app/src/main/java/com/limelight/preferences/StreamSettings.java b/app/src/main/java/com/limelight/preferences/StreamSettings.java
index 15622041..f5bd2032 100644
--- a/app/src/main/java/com/limelight/preferences/StreamSettings.java
+++ b/app/src/main/java/com/limelight/preferences/StreamSettings.java
@@ -333,19 +333,23 @@ public class StreamSettings extends Activity {
(PreferenceCategory) findPreference("category_help");
screen.removePreference(category);
}*/
-
+ PreferenceCategory category_gamepad_settings =
+ (PreferenceCategory) findPreference("category_gamepad_settings");
// Remove the vibration options if the device can't vibrate
if (!((Vibrator)getActivity().getSystemService(Context.VIBRATOR_SERVICE)).hasVibrator()) {
- PreferenceCategory category =
- (PreferenceCategory) findPreference("category_gamepad_settings");
- category.removePreference(findPreference("checkbox_vibrate_fallback"));
-
+ category_gamepad_settings.removePreference(findPreference("checkbox_vibrate_fallback"));
+ category_gamepad_settings.removePreference(findPreference("seekbar_vibrate_fallback_strength"));
// The entire OSC category may have already been removed by the touchscreen check above
- category = (PreferenceCategory) findPreference("category_onscreen_controls");
+ PreferenceCategory category = (PreferenceCategory) findPreference("category_onscreen_controls");
if (category != null) {
category.removePreference(findPreference("checkbox_vibrate_osc"));
}
}
+ else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O ||
+ !((Vibrator)getActivity().getSystemService(Context.VIBRATOR_SERVICE)).hasAmplitudeControl() ) {
+ // Remove the vibration strength selector of the device doesn't have amplitude control
+ category_gamepad_settings.removePreference(findPreference("seekbar_vibrate_fallback_strength"));
+ }
Display display = getActivity().getWindowManager().getDefaultDisplay();
float maxSupportedFps = display.getRefreshRate();
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 527ea7df..107d6f4f 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -173,6 +173,9 @@
Unchecking this option forces a gamepad to always be present
Emulate rumble support with vibration
Vibrates your device to emulate rumble if your gamepad does not support it
+ Adjust emulated rumble strength
+ Can amplify or reduce the vibration strength on your device
+ %
Adjust analog stick deadzone
Note: Some games can enforce a larger deadzone than what Moonlight is configured to use.
%
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index ff349567..d68c8c57 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -98,6 +98,14 @@
android:title="@string/title_checkbox_vibrate_fallback"
android:summary="@string/summary_checkbox_vibrate_fallback"
android:defaultValue="false" />
+