diff --git a/app/src/main/java/app/gamenative/PluviaApp.kt b/app/src/main/java/app/gamenative/PluviaApp.kt index 5c0932f0b8..1e14648c36 100644 --- a/app/src/main/java/app/gamenative/PluviaApp.kt +++ b/app/src/main/java/app/gamenative/PluviaApp.kt @@ -1,6 +1,10 @@ package app.gamenative +import android.hardware.display.DisplayManager +import android.os.Build import android.os.StrictMode +import android.util.DisplayMetrics +import android.view.Display import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue @@ -51,6 +55,7 @@ class PluviaApp : SplitCompatApplication() { override fun onCreate() { super.onCreate() + instance = this preloadSystemLibraries() @@ -199,6 +204,9 @@ class PluviaApp : SplitCompatApplication() { val events: EventDispatcher = EventDispatcher() internal var onDestinationChangedListener: NavChangedListener? = null + private lateinit var instance: PluviaApp + private var cachedDefaultScreenSize: String? = null + // TODO: find a way to make this saveable, this is terrible (leak that memory baby) internal var xEnvironment: XEnvironment? = null internal var xServerView: XServerRendererView? = null @@ -262,6 +270,56 @@ class PluviaApp : SplitCompatApplication() { fun isManualSuspendMode(): Boolean = activeSuspendPolicy.equals(Container.SUSPEND_POLICY_MANUAL, ignoreCase = true) + fun getDefaultScreenSize(): String { + cachedDefaultScreenSize?.let { return it } + + return try { + val displayManager = instance.getSystemService(DISPLAY_SERVICE) as? DisplayManager + val display = displayManager?.getDisplay(Display.DEFAULT_DISPLAY) + if (display != null) { + val width : Int + val height : Int + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + val mode = display.mode + width = mode.physicalWidth + height = mode.physicalHeight + } else { + // API < 30 - Use deprecated Display API + val displayMetrics = DisplayMetrics() + @Suppress("DEPRECATION") + display.getRealMetrics(displayMetrics) + width = displayMetrics.widthPixels + height = displayMetrics.heightPixels + } + + // Calculate aspect ratio (always use landscape orientation for calculation) + val aspectRatio = maxOf(width, height).toFloat() / minOf(width, height).toFloat() + + // Aspect ratio thresholds: + // 4:3 = 1.33 + // 16:10 = 1.6 + // 16:9 = 1.77 + + val result = when { + aspectRatio < 1.5f -> Container.DEFAULT_SCREEN_SIZE_4_3 // 4:3 aspect ratio devices + aspectRatio < 1.7f -> Container.DEFAULT_SCREEN_SIZE_16_10 // 16:10 aspect ratio devices + else -> Container.DEFAULT_SCREEN_SIZE_16_9 // 16:9 and wider aspect ratio devices + } + cachedDefaultScreenSize = result + result + } else { + val fallback = Container.DEFAULT_SCREEN_SIZE_16_9 // Fallback to default + cachedDefaultScreenSize = fallback + fallback + } + } catch (e: Exception) { + Timber.e(e, "Failed to get device screen size") + val fallback = Container.DEFAULT_SCREEN_SIZE_16_9 // Fallback to default + cachedDefaultScreenSize = fallback + fallback + } + } } /** diff --git a/app/src/main/java/app/gamenative/PrefManager.kt b/app/src/main/java/app/gamenative/PrefManager.kt index 5ba1a36910..324d3c9fa7 100644 --- a/app/src/main/java/app/gamenative/PrefManager.kt +++ b/app/src/main/java/app/gamenative/PrefManager.kt @@ -166,7 +166,7 @@ object PrefManager { /* Container Default Settings */ private val SCREEN_SIZE = stringPreferencesKey("screen_size") var screenSize: String - get() = getPref(SCREEN_SIZE, Container.DEFAULT_SCREEN_SIZE) + get() = getPref(SCREEN_SIZE, PluviaApp.getDefaultScreenSize()) set(value) { setPref(SCREEN_SIZE, value) } diff --git a/app/src/main/java/app/gamenative/ui/data/XServerState.kt b/app/src/main/java/app/gamenative/ui/data/XServerState.kt index 8c8367c024..4e22e2b8e0 100644 --- a/app/src/main/java/app/gamenative/ui/data/XServerState.kt +++ b/app/src/main/java/app/gamenative/ui/data/XServerState.kt @@ -1,6 +1,7 @@ package app.gamenative.ui.data import androidx.compose.runtime.saveable.mapSaver +import app.gamenative.PluviaApp import com.winlator.container.Container import com.winlator.core.DXVKHelper import com.winlator.core.KeyValueSet @@ -10,7 +11,7 @@ data class XServerState( var winStarted: Boolean = false, val dxwrapper: String = Container.DEFAULT_DXWRAPPER, val dxwrapperConfig: KeyValueSet? = null, - val screenSize: String = Container.DEFAULT_SCREEN_SIZE, + val screenSize: String = PluviaApp.getDefaultScreenSize(), val wineInfo: WineInfo = WineInfo.MAIN_WINE_VERSION, val graphicsDriver: String = Container.DEFAULT_GRAPHICS_DRIVER, val graphicsDriverVersion: String = "", diff --git a/app/src/main/java/app/gamenative/utils/IntentLaunchManager.kt b/app/src/main/java/app/gamenative/utils/IntentLaunchManager.kt index 48afd0f25a..76009f22ce 100644 --- a/app/src/main/java/app/gamenative/utils/IntentLaunchManager.kt +++ b/app/src/main/java/app/gamenative/utils/IntentLaunchManager.kt @@ -2,6 +2,7 @@ package app.gamenative.utils import android.content.Context import android.content.Intent +import app.gamenative.PluviaApp import app.gamenative.PrefManager import app.gamenative.data.GameSource import com.winlator.container.Container @@ -189,7 +190,7 @@ object IntentLaunchManager { // Only include non-default values to avoid overriding existing container settings val config = ContainerData( name = if (json.has("name")) json.getString("name") else "", - screenSize = if (json.has("screenSize")) json.getString("screenSize") else Container.DEFAULT_SCREEN_SIZE, + screenSize = if (json.has("screenSize")) json.getString("screenSize") else PluviaApp.getDefaultScreenSize(), envVars = if (json.has("envVars")) json.getString("envVars") else Container.DEFAULT_ENV_VARS, graphicsDriver = if (json.has("graphicsDriver")) json.getString("graphicsDriver") else Container.DEFAULT_GRAPHICS_DRIVER, graphicsDriverVersion = if (json.has("graphicsDriverVersion")) json.getString("graphicsDriverVersion") else "", @@ -259,7 +260,7 @@ object IntentLaunchManager { return ContainerData( name = override.name.ifEmpty { base.name }, - screenSize = if (override.screenSize != Container.DEFAULT_SCREEN_SIZE) { + screenSize = if (override.screenSize != base.screenSize) { override.screenSize } else { base.screenSize diff --git a/app/src/main/java/com/winlator/container/Container.java b/app/src/main/java/com/winlator/container/Container.java index 86d3b1778f..2f96135ad3 100644 --- a/app/src/main/java/com/winlator/container/Container.java +++ b/app/src/main/java/com/winlator/container/Container.java @@ -36,7 +36,9 @@ public enum XrControllerMapping { public static final String DEFAULT_EXTERNAL_DISPLAY_MODE = EXTERNAL_DISPLAY_MODE_OFF; public static final String DEFAULT_ENV_VARS = "WRAPPER_MAX_IMAGE_COUNT=0 ZINK_DESCRIPTORS=lazy ZINK_DEBUG=compact,deck_emu MESA_SHADER_CACHE_DISABLE=false MESA_SHADER_CACHE_MAX_SIZE=512MB mesa_glthread=true WINEESYNC=1 MESA_VK_WSI_PRESENT_MODE=mailbox TU_DEBUG=noconform VKD3D_SHADER_MODEL=6_0 PULSE_LATENCY_MSEC=144"; - public static final String DEFAULT_SCREEN_SIZE = "1280x720"; + public static final String DEFAULT_SCREEN_SIZE_16_9 = "1280x720"; + public static final String DEFAULT_SCREEN_SIZE_16_10 = "1280x800"; + public static final String DEFAULT_SCREEN_SIZE_4_3 = "1280x960"; public static final String DEFAULT_GRAPHICS_DRIVER = DefaultVersion.DEFAULT_GRAPHICS_DRIVER; public static final String DEFAULT_AUDIO_DRIVER = "pulseaudio"; public static final String DEFAULT_EMULATOR = "FEXCore"; @@ -75,7 +77,7 @@ public enum XrControllerMapping { public static final byte MAX_DRIVE_LETTERS = 8; public final String id; private String name; - private String screenSize = DEFAULT_SCREEN_SIZE; + private String screenSize = DEFAULT_SCREEN_SIZE_16_9; private String envVars = DEFAULT_ENV_VARS; private String graphicsDriver = DEFAULT_GRAPHICS_DRIVER; private String dxwrapper = DEFAULT_DXWRAPPER; diff --git a/app/src/main/java/com/winlator/container/ContainerData.kt b/app/src/main/java/com/winlator/container/ContainerData.kt index 9c8e339c09..1d66f4ff9a 100644 --- a/app/src/main/java/com/winlator/container/ContainerData.kt +++ b/app/src/main/java/com/winlator/container/ContainerData.kt @@ -1,6 +1,7 @@ package com.winlator.container import androidx.compose.runtime.saveable.mapSaver +import app.gamenative.PluviaApp import com.winlator.box86_64.Box86_64Preset import com.winlator.core.DefaultVersion import com.winlator.core.WineInfo @@ -11,7 +12,7 @@ import kotlin.String data class ContainerData( val name: String = "", - val screenSize: String = Container.DEFAULT_SCREEN_SIZE, + val screenSize: String = PluviaApp.getDefaultScreenSize(), val envVars: String = Container.DEFAULT_ENV_VARS, val graphicsDriver: String = Container.DEFAULT_GRAPHICS_DRIVER, val graphicsDriverVersion: String = "", diff --git a/app/src/main/java/com/winlator/container/ContainerManager.java b/app/src/main/java/com/winlator/container/ContainerManager.java index 1ee9538815..13b45c0dd7 100644 --- a/app/src/main/java/com/winlator/container/ContainerManager.java +++ b/app/src/main/java/com/winlator/container/ContainerManager.java @@ -95,52 +95,6 @@ public void createContainerAsync(String containerId, final JSONObject data, Call public Future createContainerFuture(String containerId, final JSONObject data) { return Executors.newSingleThreadExecutor().submit(() -> createContainer(containerId, data)); } - public Future createDefaultContainerFuture(WineInfo wineInfo, String containerId) { - String name = "container_" + containerId; - Log.d("XServerScreen", "Creating container $name"); - String screenSize = Container.DEFAULT_SCREEN_SIZE; - String envVars = Container.DEFAULT_ENV_VARS; - String graphicsDriver = Container.DEFAULT_GRAPHICS_DRIVER; - String dxwrapper = Container.DEFAULT_DXWRAPPER; - String dxwrapperConfig = ""; - String audioDriver = Container.DEFAULT_AUDIO_DRIVER; - String wincomponents = Container.DEFAULT_WINCOMPONENTS; - String drives = ""; - Boolean showFPS = false; - String cpuList = Container.getFallbackCPUList(); - String cpuListWoW64 = Container.getFallbackCPUListWoW64(); - Boolean wow64Mode = WineInfo.isMainWineVersion(wineInfo.identifier()); - // Boolean wow64Mode = false; - Byte startupSelection = Container.STARTUP_SELECTION_ESSENTIAL; - String box86Preset = Box86_64Preset.COMPATIBILITY; - String box64Preset = Box86_64Preset.COMPATIBILITY; - String desktopTheme = WineThemeManager.DEFAULT_DESKTOP_THEME; - - JSONObject data = new JSONObject(); - try { - data.put("name", name); - data.put("screenSize", screenSize); - data.put("envVars", envVars); - data.put("cpuList", cpuList); - data.put("cpuListWoW64", cpuListWoW64); - data.put("graphicsDriver", graphicsDriver); - data.put("dxwrapper", dxwrapper); - data.put("dxwrapperConfig", dxwrapperConfig); - data.put("audioDriver", audioDriver); - data.put("wincomponents", wincomponents); - data.put("drives", drives); - data.put("showFPS", showFPS); - data.put("wow64Mode", wow64Mode); - data.put("startupSelection", startupSelection); - data.put("box86Preset", box86Preset); - data.put("box64Preset", box64Preset); - data.put("desktopTheme", desktopTheme); - } catch (JSONException e) { - throw new RuntimeException(e); - } - - return createContainerFuture(containerId, data); - } public void duplicateContainerAsync(Container container, Runnable callback) { final Handler handler = new Handler(); diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index f8f7a46e81..ebf7459ebf 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -10,6 +10,7 @@ 1024x768 (4:3) 1280x720 (16:9) 1280x800 (16:10) + 1280x960 (4:3) 1280x1024 (5:4) 1366x768 (16:9) 1440x900 (16:10)