diff options
| author | bunnei <bunneidev@gmail.com> | 2023-06-01 17:57:49 -0700 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2023-06-03 00:06:07 -0700 | 
| commit | 057117f0096a47b07f9070d48a0dbd952ab0522e (patch) | |
| tree | b3364fb9ad8e94d16691acc7831d477d975188ff | |
| parent | ca4b07a2d7b67ee042ab886d8373faf88c2fd883 (diff) | |
android: Fix presentation layout on foldable and tablet devices.
5 files changed, 94 insertions, 22 deletions
| diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt index abeb01995..81474b824 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt @@ -7,6 +7,7 @@ import android.app.Activity  import android.content.Context  import android.content.DialogInterface  import android.content.Intent +import android.content.res.Configuration  import android.graphics.Rect  import android.hardware.Sensor  import android.hardware.SensorEvent @@ -31,6 +32,7 @@ import org.yuzu.yuzu_emu.features.settings.model.Settings  import org.yuzu.yuzu_emu.fragments.EmulationFragment  import org.yuzu.yuzu_emu.model.Game  import org.yuzu.yuzu_emu.utils.ControllerMappingHelper +import org.yuzu.yuzu_emu.utils.EmulationMenuSettings  import org.yuzu.yuzu_emu.utils.ForegroundService  import org.yuzu.yuzu_emu.utils.InputHandler  import org.yuzu.yuzu_emu.utils.NfcReader @@ -128,6 +130,11 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {          super.onResume()          nfcReader.startScanning()          startMotionSensorListener() + +        NativeLibrary.notifyOrientationChange( +            EmulationMenuSettings.landscapeScreenLayout, +            getAdjustedRotation() +        )      }      override fun onPause() { @@ -233,6 +240,23 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {      override fun onAccuracyChanged(sensor: Sensor, i: Int) {} +    private fun getAdjustedRotation():Int { +        val rotation = windowManager.defaultDisplay.rotation; +        val config: Configuration = resources.configuration + +        if ((config.screenLayout and Configuration.SCREENLAYOUT_LONG_YES) != 0 || +            (config.screenLayout and Configuration.SCREENLAYOUT_LONG_NO) == 0) { +            return rotation; +        } +        when (rotation) { +            Surface.ROTATION_0 -> return Surface.ROTATION_90; +            Surface.ROTATION_90 -> return Surface.ROTATION_0; +            Surface.ROTATION_180 -> return Surface.ROTATION_270; +            Surface.ROTATION_270 -> return Surface.ROTATION_180; +        } +        return rotation; +    } +      private fun restoreState(savedInstanceState: Bundle) {          game = savedInstanceState.parcelable(EXTRA_SELECTED_GAME)!!      } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt index 783122860..72e2cce2a 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt @@ -118,12 +118,6 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {      override fun onStop() {          super.onStop()          presenter.onStop(isFinishing) - -        // Update framebuffer layout when closing the settings -        NativeLibrary.notifyOrientationChange( -            EmulationMenuSettings.landscapeScreenLayout, -            windowManager.defaultDisplay.rotation -        )      }      override fun showSettingsFragment(menuTag: String, addToStack: Boolean, gameId: String) { 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 693e70973..c9f5797ac 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 @@ -767,10 +767,11 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context              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 +                if (insets.boundingRectTop.bottom != 0 && insets.boundingRectTop.bottom > maxY / 2) +                    insets.boundingRectTop.bottom.toFloat() else maxY +                if (insets.boundingRectRight.left != 0 && insets.boundingRectRight.left > maxX / 2) +                    insets.boundingRectRight.left.toFloat() else maxX +                  minX = insets.boundingRectLeft.right - insets.boundingRectLeft.left                  minY = insets.boundingRectBottom.top - insets.boundingRectBottom.bottom @@ -778,7 +779,6 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context                  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. diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp index bbe6abdb0..d503ef61d 100644 --- a/src/android/app/src/main/jni/native.cpp +++ b/src/android/app/src/main/jni/native.cpp @@ -89,8 +89,16 @@ public:          return m_native_window;      } -    void SetNativeWindow(ANativeWindow* m_native_window_) { -        m_native_window = m_native_window_; +    void SetNativeWindow(ANativeWindow* native_window) { +        m_native_window = native_window; +    } + +    u32 ScreenRotation() const { +        return m_screen_rotation; +    } + +    void SetScreenRotation(u32 screen_rotation) { +        m_screen_rotation = screen_rotation;      }      void InitializeGpuDriver(const std::string& hook_lib_dir, const std::string& custom_driver_dir, @@ -379,6 +387,7 @@ private:      // Window management      std::unique_ptr<EmuWindow_Android> m_window;      ANativeWindow* m_native_window{}; +    u32 m_screen_rotation{};      // Core emulation      Core::System m_system; @@ -404,6 +413,10 @@ private:  } // Anonymous namespace +u32 GetAndroidScreenRotation() { +    return EmulationSession::GetInstance().ScreenRotation(); +} +  static Core::SystemResultStatus RunEmulation(const std::string& filepath) {      Common::Log::Initialize();      Common::Log::SetColorConsoleBackendEnabled(true); @@ -450,7 +463,9 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_surfaceDestroyed(JNIEnv* env,  void Java_org_yuzu_yuzu_1emu_NativeLibrary_notifyOrientationChange(JNIEnv* env,                                                                     [[maybe_unused]] jclass clazz,                                                                     jint layout_option, -                                                                   jint rotation) {} +                                                                   jint rotation) { +    return EmulationSession::GetInstance().SetScreenRotation(static_cast<u32>(rotation)); +}  void Java_org_yuzu_yuzu_1emu_NativeLibrary_setAppDirectory(JNIEnv* env,                                                             [[maybe_unused]] jclass clazz, diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp index e4c581a28..7cdde992b 100644 --- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp +++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp @@ -37,6 +37,10 @@  #include "video_core/vulkan_common/vulkan_memory_allocator.h"  #include "video_core/vulkan_common/vulkan_wrapper.h" +#ifdef ANDROID +extern u32 GetAndroidScreenRotation(); +#endif +  namespace Vulkan {  namespace { @@ -74,23 +78,58 @@ struct ScreenRectVertex {      }  }; -constexpr std::array<f32, 4 * 4> MakeOrthographicMatrix(f32 width, f32 height) { -    // clang-format off  #ifdef ANDROID -    // Android renders in portrait, so rotate the matrix. -    return { 0.f,          2.f / width, 0.f, 0.f, -            -2.f / height, 0.f,         0.f, 0.f, -             0.f,          0.f,         1.f, 0.f, -             1.f,         -1.f,         0.f, 1.f}; + +std::array<f32, 4 * 4> MakeOrthographicMatrix(f32 width, f32 height) { +    constexpr u32 ROTATION_0 = 0; +    constexpr u32 ROTATION_90 = 1; +    constexpr u32 ROTATION_180 = 2; +    constexpr u32 ROTATION_270 = 3; + +    // clang-format off +    switch (GetAndroidScreenRotation()) { +        case ROTATION_0: +            // Desktop +            return { 2.f / width, 0.f,          0.f, 0.f, +                     0.f,         2.f / height, 0.f, 0.f, +                     0.f,         0.f,          1.f, 0.f, +                    -1.f,        -1.f,          0.f, 1.f}; +        case ROTATION_180: +            // Reverse desktop +            return {-2.f / width, 0.f,          0.f, 0.f, +                     0.f,        -2.f / height, 0.f, 0.f, +                     0.f,         0.f,          1.f, 0.f, +                     1.f,         1.f,          0.f, 1.f}; +        case ROTATION_270: +            // Reverse landscape +            return { 0.f,         -2.f / width, 0.f, 0.f, +                     2.f / height, 0.f,         0.f, 0.f, +                     0.f,          0.f,         1.f, 0.f, +                    -1.f,          1.f,         0.f, 1.f}; +        case ROTATION_90: +        default: +            // Landscape +            return { 0.f,          2.f / width, 0.f, 0.f, +                    -2.f / height, 0.f,         0.f, 0.f, +                     0.f,          0.f,         1.f, 0.f, +                     1.f,         -1.f,         0.f, 1.f}; +    } +    // clang-format on +} +  #else + +std::array<f32, 4 * 4> MakeOrthographicMatrix(f32 width, f32 height) { +    // clang-format off      return { 2.f / width, 0.f,          0.f, 0.f,               0.f,         2.f / height, 0.f, 0.f,               0.f,         0.f,          1.f, 0.f,              -1.f,        -1.f,          0.f, 1.f}; -#endif // ANDROID      // clang-format on  } +#endif +  u32 GetBytesPerPixel(const Tegra::FramebufferConfig& framebuffer) {      using namespace VideoCore::Surface;      return BytesPerBlock(PixelFormatFromGPUPixelFormat(framebuffer.pixel_format)); | 
