diff options
| author | PabloG02 <tioo23000@gmail.com> | 2023-06-01 17:49:20 +0200 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2023-06-03 00:06:07 -0700 | 
| commit | a7e0a0d5b10e1a2cd1ba46d7b3014d7b9997fea0 (patch) | |
| tree | 993acc27cd976cf4c011d81d6eb1b71d7c640d2f | |
| parent | 8e8627a258917f7ede82add331b95a3f9f1337db (diff) | |
Save the position of buttons as a percentage
| -rw-r--r-- | src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt | 216 | 
1 files 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()      } @@ -767,6 +746,59 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context          }          /** +         * 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<Point, Point> { +            // 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<Point, Point>,              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<Point, Point>,              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<Point, Point>,              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. | 
