From 81686f8e8f8e256834ab97db4a305464bb233450 Mon Sep 17 00:00:00 2001 From: BeZide93 Date: Tue, 28 Oct 2025 13:45:16 +0100 Subject: [PATCH 1/2] Fixed Gamescreen for Tablets and Foldables --- .../org/kenjinx/android/views/GameViews.kt | 75 +++++++++++++++++-- 1 file changed, 68 insertions(+), 7 deletions(-) diff --git a/src/KenjinxAndroid/app/src/main/java/org/kenjinx/android/views/GameViews.kt b/src/KenjinxAndroid/app/src/main/java/org/kenjinx/android/views/GameViews.kt index 8ae382828..03fbd7e59 100644 --- a/src/KenjinxAndroid/app/src/main/java/org/kenjinx/android/views/GameViews.kt +++ b/src/KenjinxAndroid/app/src/main/java/org/kenjinx/android/views/GameViews.kt @@ -48,6 +48,15 @@ import org.kenjinx.android.viewmodels.VSyncMode import org.kenjinx.android.widgets.SimpleAlertDialog import java.util.Locale import kotlin.math.roundToInt +import android.net.Uri +import android.widget.Toast +import androidx.compose.foundation.layout.aspectRatio +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.ui.platform.LocalConfiguration +import org.kenjinx.android.viewmodels.QuickSettings.VirtualControllerPreset + class GameViews { companion object { @@ -55,7 +64,7 @@ class GameViews { fun Main() { Surface( modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colorScheme.background + color = Color.Black ) { GameView(mainViewModel = MainActivity.mainViewModel!!) } @@ -63,17 +72,69 @@ class GameViews { @Composable fun GameView(mainViewModel: MainViewModel) { - Box(modifier = Modifier.fillMaxSize()) { - AndroidView( + val cfg = LocalConfiguration.current + val isLandscape = cfg.screenWidthDp >= cfg.screenHeightDp + val isLarge = (cfg.smallestScreenWidthDp >= 600) || (cfg.screenWidthDp >= 900) + + // Setting aus den Preferences (wird beim Game-Start gelesen) + val stretch = QuickSettings(mainViewModel.activity).stretchToFullscreen + + // Standard-Ratio (Switch 16:9). Wenn du später dynamisch aus dem Renderer lesen willst, + // kannst du gameAspect hier zur Laufzeit aktualisieren. + val gameAspect = 16f / 9f + + if (stretch) { + // Vollbild strecken (keine Letterbox), oben verankert + Box( modifier = Modifier.fillMaxSize(), - factory = { context -> - GameHost(context, mainViewModel) + contentAlignment = Alignment.TopCenter + ) { + AndroidView( + modifier = Modifier + .fillMaxSize() + .align(Alignment.TopCenter), + factory = { context -> GameHost(context, mainViewModel) } + ) + GameOverlay(mainViewModel) + } + } else { + // Letterbox beibehalten, aber oben fixieren. Phones: smart-fit, + // Tablets/Foldables in Landscape: erzwinge fitWidth (wie gewünscht). + BoxWithConstraints(modifier = Modifier.fillMaxSize()) { + val containerAspect = maxWidth.value / maxHeight.value + + val useFitWidth = + if (isLandscape && isLarge) true + else containerAspect < gameAspect + + val fitModifier = + if (useFitWidth) { + Modifier + .fillMaxWidth() + .aspectRatio(gameAspect) + .align(Alignment.TopCenter) + } else { + Modifier + .fillMaxHeight() + .aspectRatio(gameAspect) + .align(Alignment.TopCenter) + } + + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.TopCenter + ) { + AndroidView( + modifier = fitModifier, + factory = { context -> GameHost(context, mainViewModel) } + ) + GameOverlay(mainViewModel) } - ) - GameOverlay(mainViewModel) + } } } + @OptIn(ExperimentalMaterial3Api::class) @Composable fun GameOverlay(mainViewModel: MainViewModel) { From e8a5d136c14fa359fa1bc08b84a667310ed880f9 Mon Sep 17 00:00:00 2001 From: BeZide93 Date: Sun, 2 Nov 2025 00:55:29 +0100 Subject: [PATCH 2/2] changed comments to english --- .../main/java/org/kenjinx/android/views/GameViews.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/KenjinxAndroid/app/src/main/java/org/kenjinx/android/views/GameViews.kt b/src/KenjinxAndroid/app/src/main/java/org/kenjinx/android/views/GameViews.kt index 03fbd7e59..510ee60c6 100644 --- a/src/KenjinxAndroid/app/src/main/java/org/kenjinx/android/views/GameViews.kt +++ b/src/KenjinxAndroid/app/src/main/java/org/kenjinx/android/views/GameViews.kt @@ -76,15 +76,15 @@ class GameViews { val isLandscape = cfg.screenWidthDp >= cfg.screenHeightDp val isLarge = (cfg.smallestScreenWidthDp >= 600) || (cfg.screenWidthDp >= 900) - // Setting aus den Preferences (wird beim Game-Start gelesen) + // Setting from preferences (read at game start) val stretch = QuickSettings(mainViewModel.activity).stretchToFullscreen - // Standard-Ratio (Switch 16:9). Wenn du später dynamisch aus dem Renderer lesen willst, - // kannst du gameAspect hier zur Laufzeit aktualisieren. + // Default aspect ratio (Switch 16:9). If you later want to read dynamically from the renderer, + // you can update gameAspect here at runtime. val gameAspect = 16f / 9f if (stretch) { - // Vollbild strecken (keine Letterbox), oben verankert + // Stretch to full screen (no letterbox), anchored to the top Box( modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.TopCenter @@ -98,8 +98,8 @@ class GameViews { GameOverlay(mainViewModel) } } else { - // Letterbox beibehalten, aber oben fixieren. Phones: smart-fit, - // Tablets/Foldables in Landscape: erzwinge fitWidth (wie gewünscht). + // Keep letterbox but pin to the top. Phones: smart-fit, + // Tablets/Foldables in landscape: enforce fitWidth (as desired). BoxWithConstraints(modifier = Modifier.fillMaxSize()) { val containerAspect = maxWidth.value / maxHeight.value