diff --git a/app/src/main/java/emu/skyline/EmulationActivity.kt b/app/src/main/java/emu/skyline/EmulationActivity.kt
index 0515a01d..2bb3e707 100644
--- a/app/src/main/java/emu/skyline/EmulationActivity.kt
+++ b/app/src/main/java/emu/skyline/EmulationActivity.kt
@@ -265,6 +265,7 @@ class EmulationActivity : AppCompatActivity(), SurfaceHolder.Callback, View.OnTo
isGone = controllerType == ControllerType.None || !preferenceSettings.onScreenControl
setOnButtonStateChangedListener(::onButtonStateChanged)
setOnStickStateChangedListener(::onStickStateChanged)
+ hapticFeedback = preferenceSettings.onScreenControl && preferenceSettings.onScreenControlFeedback
recenterSticks = preferenceSettings.onScreenControlRecenterSticks
}
diff --git a/app/src/main/java/emu/skyline/input/ControllerActivity.kt b/app/src/main/java/emu/skyline/input/ControllerActivity.kt
index 4d224ad6..7169c171 100644
--- a/app/src/main/java/emu/skyline/input/ControllerActivity.kt
+++ b/app/src/main/java/emu/skyline/input/ControllerActivity.kt
@@ -91,6 +91,11 @@ class ControllerActivity : AppCompatActivity() {
adapter.notifyItemChanged(position)
})
+ items.add(ControllerCheckBoxViewItem(getString(R.string.osc_feedback), "", preferenceSettings.onScreenControlFeedback) { item, position ->
+ preferenceSettings.onScreenControlFeedback = item.checked
+ adapter.notifyItemChanged(position)
+ })
+
items.add(ControllerCheckBoxViewItem(getString(R.string.osc_recenter_sticks), "", preferenceSettings.onScreenControlRecenterSticks) { item, position ->
preferenceSettings.onScreenControlRecenterSticks = item.checked
adapter.notifyItemChanged(position)
diff --git a/app/src/main/java/emu/skyline/input/onscreen/OnScreenButton.kt b/app/src/main/java/emu/skyline/input/onscreen/OnScreenButton.kt
index 4b1fc631..7bd43cfb 100644
--- a/app/src/main/java/emu/skyline/input/onscreen/OnScreenButton.kt
+++ b/app/src/main/java/emu/skyline/input/onscreen/OnScreenButton.kt
@@ -74,6 +74,8 @@ abstract class OnScreenButton(
var isPressed = false
+ var hapticFeedback = false
+
var isEditing = false
private set
diff --git a/app/src/main/java/emu/skyline/input/onscreen/OnScreenControllerView.kt b/app/src/main/java/emu/skyline/input/onscreen/OnScreenControllerView.kt
index 54a86e25..0d83ac10 100644
--- a/app/src/main/java/emu/skyline/input/onscreen/OnScreenControllerView.kt
+++ b/app/src/main/java/emu/skyline/input/onscreen/OnScreenControllerView.kt
@@ -9,8 +9,14 @@ import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
+import android.content.Context.VIBRATOR_MANAGER_SERVICE
+import android.content.Context.VIBRATOR_SERVICE
import android.graphics.Canvas
import android.graphics.PointF
+import android.os.Build
+import android.os.VibrationEffect
+import android.os.Vibrator
+import android.os.VibratorManager
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
@@ -55,6 +61,11 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
field = value
controls.joysticks.forEach { it.recenterSticks = recenterSticks }
}
+ var hapticFeedback = false
+ set(value) {
+ field = value
+ (controls.circularButtons + controls.rectangularButtons + controls.triggerButtons).forEach { it.hapticFeedback = hapticFeedback }
+ }
override fun onDraw(canvas : Canvas) {
super.onDraw(canvas)
@@ -73,6 +84,16 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
}
}
+ private val vibrationEffect = VibrationEffect.createOneShot(20, VibrationEffect.DEFAULT_AMPLITUDE)
+ private val vibrate = {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ (context.getSystemService(VIBRATOR_MANAGER_SERVICE) as VibratorManager).defaultVibrator.vibrate(vibrationEffect)
+ } else {
+ @Suppress("DEPRECATION")
+ (context.getSystemService(VIBRATOR_SERVICE) as Vibrator).vibrate(vibrationEffect)
+ }
+ }
+
private val playingTouchHandler = OnTouchListener { _, event ->
var handled = false
val actionIndex = event.actionIndex
@@ -102,6 +123,7 @@ class OnScreenControllerView @JvmOverloads constructor(context : Context, attrs
if (button.config.enabled && button.isTouched(x, y)) {
button.touchPointerId = pointerId
button.onFingerDown(x, y)
+ if (hapticFeedback) vibrate()
performClick()
onButtonStateChangedListener?.invoke(button.buttonId, ButtonState.Pressed)
handled = true
diff --git a/app/src/main/java/emu/skyline/utils/PreferenceSettings.kt b/app/src/main/java/emu/skyline/utils/PreferenceSettings.kt
index 00555579..611a635f 100644
--- a/app/src/main/java/emu/skyline/utils/PreferenceSettings.kt
+++ b/app/src/main/java/emu/skyline/utils/PreferenceSettings.kt
@@ -51,6 +51,7 @@ class PreferenceSettings @Inject constructor(@ApplicationContext private val con
// Input
var onScreenControl by sharedPreferences(context, true)
+ var onScreenControlFeedback by sharedPreferences(context, true)
var onScreenControlRecenterSticks by sharedPreferences(context, true)
// Other
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e1bc619f..913f167c 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -110,6 +110,7 @@
Enable On-Screen Controls
On-Screen Controls won\'t be shown
On-Screen Controls will be shown
+ Enable Haptic Feedback
Edit On-Screen Controls layout
Setup Guide
Sequentially map every stick and button