summaryrefslogtreecommitdiff
path: root/src/android
diff options
context:
space:
mode:
authorGravatar Abandoned Cart2023-06-11 19:37:55 -0400
committerGravatar Abandoned Cart2023-06-14 16:34:16 -0400
commit0ef93541b458b4845a6a50278e1539f91eb05e9f (patch)
treee191f055a99770178f0d9abdc3567d3f4ac238c9 /src/android
parentandroid: Add Picture in Picture / Orientation (diff)
downloadyuzu-0ef93541b458b4845a6a50278e1539f91eb05e9f.tar.gz
yuzu-0ef93541b458b4845a6a50278e1539f91eb05e9f.tar.xz
yuzu-0ef93541b458b4845a6a50278e1539f91eb05e9f.zip
android: Enable automated portrait controls
Diffstat (limited to 'src/android')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt6
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/overlay/InputOverlay.kt115
2 files changed, 40 insertions, 81 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
index 6ea5c90f3..097820952 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
@@ -10,6 +10,7 @@ import android.content.DialogInterface
10import android.content.Intent 10import android.content.Intent
11import android.content.SharedPreferences 11import android.content.SharedPreferences
12import android.content.pm.ActivityInfo 12import android.content.pm.ActivityInfo
13import android.content.res.Configuration
13import android.content.res.Resources 14import android.content.res.Resources
14import android.graphics.Color 15import android.graphics.Color
15import android.os.Bundle 16import android.os.Bundle
@@ -192,6 +193,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
192 } 193 }
193 } 194 }
194 195
196 override fun onConfigurationChanged(newConfig: Configuration) {
197 super.onConfigurationChanged(newConfig)
198 if (!binding.surfaceInputOverlay.isInEditMode()) refreshInputOverlay()
199 }
200
195 override fun onResume() { 201 override fun onResume() {
196 super.onResume() 202 super.onResume()
197 if (!DirectoryInitialization.areDirectoriesReady) { 203 if (!DirectoryInitialization.areDirectoriesReady) {
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 724929a04..45dbf9dfa 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
@@ -7,7 +7,6 @@ import android.annotation.SuppressLint
7import android.app.Activity 7import android.app.Activity
8import android.content.Context 8import android.content.Context
9import android.content.SharedPreferences 9import android.content.SharedPreferences
10import android.content.res.Configuration
11import android.graphics.Bitmap 10import android.graphics.Bitmap
12import android.graphics.Canvas 11import android.graphics.Canvas
13import android.graphics.Point 12import android.graphics.Point
@@ -77,25 +76,6 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
77 requestFocus() 76 requestFocus()
78 } 77 }
79 78
80 @SuppressLint("DrawAllocation")
81 override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
82 super.onMeasure(widthMeasureSpec, heightMeasureSpec)
83 val width = MeasureSpec.getSize(widthMeasureSpec)
84 val height = MeasureSpec.getSize(heightMeasureSpec)
85 if (height > width) {
86 val aspectRatio = with (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager) {
87 val metrics = maximumWindowMetrics.bounds
88 Rational(metrics.height(), metrics.width()).toFloat()
89 }
90 val newWidth: Int = width
91 val newHeight: Int = (width / aspectRatio).roundToInt()
92 setMeasuredDimension(newWidth, newHeight)
93 invalidate()
94 } else {
95 setMeasuredDimension(width, height)
96 }
97 }
98
99 override fun draw(canvas: Canvas) { 79 override fun draw(canvas: Canvas) {
100 super.draw(canvas) 80 super.draw(canvas)
101 for (button in overlayButtons) { 81 for (button in overlayButtons) {
@@ -256,10 +236,6 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
256 val fingerPositionX = event.getX(pointerIndex).toInt() 236 val fingerPositionX = event.getX(pointerIndex).toInt()
257 val fingerPositionY = event.getY(pointerIndex).toInt() 237 val fingerPositionY = event.getY(pointerIndex).toInt()
258 238
259 // TODO: Provide support for portrait layout
260 //val orientation =
261 // if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) "-Portrait" else ""
262
263 for (button in overlayButtons) { 239 for (button in overlayButtons) {
264 // Determine the button state to apply based on the MotionEvent action flag. 240 // Determine the button state to apply based on the MotionEvent action flag.
265 when (event.action and MotionEvent.ACTION_MASK) { 241 when (event.action and MotionEvent.ACTION_MASK) {
@@ -288,8 +264,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
288 saveControlPosition( 264 saveControlPosition(
289 buttonBeingConfigured!!.buttonId, 265 buttonBeingConfigured!!.buttonId,
290 buttonBeingConfigured!!.bounds.centerX(), 266 buttonBeingConfigured!!.bounds.centerX(),
291 buttonBeingConfigured!!.bounds.centerY(), 267 buttonBeingConfigured!!.bounds.centerY()
292 ""
293 ) 268 )
294 buttonBeingConfigured = null 269 buttonBeingConfigured = null
295 } 270 }
@@ -321,8 +296,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
321 saveControlPosition( 296 saveControlPosition(
322 dpadBeingConfigured!!.upId, 297 dpadBeingConfigured!!.upId,
323 dpadBeingConfigured!!.bounds.centerX(), 298 dpadBeingConfigured!!.bounds.centerX(),
324 dpadBeingConfigured!!.bounds.centerY(), 299 dpadBeingConfigured!!.bounds.centerY()
325 ""
326 ) 300 )
327 dpadBeingConfigured = null 301 dpadBeingConfigured = null
328 } 302 }
@@ -352,8 +326,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
352 saveControlPosition( 326 saveControlPosition(
353 joystickBeingConfigured!!.buttonId, 327 joystickBeingConfigured!!.buttonId,
354 joystickBeingConfigured!!.bounds.centerX(), 328 joystickBeingConfigured!!.bounds.centerX(),
355 joystickBeingConfigured!!.bounds.centerY(), 329 joystickBeingConfigured!!.bounds.centerY()
356 ""
357 ) 330 )
358 joystickBeingConfigured = null 331 joystickBeingConfigured = null
359 } 332 }
@@ -363,7 +336,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
363 return true 336 return true
364 } 337 }
365 338
366 private fun addOverlayControls(orientation: String) { 339 private fun addOverlayControls() {
367 val windowSize = getSafeScreenSize(context) 340 val windowSize = getSafeScreenSize(context)
368 if (preferences.getBoolean(Settings.PREF_BUTTON_TOGGLE_0, true)) { 341 if (preferences.getBoolean(Settings.PREF_BUTTON_TOGGLE_0, true)) {
369 overlayButtons.add( 342 overlayButtons.add(
@@ -372,8 +345,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
372 windowSize, 345 windowSize,
373 R.drawable.facebutton_a, 346 R.drawable.facebutton_a,
374 R.drawable.facebutton_a_depressed, 347 R.drawable.facebutton_a_depressed,
375 ButtonType.BUTTON_A, 348 ButtonType.BUTTON_A
376 orientation
377 ) 349 )
378 ) 350 )
379 } 351 }
@@ -384,8 +356,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
384 windowSize, 356 windowSize,
385 R.drawable.facebutton_b, 357 R.drawable.facebutton_b,
386 R.drawable.facebutton_b_depressed, 358 R.drawable.facebutton_b_depressed,
387 ButtonType.BUTTON_B, 359 ButtonType.BUTTON_B
388 orientation
389 ) 360 )
390 ) 361 )
391 } 362 }
@@ -396,8 +367,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
396 windowSize, 367 windowSize,
397 R.drawable.facebutton_x, 368 R.drawable.facebutton_x,
398 R.drawable.facebutton_x_depressed, 369 R.drawable.facebutton_x_depressed,
399 ButtonType.BUTTON_X, 370 ButtonType.BUTTON_X
400 orientation
401 ) 371 )
402 ) 372 )
403 } 373 }
@@ -408,8 +378,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
408 windowSize, 378 windowSize,
409 R.drawable.facebutton_y, 379 R.drawable.facebutton_y,
410 R.drawable.facebutton_y_depressed, 380 R.drawable.facebutton_y_depressed,
411 ButtonType.BUTTON_Y, 381 ButtonType.BUTTON_Y
412 orientation
413 ) 382 )
414 ) 383 )
415 } 384 }
@@ -420,8 +389,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
420 windowSize, 389 windowSize,
421 R.drawable.l_shoulder, 390 R.drawable.l_shoulder,
422 R.drawable.l_shoulder_depressed, 391 R.drawable.l_shoulder_depressed,
423 ButtonType.TRIGGER_L, 392 ButtonType.TRIGGER_L
424 orientation
425 ) 393 )
426 ) 394 )
427 } 395 }
@@ -432,8 +400,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
432 windowSize, 400 windowSize,
433 R.drawable.r_shoulder, 401 R.drawable.r_shoulder,
434 R.drawable.r_shoulder_depressed, 402 R.drawable.r_shoulder_depressed,
435 ButtonType.TRIGGER_R, 403 ButtonType.TRIGGER_R
436 orientation
437 ) 404 )
438 ) 405 )
439 } 406 }
@@ -444,8 +411,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
444 windowSize, 411 windowSize,
445 R.drawable.zl_trigger, 412 R.drawable.zl_trigger,
446 R.drawable.zl_trigger_depressed, 413 R.drawable.zl_trigger_depressed,
447 ButtonType.TRIGGER_ZL, 414 ButtonType.TRIGGER_ZL
448 orientation
449 ) 415 )
450 ) 416 )
451 } 417 }
@@ -456,8 +422,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
456 windowSize, 422 windowSize,
457 R.drawable.zr_trigger, 423 R.drawable.zr_trigger,
458 R.drawable.zr_trigger_depressed, 424 R.drawable.zr_trigger_depressed,
459 ButtonType.TRIGGER_ZR, 425 ButtonType.TRIGGER_ZR
460 orientation
461 ) 426 )
462 ) 427 )
463 } 428 }
@@ -468,8 +433,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
468 windowSize, 433 windowSize,
469 R.drawable.facebutton_plus, 434 R.drawable.facebutton_plus,
470 R.drawable.facebutton_plus_depressed, 435 R.drawable.facebutton_plus_depressed,
471 ButtonType.BUTTON_PLUS, 436 ButtonType.BUTTON_PLUS
472 orientation
473 ) 437 )
474 ) 438 )
475 } 439 }
@@ -480,8 +444,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
480 windowSize, 444 windowSize,
481 R.drawable.facebutton_minus, 445 R.drawable.facebutton_minus,
482 R.drawable.facebutton_minus_depressed, 446 R.drawable.facebutton_minus_depressed,
483 ButtonType.BUTTON_MINUS, 447 ButtonType.BUTTON_MINUS
484 orientation
485 ) 448 )
486 ) 449 )
487 } 450 }
@@ -492,8 +455,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
492 windowSize, 455 windowSize,
493 R.drawable.dpad_standard, 456 R.drawable.dpad_standard,
494 R.drawable.dpad_standard_cardinal_depressed, 457 R.drawable.dpad_standard_cardinal_depressed,
495 R.drawable.dpad_standard_diagonal_depressed, 458 R.drawable.dpad_standard_diagonal_depressed
496 orientation
497 ) 459 )
498 ) 460 )
499 } 461 }
@@ -506,8 +468,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
506 R.drawable.joystick, 468 R.drawable.joystick,
507 R.drawable.joystick_depressed, 469 R.drawable.joystick_depressed,
508 StickType.STICK_L, 470 StickType.STICK_L,
509 ButtonType.STICK_L, 471 ButtonType.STICK_L
510 orientation
511 ) 472 )
512 ) 473 )
513 } 474 }
@@ -520,8 +481,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
520 R.drawable.joystick, 481 R.drawable.joystick,
521 R.drawable.joystick_depressed, 482 R.drawable.joystick_depressed,
522 StickType.STICK_R, 483 StickType.STICK_R,
523 ButtonType.STICK_R, 484 ButtonType.STICK_R
524 orientation
525 ) 485 )
526 ) 486 )
527 } 487 }
@@ -532,8 +492,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
532 windowSize, 492 windowSize,
533 R.drawable.facebutton_home, 493 R.drawable.facebutton_home,
534 R.drawable.facebutton_home_depressed, 494 R.drawable.facebutton_home_depressed,
535 ButtonType.BUTTON_HOME, 495 ButtonType.BUTTON_HOME
536 orientation
537 ) 496 )
538 ) 497 )
539 } 498 }
@@ -544,8 +503,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
544 windowSize, 503 windowSize,
545 R.drawable.facebutton_screenshot, 504 R.drawable.facebutton_screenshot,
546 R.drawable.facebutton_screenshot_depressed, 505 R.drawable.facebutton_screenshot_depressed,
547 ButtonType.BUTTON_CAPTURE, 506 ButtonType.BUTTON_CAPTURE
548 orientation
549 ) 507 )
550 ) 508 )
551 } 509 }
@@ -556,23 +514,21 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
556 overlayButtons.clear() 514 overlayButtons.clear()
557 overlayDpads.clear() 515 overlayDpads.clear()
558 overlayJoysticks.clear() 516 overlayJoysticks.clear()
559 val orientation =
560 if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) "-Portrait" else ""
561 517
562 // Add all the enabled overlay items back to the HashSet. 518 // Add all the enabled overlay items back to the HashSet.
563 if (EmulationMenuSettings.showOverlay) { 519 if (EmulationMenuSettings.showOverlay) {
564 addOverlayControls(orientation) 520 addOverlayControls()
565 } 521 }
566 invalidate() 522 invalidate()
567 } 523 }
568 524
569 private fun saveControlPosition(sharedPrefsId: Int, x: Int, y: Int, orientation: String) { 525 private fun saveControlPosition(sharedPrefsId: Int, x: Int, y: Int) {
570 val windowSize = getSafeScreenSize(context) 526 val windowSize = getSafeScreenSize(context)
571 val min = windowSize.first 527 val min = windowSize.first
572 val max = windowSize.second 528 val max = windowSize.second
573 PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext).edit() 529 PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext).edit()
574 .putFloat("$sharedPrefsId$orientation-X", (x - min.x).toFloat() / max.x) 530 .putFloat("$sharedPrefsId-X", (x - min.x).toFloat() / max.x)
575 .putFloat("$sharedPrefsId$orientation-Y", (y - min.y).toFloat() / max.y) 531 .putFloat("$sharedPrefsId-Y", (y - min.y).toFloat() / max.y)
576 .apply() 532 .apply()
577 } 533 }
578 534
@@ -791,9 +747,9 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
791 val insets = context.windowManager.currentWindowMetrics.windowInsets.displayCutout 747 val insets = context.windowManager.currentWindowMetrics.windowInsets.displayCutout
792 if (insets != null) { 748 if (insets != null) {
793 if (insets.boundingRectTop.bottom != 0 && insets.boundingRectTop.bottom > maxY / 2) 749 if (insets.boundingRectTop.bottom != 0 && insets.boundingRectTop.bottom > maxY / 2)
794 insets.boundingRectTop.bottom.toFloat() else maxY 750 maxY = insets.boundingRectTop.bottom.toFloat()
795 if (insets.boundingRectRight.left != 0 && insets.boundingRectRight.left > maxX / 2) 751 if (insets.boundingRectRight.left != 0 && insets.boundingRectRight.left > maxX / 2)
796 insets.boundingRectRight.left.toFloat() else maxX 752 maxX = insets.boundingRectRight.left.toFloat()
797 753
798 minX = insets.boundingRectLeft.right - insets.boundingRectLeft.left 754 minX = insets.boundingRectLeft.right - insets.boundingRectLeft.left
799 minY = insets.boundingRectBottom.top - insets.boundingRectBottom.bottom 755 minY = insets.boundingRectBottom.top - insets.boundingRectBottom.bottom
@@ -862,8 +818,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
862 windowSize: Pair<Point, Point>, 818 windowSize: Pair<Point, Point>,
863 defaultResId: Int, 819 defaultResId: Int,
864 pressedResId: Int, 820 pressedResId: Int,
865 buttonId: Int, 821 buttonId: Int
866 orientation: String
867 ): InputOverlayDrawableButton { 822 ): InputOverlayDrawableButton {
868 // Resources handle for fetching the initial Drawable resource. 823 // Resources handle for fetching the initial Drawable resource.
869 val res = context.resources 824 val res = context.resources
@@ -900,8 +855,8 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
900 855
901 // The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay. 856 // The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay.
902 // These were set in the input overlay configuration menu. 857 // These were set in the input overlay configuration menu.
903 val xKey = "$buttonId$orientation-X" 858 val xKey = "$buttonId-X"
904 val yKey = "$buttonId$orientation-Y" 859 val yKey = "$buttonId-Y"
905 val drawableXPercent = sPrefs.getFloat(xKey, 0f) 860 val drawableXPercent = sPrefs.getFloat(xKey, 0f)
906 val drawableYPercent = sPrefs.getFloat(yKey, 0f) 861 val drawableYPercent = sPrefs.getFloat(yKey, 0f)
907 val drawableX = (drawableXPercent * max.x + min.x).toInt() 862 val drawableX = (drawableXPercent * max.x + min.x).toInt()
@@ -943,8 +898,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
943 windowSize: Pair<Point, Point>, 898 windowSize: Pair<Point, Point>,
944 defaultResId: Int, 899 defaultResId: Int,
945 pressedOneDirectionResId: Int, 900 pressedOneDirectionResId: Int,
946 pressedTwoDirectionsResId: Int, 901 pressedTwoDirectionsResId: Int
947 orientation: String
948 ): InputOverlayDrawableDpad { 902 ): InputOverlayDrawableDpad {
949 // Resources handle for fetching the initial Drawable resource. 903 // Resources handle for fetching the initial Drawable resource.
950 val res = context.resources 904 val res = context.resources
@@ -981,8 +935,8 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
981 935
982 // The X and Y coordinates of the InputOverlayDrawableDpad on the InputOverlay. 936 // The X and Y coordinates of the InputOverlayDrawableDpad on the InputOverlay.
983 // These were set in the input overlay configuration menu. 937 // These were set in the input overlay configuration menu.
984 val drawableXPercent = sPrefs.getFloat("${ButtonType.DPAD_UP}$orientation-X", 0f) 938 val drawableXPercent = sPrefs.getFloat("${ButtonType.DPAD_UP}-X", 0f)
985 val drawableYPercent = sPrefs.getFloat("${ButtonType.DPAD_UP}$orientation-Y", 0f) 939 val drawableYPercent = sPrefs.getFloat("${ButtonType.DPAD_UP}-Y", 0f)
986 val drawableX = (drawableXPercent * max.x + min.x).toInt() 940 val drawableX = (drawableXPercent * max.x + min.x).toInt()
987 val drawableY = (drawableYPercent * max.y + min.y).toInt() 941 val drawableY = (drawableYPercent * max.y + min.y).toInt()
988 val width = overlayDrawable.width 942 val width = overlayDrawable.width
@@ -1023,8 +977,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
1023 defaultResInner: Int, 977 defaultResInner: Int,
1024 pressedResInner: Int, 978 pressedResInner: Int,
1025 joystick: Int, 979 joystick: Int,
1026 button: Int, 980 button: Int
1027 orientation: String
1028 ): InputOverlayDrawableJoystick { 981 ): InputOverlayDrawableJoystick {
1029 // Resources handle for fetching the initial Drawable resource. 982 // Resources handle for fetching the initial Drawable resource.
1030 val res = context.resources 983 val res = context.resources
@@ -1048,8 +1001,8 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context
1048 1001
1049 // The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay. 1002 // The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay.
1050 // These were set in the input overlay configuration menu. 1003 // These were set in the input overlay configuration menu.
1051 val drawableXPercent = sPrefs.getFloat("$button$orientation-X", 0f) 1004 val drawableXPercent = sPrefs.getFloat("$button-X", 0f)
1052 val drawableYPercent = sPrefs.getFloat("$button$orientation-Y", 0f) 1005 val drawableYPercent = sPrefs.getFloat("$button-Y", 0f)
1053 val drawableX = (drawableXPercent * max.x + min.x).toInt() 1006 val drawableX = (drawableXPercent * max.x + min.x).toInt()
1054 val drawableY = (drawableYPercent * max.y + min.y).toInt() 1007 val drawableY = (drawableYPercent * max.y + min.y).toInt()
1055 val outerScale = 1.66f 1008 val outerScale = 1.66f