From a7e0a0d5b10e1a2cd1ba46d7b3014d7b9997fea0 Mon Sep 17 00:00:00 2001 From: PabloG02 Date: Thu, 1 Jun 2023 17:49:20 +0200 Subject: [PATCH] Save the position of buttons as a percentage --- .../org/yuzu/yuzu_emu/overlay/InputOverlay.kt | 216 +++++++++++------- 1 file changed, 136 insertions(+), 80 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt index f0b0af9e5..bb20e5207 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt @@ -9,6 +9,7 @@ import android.content.SharedPreferences import android.content.res.Configuration import android.graphics.Bitmap import android.graphics.Canvas +import android.graphics.Point import android.graphics.Rect import android.graphics.drawable.Drawable import android.graphics.drawable.VectorDrawable @@ -343,10 +344,12 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context } private fun addOverlayControls(orientation: String) { + val windowSize = getSafeScreenSize(context) if (preferences.getBoolean(Settings.PREF_BUTTON_TOGGLE_0, true)) { overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.facebutton_a, R.drawable.facebutton_a_depressed, ButtonType.BUTTON_A, @@ -358,6 +361,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.facebutton_b, R.drawable.facebutton_b_depressed, ButtonType.BUTTON_B, @@ -369,6 +373,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.facebutton_x, R.drawable.facebutton_x_depressed, ButtonType.BUTTON_X, @@ -380,6 +385,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.facebutton_y, R.drawable.facebutton_y_depressed, ButtonType.BUTTON_Y, @@ -391,6 +397,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.l_shoulder, R.drawable.l_shoulder_depressed, ButtonType.TRIGGER_L, @@ -402,6 +409,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.r_shoulder, R.drawable.r_shoulder_depressed, ButtonType.TRIGGER_R, @@ -413,6 +421,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.zl_trigger, R.drawable.zl_trigger_depressed, ButtonType.TRIGGER_ZL, @@ -424,6 +433,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.zr_trigger, R.drawable.zr_trigger_depressed, ButtonType.TRIGGER_ZR, @@ -435,6 +445,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.facebutton_plus, R.drawable.facebutton_plus_depressed, ButtonType.BUTTON_PLUS, @@ -446,6 +457,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.facebutton_minus, R.drawable.facebutton_minus_depressed, ButtonType.BUTTON_MINUS, @@ -457,6 +469,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayDpads.add( initializeOverlayDpad( context, + windowSize, R.drawable.dpad_standard, R.drawable.dpad_standard_cardinal_depressed, R.drawable.dpad_standard_diagonal_depressed, @@ -468,6 +481,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayJoysticks.add( initializeOverlayJoystick( context, + windowSize, R.drawable.joystick_range, R.drawable.joystick, R.drawable.joystick_depressed, @@ -481,6 +495,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayJoysticks.add( initializeOverlayJoystick( context, + windowSize, R.drawable.joystick_range, R.drawable.joystick, R.drawable.joystick_depressed, @@ -494,6 +509,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.facebutton_home, R.drawable.facebutton_home_depressed, ButtonType.BUTTON_HOME, @@ -505,6 +521,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context overlayButtons.add( initializeOverlayButton( context, + windowSize, R.drawable.facebutton_screenshot, R.drawable.facebutton_screenshot_depressed, ButtonType.BUTTON_CAPTURE, @@ -530,9 +547,12 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context } private fun saveControlPosition(sharedPrefsId: Int, x: Int, y: Int, orientation: String) { + val windowSize = getSafeScreenSize(context) + val min = windowSize.first + val max = windowSize.second PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext).edit() - .putFloat("$sharedPrefsId$orientation-X", x.toFloat()) - .putFloat("$sharedPrefsId$orientation-Y", y.toFloat()) + .putFloat("$sharedPrefsId$orientation-X", (x - min.x).toFloat() / max.x) + .putFloat("$sharedPrefsId$orientation-Y", (y - min.y).toFloat() / max.y) .apply() } @@ -557,170 +577,129 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context } private fun defaultOverlayLandscape() { - // Get screen size - val windowMetrics = - WindowMetricsCalculator.getOrCreate().computeCurrentWindowMetrics(context as Activity) - var maxY = windowMetrics.bounds.height().toFloat() - var maxX = windowMetrics.bounds.width().toFloat() - var minY = 0 - var minX = 0 - - // If we have API access, calculate the safe area to draw the overlay - var cutoutLeft = 0 - var cutoutBottom = 0 - val insets = windowInsets.displayCutout - if (insets != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - maxY = - if (insets.boundingRectTop.bottom != 0) insets.boundingRectTop.bottom.toFloat() else maxY - maxX = - if (insets.boundingRectRight.left != 0) insets.boundingRectRight.left.toFloat() else maxX - minX = insets.boundingRectLeft.right - insets.boundingRectLeft.left - minY = insets.boundingRectBottom.top - insets.boundingRectBottom.bottom - - cutoutLeft = insets.boundingRectRight.right - insets.boundingRectRight.left - cutoutBottom = insets.boundingRectTop.top - insets.boundingRectTop.bottom - } - - // This makes sure that if we have an inset on one side of the screen, we mirror it on - // the other side. Since removing space from one of the max values messes with the scale, - // we also have to account for it using our min values. - if (maxX.toInt() != windowMetrics.bounds.width()) minX += cutoutLeft - if (maxY.toInt() != windowMetrics.bounds.height()) minY += cutoutBottom - if (minX > 0 && maxX.toInt() == windowMetrics.bounds.width()) { - maxX -= (minX * 2) - } else if (minX > 0) { - maxX -= minX - } - if (minY > 0 && maxY.toInt() == windowMetrics.bounds.height()) { - maxY -= (minY * 2) - } else if (minY > 0) { - maxY -= minY - } - - // Each value is a percent from max X/Y stored as an int. Have to bring that value down - // to a decimal before multiplying by MAX X/Y. + // Each value represents the position of the button in relation to the screen size without insets. preferences.edit() .putFloat( ButtonType.BUTTON_A.toString() + "-X", - resources.getInteger(R.integer.SWITCH_BUTTON_A_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_BUTTON_A_X).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_A.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_BUTTON_A_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_BUTTON_A_Y).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_B.toString() + "-X", - resources.getInteger(R.integer.SWITCH_BUTTON_B_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_BUTTON_B_X).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_B.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_BUTTON_B_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_BUTTON_B_Y).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_X.toString() + "-X", - resources.getInteger(R.integer.SWITCH_BUTTON_X_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_BUTTON_X_X).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_X.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_BUTTON_X_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_BUTTON_X_Y).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_Y.toString() + "-X", - resources.getInteger(R.integer.SWITCH_BUTTON_Y_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_BUTTON_Y_X).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_Y.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_BUTTON_Y_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_BUTTON_Y_Y).toFloat() / 1000 ) .putFloat( ButtonType.TRIGGER_ZL.toString() + "-X", - resources.getInteger(R.integer.SWITCH_TRIGGER_ZL_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_TRIGGER_ZL_X).toFloat() / 1000 ) .putFloat( ButtonType.TRIGGER_ZL.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_TRIGGER_ZL_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_TRIGGER_ZL_Y).toFloat() / 1000 ) .putFloat( ButtonType.TRIGGER_ZR.toString() + "-X", - resources.getInteger(R.integer.SWITCH_TRIGGER_ZR_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_TRIGGER_ZR_X).toFloat() / 1000 ) .putFloat( ButtonType.TRIGGER_ZR.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_TRIGGER_ZR_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_TRIGGER_ZR_Y).toFloat() / 1000 ) .putFloat( ButtonType.DPAD_UP.toString() + "-X", - resources.getInteger(R.integer.SWITCH_BUTTON_DPAD_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_BUTTON_DPAD_X).toFloat() / 1000 ) .putFloat( ButtonType.DPAD_UP.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_BUTTON_DPAD_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_BUTTON_DPAD_Y).toFloat() / 1000 ) .putFloat( ButtonType.TRIGGER_L.toString() + "-X", - resources.getInteger(R.integer.SWITCH_TRIGGER_L_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_TRIGGER_L_X).toFloat() / 1000 ) .putFloat( ButtonType.TRIGGER_L.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_TRIGGER_L_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_TRIGGER_L_Y).toFloat() / 1000 ) .putFloat( ButtonType.TRIGGER_R.toString() + "-X", - resources.getInteger(R.integer.SWITCH_TRIGGER_R_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_TRIGGER_R_X).toFloat() / 1000 ) .putFloat( ButtonType.TRIGGER_R.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_TRIGGER_R_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_TRIGGER_R_Y).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_PLUS.toString() + "-X", - resources.getInteger(R.integer.SWITCH_BUTTON_PLUS_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_BUTTON_PLUS_X).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_PLUS.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_BUTTON_PLUS_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_BUTTON_PLUS_Y).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_MINUS.toString() + "-X", - resources.getInteger(R.integer.SWITCH_BUTTON_MINUS_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_BUTTON_MINUS_X).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_MINUS.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_BUTTON_MINUS_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_BUTTON_MINUS_Y).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_HOME.toString() + "-X", - resources.getInteger(R.integer.SWITCH_BUTTON_HOME_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_BUTTON_HOME_X).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_HOME.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_BUTTON_HOME_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_BUTTON_HOME_Y).toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_CAPTURE.toString() + "-X", resources.getInteger(R.integer.SWITCH_BUTTON_CAPTURE_X) - .toFloat() / 1000 * maxX + minX + .toFloat() / 1000 ) .putFloat( ButtonType.BUTTON_CAPTURE.toString() + "-Y", resources.getInteger(R.integer.SWITCH_BUTTON_CAPTURE_Y) - .toFloat() / 1000 * maxY + minY + .toFloat() / 1000 ) .putFloat( ButtonType.STICK_R.toString() + "-X", - resources.getInteger(R.integer.SWITCH_STICK_R_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_STICK_R_X).toFloat() / 1000 ) .putFloat( ButtonType.STICK_R.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_STICK_R_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_STICK_R_Y).toFloat() / 1000 ) .putFloat( ButtonType.STICK_L.toString() + "-X", - resources.getInteger(R.integer.SWITCH_STICK_L_X).toFloat() / 1000 * maxX + minX + resources.getInteger(R.integer.SWITCH_STICK_L_X).toFloat() / 1000 ) .putFloat( ButtonType.STICK_L.toString() + "-Y", - resources.getInteger(R.integer.SWITCH_STICK_L_Y).toFloat() / 1000 * maxY + minY + resources.getInteger(R.integer.SWITCH_STICK_L_Y).toFloat() / 1000 ) .apply() } @@ -766,6 +745,59 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context return scaledBitmap } + /** + * Gets the safe screen size for drawing the overlay + * + * @param context Context for getting the window metrics + * @return A pair of points, the first being the top left corner of the safe area, + * the second being the bottom right corner of the safe area + */ + private fun getSafeScreenSize(context: Context): Pair { + // Get screen size + val windowMetrics = + WindowMetricsCalculator.getOrCreate() + .computeCurrentWindowMetrics(context as Activity) + var maxY = windowMetrics.bounds.height().toFloat() + var maxX = windowMetrics.bounds.width().toFloat() + var minY = 0 + var minX = 0 + + // If we have API access, calculate the safe area to draw the overlay + var cutoutLeft = 0 + var cutoutBottom = 0 + val insets = context.windowManager.currentWindowMetrics.windowInsets.displayCutout + if (insets != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + maxY = + if (insets.boundingRectTop.bottom != 0) insets.boundingRectTop.bottom.toFloat() else maxY + maxX = + if (insets.boundingRectRight.left != 0) insets.boundingRectRight.left.toFloat() else maxX + minX = insets.boundingRectLeft.right - insets.boundingRectLeft.left + minY = insets.boundingRectBottom.top - insets.boundingRectBottom.bottom + + cutoutLeft = insets.boundingRectRight.right - insets.boundingRectRight.left + cutoutBottom = insets.boundingRectTop.top - insets.boundingRectTop.bottom + } + + + // This makes sure that if we have an inset on one side of the screen, we mirror it on + // the other side. Since removing space from one of the max values messes with the scale, + // we also have to account for it using our min values. + if (maxX.toInt() != windowMetrics.bounds.width()) minX += cutoutLeft + if (maxY.toInt() != windowMetrics.bounds.height()) minY += cutoutBottom + if (minX > 0 && maxX.toInt() == windowMetrics.bounds.width()) { + maxX -= (minX * 2) + } else if (minX > 0) { + maxX -= minX + } + if (minY > 0 && maxY.toInt() == windowMetrics.bounds.height()) { + maxY -= (minY * 2) + } else if (minY > 0) { + maxY -= minY + } + + return Pair(Point(minX, minY), Point(maxX.toInt(), maxY.toInt())) + } + /** * Initializes an InputOverlayDrawableButton, given by resId, with all of the * parameters set for it to be properly shown on the InputOverlay. @@ -795,6 +827,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context * for Android to call the onDraw method. * * @param context The current [Context]. + * @param windowSize The size of the window to draw the overlay on. * @param defaultResId The resource ID of the [Drawable] to get the [Bitmap] of (Default State). * @param pressedResId The resource ID of the [Drawable] to get the [Bitmap] of (Pressed State). * @param buttonId Identifier for determining what type of button the initialized InputOverlayDrawableButton represents. @@ -802,6 +835,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context */ private fun initializeOverlayButton( context: Context, + windowSize: Pair, defaultResId: Int, pressedResId: Int, buttonId: Int, @@ -836,12 +870,18 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context val overlayDrawable = InputOverlayDrawableButton(res, defaultStateBitmap, pressedStateBitmap, buttonId) + // Get the minimum and maximum coordinates of the screen where the button can be placed. + val min = windowSize.first + val max = windowSize.second + // The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay. // These were set in the input overlay configuration menu. val xKey = "$buttonId$orientation-X" val yKey = "$buttonId$orientation-Y" - val drawableX = sPrefs.getFloat(xKey, 0f).toInt() - val drawableY = sPrefs.getFloat(yKey, 0f).toInt() + val drawableXPercent = sPrefs.getFloat(xKey, 0f) + val drawableYPercent = sPrefs.getFloat(yKey, 0f) + val drawableX = (drawableXPercent * max.x + min.x).toInt() + val drawableY = (drawableYPercent * max.y + min.y).toInt() val width = overlayDrawable.width val height = overlayDrawable.height @@ -866,6 +906,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context * Initializes an [InputOverlayDrawableDpad] * * @param context The current [Context]. + * @param windowSize The size of the window to draw the overlay on. * @param defaultResId The [Bitmap] resource ID of the default state. * @param pressedOneDirectionResId The [Bitmap] resource ID of the pressed state in one direction. * @param pressedTwoDirectionsResId The [Bitmap] resource ID of the pressed state in two directions. @@ -873,6 +914,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context */ private fun initializeOverlayDpad( context: Context, + windowSize: Pair, defaultResId: Int, pressedOneDirectionResId: Int, pressedTwoDirectionsResId: Int, @@ -907,10 +949,16 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context ButtonType.DPAD_RIGHT ) + // Get the minimum and maximum coordinates of the screen where the button can be placed. + val min = windowSize.first + val max = windowSize.second + // The X and Y coordinates of the InputOverlayDrawableDpad on the InputOverlay. // These were set in the input overlay configuration menu. - val drawableX = sPrefs.getFloat("${ButtonType.DPAD_UP}$orientation-X", 0f).toInt() - val drawableY = sPrefs.getFloat("${ButtonType.DPAD_UP}$orientation-Y", 0f).toInt() + val drawableXPercent = sPrefs.getFloat("${ButtonType.DPAD_UP}$orientation-X", 0f) + val drawableYPercent = sPrefs.getFloat("${ButtonType.DPAD_UP}$orientation-Y", 0f) + val drawableX = (drawableXPercent * max.x + min.x).toInt() + val drawableY = (drawableYPercent * max.y + min.y).toInt() val width = overlayDrawable.width val height = overlayDrawable.height @@ -932,6 +980,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context * Initializes an [InputOverlayDrawableJoystick] * * @param context The current [Context] + * @param windowSize The size of the window to draw the overlay on. * @param resOuter Resource ID for the outer image of the joystick (the static image that shows the circular bounds). * @param defaultResInner Resource ID for the default inner image of the joystick (the one you actually move around). * @param pressedResInner Resource ID for the pressed inner image of the joystick. @@ -941,6 +990,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context */ private fun initializeOverlayJoystick( context: Context, + windowSize: Pair, resOuter: Int, defaultResInner: Int, pressedResInner: Int, @@ -964,10 +1014,16 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context val bitmapInnerDefault = getBitmap(context, defaultResInner, 1.0f) val bitmapInnerPressed = getBitmap(context, pressedResInner, 1.0f) + // Get the minimum and maximum coordinates of the screen where the button can be placed. + val min = windowSize.first + val max = windowSize.second + // The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay. // These were set in the input overlay configuration menu. - val drawableX = sPrefs.getFloat("$button$orientation-X", 0f).toInt() - val drawableY = sPrefs.getFloat("$button$orientation-Y", 0f).toInt() + val drawableXPercent = sPrefs.getFloat("$button$orientation-X", 0f) + val drawableYPercent = sPrefs.getFloat("$button$orientation-Y", 0f) + val drawableX = (drawableXPercent * max.x + min.x).toInt() + val drawableY = (drawableYPercent * max.y + min.y).toInt() val outerScale = 1.66f // Now set the bounds for the InputOverlayDrawableJoystick.