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" /> +