From 08a6e3bc5e1802a2041ccc91889ce6d47970cfc6 Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Fri, 5 Aug 2022 22:33:47 +0200 Subject: [PATCH] Several changes - added "borderless" and "virtual desktop" options to settings; added separate FSR option to gamescope settings - dxvk now uses wine64 to update prefix before applying patches - added setting of `-window-mode exclusive` args to the wine when using wine FSR - `WinePrefix::update` and so now use wine64 binary instead of wineboot - renamed `files.wine` to `files.wine64` in `wine.json` - `Config::try_get_wine_executable` function now return wine64 binary - added picture to the repo --- README.md | 1 + assets/ui/preferences/enhancements.blp | 16 ++++ assets/ui/preferences/gamescope.blp | 10 ++- assets/wine.json | 78 +++++++++---------- .../config/game/enhancements/gamescope/mod.rs | 31 +++++--- src/lib/config/game/wine/mod.rs | 20 ++++- src/lib/config/game/wine/virtual_desktop.rs | 60 ++++++++++++++ src/lib/config/game/wine/wine_lang.rs | 22 ++++-- src/lib/config/mod.rs | 57 +++++--------- src/lib/config/resolution.rs | 75 ++++++++++++++++++ src/lib/dxvk.rs | 6 +- src/lib/game.rs | 17 +++- src/lib/wine.rs | 2 +- src/lib/wine_prefix.rs | 16 ++-- src/ui/preferences/enhancements.rs | 74 ++++++++++++++++-- src/ui/preferences/gamescope.rs | 24 ++++-- 16 files changed, 387 insertions(+), 122 deletions(-) create mode 100644 src/lib/config/game/wine/virtual_desktop.rs create mode 100644 src/lib/config/resolution.rs diff --git a/README.md b/README.md index 5dd5db0..746edb5 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ The launcher variant written on Rust, GTK4 and libadwaita, using [Anime Game Core](https://gitlab.com/an-anime-team/anime-game-core) library + diff --git a/assets/ui/preferences/enhancements.blp b/assets/ui/preferences/enhancements.blp index 9afeae2..7de83c7 100644 --- a/assets/ui/preferences/enhancements.blp +++ b/assets/ui/preferences/enhancements.blp @@ -23,6 +23,22 @@ Adw.PreferencesPage page { title: "Language"; subtitle: "Choose the language to use in wine environment. Can fix keyboard layout detection in-game"; } + + Adw.ActionRow { + title: "Borderless window"; + + Gtk.Switch borderless { + valign: center; + } + } + + Adw.ComboRow virtual_desktop_row { + title: "Virtual desktop"; + + Gtk.Switch virtual_desktop { + valign: center; + } + } } Adw.PreferencesGroup { diff --git a/assets/ui/preferences/gamescope.blp b/assets/ui/preferences/gamescope.blp index fbcc852..7f6b2ab 100644 --- a/assets/ui/preferences/gamescope.blp +++ b/assets/ui/preferences/gamescope.blp @@ -87,10 +87,18 @@ Adw.PreferencesWindow window { } } + Adw.ActionRow { + title: "FSR"; + + Gtk.Switch fsr { + valign: center; + } + } + Adw.ActionRow { title: "Nvidia Image Scaling"; - Gtk.Switch nvidia_image_scaling { + Gtk.Switch nis { valign: center; } } diff --git a/assets/wine.json b/assets/wine.json index 14a3a87..57e834b 100644 --- a/assets/wine.json +++ b/assets/wine.json @@ -9,7 +9,7 @@ "title": "Wine-GE-Proton 7-24", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-24/wine-lutris-GE-Proton7-24-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -22,7 +22,7 @@ "title": "Wine-GE-Proton 7-23", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-23/wine-lutris-GE-Proton7-23-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -35,7 +35,7 @@ "title": "Wine-GE-Proton 7-22", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-22/wine-lutris-GE-Proton7-22-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -48,7 +48,7 @@ "title": "Wine-GE-Proton 7-20", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-20/wine-lutris-GE-Proton7-20-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -61,7 +61,7 @@ "title": "Wine-GE-Proton 7-18", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-18/wine-lutris-GE-Proton7-18-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -74,7 +74,7 @@ "title": "Wine-GE-Proton 7-16", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-16/wine-lutris-GE-Proton7-16-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -87,7 +87,7 @@ "title": "Wine-GE-Proton 7-15", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-15/wine-lutris-GE-Proton7-15-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -100,7 +100,7 @@ "title": "Wine-GE-Proton 7-14", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-14/wine-lutris-GE-Proton7-14-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -113,7 +113,7 @@ "title": "Wine-GE-Proton 7-12", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-12/wine-lutris-GE-Proton7-12-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -126,7 +126,7 @@ "title": "Wine-GE-Proton 7-11", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-11/wine-lutris-GE-Proton7-11-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -139,7 +139,7 @@ "title": "Wine-GE-Proton 7-10", "uri": "https://github.com/GloriousEggroll/wine-ge-custom/releases/download/GE-Proton7-10/wine-lutris-GE-Proton7-10-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -158,7 +158,7 @@ "title": "GE-Proton 7-28", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-28/GE-Proton7-28.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -171,7 +171,7 @@ "title": "GE-Proton 7-27", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-27/GE-Proton7-27.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -184,7 +184,7 @@ "title": "GE-Proton 7-26", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-26/GE-Proton7-26.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -197,7 +197,7 @@ "title": "GE-Proton 7-24", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-24/GE-Proton7-24.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -210,7 +210,7 @@ "title": "GE-Proton 7-20", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-20/GE-Proton7-20.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -223,7 +223,7 @@ "title": "GE-Proton 7-19", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-19/GE-Proton7-19.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -236,7 +236,7 @@ "title": "GE-Proton 7-18", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-18/GE-Proton7-18.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -249,7 +249,7 @@ "title": "GE-Proton 7-17", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-17/GE-Proton7-17.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -262,7 +262,7 @@ "title": "GE-Proton 7-16", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-16/GE-Proton7-16.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -275,7 +275,7 @@ "title": "GE-Proton 7-15", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-15/GE-Proton7-15.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -288,7 +288,7 @@ "title": "GE-Proton 7-13", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-13/GE-Proton7-13.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -301,7 +301,7 @@ "title": "GE-Proton 7-10", "uri": "https://github.com/GloriousEggroll/proton-ge-custom/releases/download/GE-Proton7-10/GE-Proton7-10.tar.gz", "files": { - "wine": "files/bin/wine64", + "wine64": "files/bin/wine64", "wineserver": "files/bin/wineserver", "wineboot": "files/bin/wineboot", "winecfg": "files/lib64/wine/x86_64-windows/winecfg.exe" @@ -320,7 +320,7 @@ "title": "Soda 7.0-2", "uri": "https://github.com/bottlesdevs/wine/releases/download/soda-7.0-2/soda-7.0-2-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib/wine/x86_64-windows/winecfg.exe" @@ -333,7 +333,7 @@ "title": "Soda 7.0-1", "uri": "https://github.com/bottlesdevs/wine/releases/download/soda-7.0-1/soda-7.0-1-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib/wine/x86_64-windows/winecfg.exe" @@ -346,7 +346,7 @@ "title": "Soda 7.0", "uri": "https://github.com/bottlesdevs/wine/releases/download/soda-7.0/soda-7.0-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib/wine/x86_64-windows/winecfg.exe" @@ -365,7 +365,7 @@ "title": "Lutris 7.2-2", "uri": "https://github.com/lutris/wine/releases/download/lutris-wine-7.2-2/wine-lutris-7.2-2-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -378,7 +378,7 @@ "title": "Lutris 7.2", "uri": "https://github.com/lutris/wine/releases/download/lutris-wine-7.2/wine-lutris-7.2-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -391,7 +391,7 @@ "title": "Lutris 7.1", "uri": "https://github.com/lutris/wine/releases/download/lutris-7.1/wine-lutris-7.1-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -404,7 +404,7 @@ "title": "Lutris 6.21-6", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.21-6/wine-lutris-6.21-6-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -417,7 +417,7 @@ "title": "Lutris 6.21-5", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.21-5/wine-lutris-6.21-5-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -430,7 +430,7 @@ "title": "Lutris 6.21-4", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.21-4/wine-lutris-6.21-4-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -443,7 +443,7 @@ "title": "Lutris 6.21-3", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.21-3/wine-lutris-6.21-3-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -456,7 +456,7 @@ "title": "Lutris 6.21-2", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.21-2/wine-lutris-6.21-2-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -469,7 +469,7 @@ "title": "Lutris 6.21", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.21/wine-lutris-6.21-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -482,7 +482,7 @@ "title": "Lutris 6.14-4", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.14-4/wine-lutris-6.14-4-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -495,7 +495,7 @@ "title": "Lutris 6.14-3", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.14-3/wine-lutris-6.14-3-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -508,7 +508,7 @@ "title": "Lutris 6.14-2", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.14-2/wine-lutris-6.14-2-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" @@ -521,7 +521,7 @@ "title": "Lutris 6.14", "uri": "https://github.com/lutris/wine/releases/download/lutris-6.14/wine-lutris-6.14-x86_64.tar.xz", "files": { - "wine": "bin/wine64", + "wine64": "bin/wine64", "wineserver": "bin/wineserver", "wineboot": "bin/wineboot", "winecfg": "lib64/wine/x86_64-windows/winecfg.exe" diff --git a/src/lib/config/game/enhancements/gamescope/mod.rs b/src/lib/config/game/enhancements/gamescope/mod.rs index 888496d..0e5783d 100644 --- a/src/lib/config/game/enhancements/gamescope/mod.rs +++ b/src/lib/config/game/enhancements/gamescope/mod.rs @@ -21,12 +21,13 @@ pub struct Gamescope { pub gamescope: Size, pub framerate: Framerate, pub integer_scaling: bool, - pub nvidia_image_scaling: bool, + pub fsr: bool, + pub nis: bool, pub window_type: WindowType } impl Gamescope { - pub fn get_command(&self, fsr_enabled: bool) -> Option { + pub fn get_command(&self) -> Option { // https://github.com/bottlesdevs/Bottles/blob/b908311348ed1184ead23dd76f9d8af41ff24082/src/backend/wine/winecommand.py#L478 if self.enabled { let mut gamescope = String::from("gamescope"); @@ -72,14 +73,14 @@ impl Gamescope { gamescope += " -n"; } - // Set NIS (Nvidia Image Scaling) support - if self.nvidia_image_scaling { - gamescope += " -Y"; + // Set FSR support + if self.fsr { + gamescope += " -U"; } - // Set FSR support (only if NIS is not enabled) - else if fsr_enabled { - gamescope += " -U"; + // Set NIS (Nvidia Image Scaling) support + if self.nis { + gamescope += " -Y"; } Some(gamescope) @@ -99,7 +100,8 @@ impl Default for Gamescope { gamescope: Size::default(), framerate: Framerate::default(), integer_scaling: true, - nvidia_image_scaling: false, + fsr: false, + nis: false, window_type: WindowType::default() } } @@ -135,9 +137,14 @@ impl From<&JsonValue> for Gamescope { None => default.integer_scaling }, - nvidia_image_scaling: match value.get("nvidia_image_scaling") { - Some(value) => value.as_bool().unwrap_or(default.nvidia_image_scaling), - None => default.nvidia_image_scaling + fsr: match value.get("fsr") { + Some(value) => value.as_bool().unwrap_or(default.fsr), + None => default.fsr + }, + + nis: match value.get("nis") { + Some(value) => value.as_bool().unwrap_or(default.nis), + None => default.nis }, window_type: match value.get("window_type") { diff --git a/src/lib/config/game/wine/mod.rs b/src/lib/config/game/wine/mod.rs index 7b8a57e..dcb4f19 100644 --- a/src/lib/config/game/wine/mod.rs +++ b/src/lib/config/game/wine/mod.rs @@ -5,11 +5,13 @@ use crate::lib::consts::launcher_dir; pub mod wine_sync; pub mod wine_lang; +pub mod virtual_desktop; pub mod prelude { pub use super::Wine; pub use super::wine_sync::WineSync; pub use super::wine_lang::WineLang; + pub use super::virtual_desktop::VirtualDesktop; } use prelude::*; @@ -20,7 +22,9 @@ pub struct Wine { pub builds: String, pub selected: Option, pub sync: WineSync, - pub language: WineLang + pub language: WineLang, + pub borderless: bool, + pub virtual_desktop: VirtualDesktop } impl Default for Wine { @@ -32,7 +36,9 @@ impl Default for Wine { builds: format!("{launcher_dir}/runners"), selected: None, sync: WineSync::default(), - language: WineLang::default() + language: WineLang::default(), + borderless: false, + virtual_desktop: VirtualDesktop::default() } } } @@ -74,6 +80,16 @@ impl From<&JsonValue> for Wine { language: match value.get("language") { Some(value) => WineLang::from(value), None => default.language + }, + + borderless: match value.get("borderless") { + Some(value) => value.as_bool().unwrap_or(default.borderless), + None => default.borderless + }, + + virtual_desktop: match value.get("virtual_desktop") { + Some(value) => VirtualDesktop::from(value), + None => default.virtual_desktop } } } diff --git a/src/lib/config/game/wine/virtual_desktop.rs b/src/lib/config/game/wine/virtual_desktop.rs new file mode 100644 index 0000000..82d2201 --- /dev/null +++ b/src/lib/config/game/wine/virtual_desktop.rs @@ -0,0 +1,60 @@ +use serde::{Serialize, Deserialize}; +use serde_json::Value as JsonValue; + +use crate::lib::config::prelude::*; + +#[derive(Debug, Clone, Copy, Serialize, Deserialize)] +pub struct VirtualDesktop { + pub enabled: bool, + pub width: u64, + pub height: u64 +} + +impl Default for VirtualDesktop { + fn default() -> Self { + Self { + enabled: false, + width: 1920, + height: 1080 + } + } +} + +impl From<&JsonValue> for VirtualDesktop { + fn from(value: &JsonValue) -> Self { + let default = Self::default(); + + Self { + enabled: match value.get("enabled") { + Some(value) => value.as_bool().unwrap_or(default.enabled), + None => default.enabled + }, + + width: match value.get("width") { + Some(value) => value.as_u64().unwrap_or(default.width), + None => default.width + }, + + height: match value.get("height") { + Some(value) => value.as_u64().unwrap_or(default.height), + None => default.height + } + } + } +} + +impl VirtualDesktop { + pub fn get_resolution(&self) -> Resolution { + Resolution::from_pair(self.width, self.height) + } + + pub fn get_command(&self) -> Option { + if self.enabled { + Some(format!("explorer /desktop=animegame,{}x{}", self.width, self.height)) + } + + else { + None + } + } +} diff --git a/src/lib/config/game/wine/wine_lang.rs b/src/lib/config/game/wine/wine_lang.rs index df69c1f..aa01091 100644 --- a/src/lib/config/game/wine/wine_lang.rs +++ b/src/lib/config/game/wine/wine_lang.rs @@ -1,3 +1,5 @@ +use gtk4 as gtk; + use std::collections::HashMap; use serde::{Serialize, Deserialize}; @@ -30,12 +32,6 @@ impl From<&JsonValue> for WineLang { } } -impl Into for WineLang { - fn into(self) -> String { - format!("{:?}", self) - } -} - impl Into for WineLang { fn into(self) -> u32 { for (i, lang) in Self::list().into_iter().enumerate() { @@ -65,6 +61,20 @@ impl WineLang { ] } + pub fn get_model() -> gtk::StringList { + let model = gtk::StringList::new(&[]); + + for lang in Self::list() { + model.append(&lang.to_string()); + } + + model + } + + pub fn to_string(&self) -> String { + format!("{:?}", self) + } + /// Get environment variables corresponding to used wine language pub fn get_env_vars(&self) -> HashMap<&str, &str> { HashMap::from([("LANG", match self { diff --git a/src/lib/config/mod.rs b/src/lib/config/mod.rs index 4a32224..4fe5465 100644 --- a/src/lib/config/mod.rs +++ b/src/lib/config/mod.rs @@ -16,17 +16,19 @@ use super::wine::{ pub mod launcher; pub mod game; pub mod patch; +pub mod resolution; pub mod prelude { pub use super::launcher::prelude::*; pub use super::game::prelude::*; pub use super::patch::Patch; + pub use super::resolution::Resolution; } use prelude::*; -static mut CONFIG: Option = None; +static mut CONFIG: Option = None; /// Get config data /// @@ -130,41 +132,6 @@ pub struct Config { } impl Config { - /// Try to get a path to the wine executable based on `game.wine.builds` and `game.wine.selected` - /// - /// Returns `Some("wine")` if: - /// 1) `game.wine.selected = None` - /// 2) wine installed and available in system - pub fn try_get_wine_executable(&self) -> Option { - match &self.game.wine.selected { - Some(selected) => { - // Most of wine builds - let path = format!("{}/{}/bin/wine", &self.game.wine.builds, &selected); - - if Path::new(&path).exists() { - return Some(path); - } - - // Proton-based builds - let path = format!("{}/{}/files/bin/wine", &self.game.wine.builds, &selected); - - if Path::new(&path).exists() { - return Some(path); - } - - // ???? - None - }, - None => { - if lib::is_available("wine") { - Some(String::from("wine")) - } else { - None - } - } - } - } - pub fn try_get_selected_wine_info(&self) -> Option { match &self.game.wine.selected { Some(selected) => { @@ -186,6 +153,24 @@ impl Config { None => None } } + + /// Try to get a path to the wine64 executable based on `game.wine.builds` and `game.wine.selected` + /// + /// Returns `Some("wine64")` if: + /// 1) `game.wine.selected = None` + /// 2) wine64 installed and available in system + pub fn try_get_wine_executable(&self) -> Option { + match self.try_get_selected_wine_info() { + Some(selected) => Some(format!("{}/{}/{}", &self.game.wine.builds, selected.name, selected.files.wine64)), + None => { + if lib::is_available("wine64") { + Some(String::from("wine64")) + } else { + None + } + } + } + } } impl From<&JsonValue> for Config { diff --git a/src/lib/config/resolution.rs b/src/lib/config/resolution.rs new file mode 100644 index 0000000..8d97d58 --- /dev/null +++ b/src/lib/config/resolution.rs @@ -0,0 +1,75 @@ +use gtk4 as gtk; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] +pub enum Resolution { + // qHD; 960x540 + MiniHD, + + // 1280x720 + HD, + + // 1920x1080 + FullHD, + + // 2560x1440 + QuadHD, + + // 3840x2160 + UltraHD, + + Custom(u64, u64) +} + +impl Resolution { + pub fn list() -> Vec { + vec![ + Self::MiniHD, + Self::HD, + Self::FullHD, + Self::QuadHD, + Self::UltraHD + ] + } + + pub fn get_model() -> gtk::StringList { + let model = gtk::StringList::new(&[]); + + model.append("Custom"); + + for res in Self::list() { + model.append(&res.to_string()); + } + + model + } + + pub fn from_pair(width: u64, height: u64) -> Self { + for res in Self::list() { + let pair = res.get_pair(); + + if pair.0 == width && pair.1 == height { + return res; + } + } + + Self::Custom(width, height) + } + + pub fn get_pair(&self) -> (u64, u64) { + match self { + Self::MiniHD => (960, 540), + Self::HD => (1280, 720), + Self::FullHD => (1920, 1080), + Self::QuadHD => (2560, 1440), + Self::UltraHD => (3840, 2160), + + Self::Custom(w, h) => (*w, *h) + } + } + + pub fn to_string(&self) -> String { + let (w, h) = self.get_pair(); + + format!("{w}x{h}") + } +} diff --git a/src/lib/dxvk.rs b/src/lib/dxvk.rs index 420a358..080cc8e 100644 --- a/src/lib/dxvk.rs +++ b/src/lib/dxvk.rs @@ -75,7 +75,7 @@ impl Version { match config.try_get_selected_wine_info() { Some(wine) => { - let wine_path = format!("{}/{}/{}", &config.game.wine.builds, wine.name, wine.files.wine); + let wine_path = format!("{}/{}/{}", &config.game.wine.builds, wine.name, wine.files.wine64); let wineserver_path = format!("{}/{}/{}", &config.game.wine.builds, wine.name, wine.files.wineserver); let wineboot_path = format!("{}/{}/{}", &config.game.wine.builds, wine.name, wine.files.wineboot); @@ -92,6 +92,10 @@ impl Version { apply_script = WINE64.replace_all(&apply_script, &format!("wine64=\"{}\"", &wine_path)).to_string(); apply_script = WINEBOOT.replace_all(&apply_script, &format!("wineboot=\"{}\"", &wineboot_path)).to_string(); + // Use wine64 to update wine prefix instead of running wineboot + // so we can get rid of 32bit support + apply_script = apply_script.replace("$wineboot -u", "$wine64 -u"); + // Old GE builds return specific --version output which can break // DXVK installation script apply_script = apply_script.replace("grep wine", "grep \"wine\\|GE\""); diff --git a/src/lib/game.rs b/src/lib/game.rs index 070ad6e..28f023e 100644 --- a/src/lib/game.rs +++ b/src/lib/game.rs @@ -92,14 +92,27 @@ pub fn run(debug: bool) -> std::io::Result<()> { bash_chain += &format!("'{wine_executable}' "); + if let Some(virtual_desktop) = config.game.wine.virtual_desktop.get_command() { + bash_chain += &format!("{virtual_desktop} "); + } + if debug { todo!(); } else { - bash_chain += "launcher.bat"; + bash_chain += "launcher.bat "; + } + + if config.game.wine.borderless { + bash_chain += "-screen-fullscreen 0 -popupwindow "; + } + + // https://notabug.org/Krock/dawn/src/master/TWEAKS.md + if config.game.enhancements.fsr.enabled { + bash_chain += "-window-mode exclusive "; } // gamescope -- - if let Some(gamescope) = config.game.enhancements.gamescope.get_command(config.game.enhancements.fsr.enabled) { + if let Some(gamescope) = config.game.enhancements.gamescope.get_command() { bash_chain = format!("{gamescope} -- {bash_chain}"); } diff --git a/src/lib/wine.rs b/src/lib/wine.rs index bd1e2dd..bb0aac5 100644 --- a/src/lib/wine.rs +++ b/src/lib/wine.rs @@ -64,7 +64,7 @@ impl Version { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Files { - pub wine: String, + pub wine64: String, pub wineserver: String, pub wineboot: String, pub winecfg: String diff --git a/src/lib/wine_prefix.rs b/src/lib/wine_prefix.rs index 2a87b30..97c2cc0 100644 --- a/src/lib/wine_prefix.rs +++ b/src/lib/wine_prefix.rs @@ -15,13 +15,13 @@ impl WinePrefix { Path::new(&format!("{}/drive_c", self.path)).exists() } - fn wineboot(&self, runners_folder: T, runner: super::wine::Version, command: &str) -> std::io::Result { + fn wine(&self, runners_folder: T, runner: super::wine::Version, command: &str) -> std::io::Result { let runners_folder = runners_folder.to_string(); - let wineboot = format!("{}/{}/{}", &runners_folder, runner.name, runner.files.wineboot); + let wine = format!("{}/{}/{}", &runners_folder, runner.name, runner.files.wine64); let wineserver = format!("{}/{}/{}", &runners_folder, runner.name, runner.files.wineserver); - let mut wineboot = Command::new(wineboot); + let mut wineboot = Command::new(wine); wineboot.env("WINEARCH", "win64") .env("WINESERVER", wineserver) @@ -32,22 +32,22 @@ impl WinePrefix { } pub fn update(&self, runners_folder: T, runner: super::wine::Version) -> std::io::Result { - self.wineboot(runners_folder, runner, "-u") + self.wine(runners_folder, runner, "-u") } pub fn end(&self, runners_folder: T, runner: super::wine::Version) -> std::io::Result { - self.wineboot(runners_folder, runner, "-e") + self.wine(runners_folder, runner, "-e") } pub fn kill(&self, runners_folder: T, runner: super::wine::Version) -> std::io::Result { - self.wineboot(runners_folder, runner, "-k") + self.wine(runners_folder, runner, "-k") } pub fn restart(&self, runners_folder: T, runner: super::wine::Version) -> std::io::Result { - self.wineboot(runners_folder, runner, "-r") + self.wine(runners_folder, runner, "-r") } pub fn shutdown(&self, runners_folder: T, runner: super::wine::Version) -> std::io::Result { - self.wineboot(runners_folder, runner, "-s") + self.wine(runners_folder, runner, "-s") } } diff --git a/src/ui/preferences/enhancements.rs b/src/ui/preferences/enhancements.rs index b8c4d24..321790c 100644 --- a/src/ui/preferences/enhancements.rs +++ b/src/ui/preferences/enhancements.rs @@ -23,6 +23,9 @@ pub struct AppWidgets { pub sync_combo: adw::ComboRow, pub wine_lang: adw::ComboRow, + pub borderless: gtk::Switch, + pub virtual_desktop_row: adw::ComboRow, + pub virtual_desktop: gtk::Switch, pub hud_combo: adw::ComboRow, pub fsr_combo: adw::ComboRow, @@ -47,6 +50,9 @@ impl AppWidgets { sync_combo: get_object(&builder, "sync_combo")?, wine_lang: get_object(&builder, "wine_lang")?, + borderless: get_object(&builder, "borderless")?, + virtual_desktop_row: get_object(&builder, "virtual_desktop_row")?, + virtual_desktop: get_object(&builder, "virtual_desktop")?, hud_combo: get_object(&builder, "hud_combo")?, fsr_combo: get_object(&builder, "fsr_combo")?, @@ -63,15 +69,10 @@ impl AppWidgets { }; // Set availale wine languages - let model = gtk::StringList::new(&[]); + result.wine_lang.set_model(Some(&WineLang::get_model())); - for lang in WineLang::list() { - let lang: String = lang.into(); - - model.append(&lang); - } - - result.wine_lang.set_model(Some(&model)); + // Set availale virtual desktop resolutions + result.virtual_desktop_row.set_model(Some(&Resolution::get_model())); // Disable gamemode row if it's not available if !lib::is_available("gamemoderun") { @@ -135,6 +136,40 @@ impl App { } }); + // Borderless switching + self.widgets.borderless.connect_state_notify(move |switch| { + if let Ok(mut config) = config::get() { + config.game.wine.borderless = switch.state(); + + config::update(config); + } + }); + + // Virtual desktop resolution selection + self.widgets.virtual_desktop_row.connect_selected_notify(move |row| { + if let Ok(mut config) = config::get() { + let resolutions = Resolution::list(); + + if row.selected() > 0 { + let (w, h) = resolutions[row.selected() as usize - 1].get_pair(); + + config.game.wine.virtual_desktop.width = w; + config.game.wine.virtual_desktop.height = h; + + config::update(config); + } + } + }); + + // Virtual desktop switching + self.widgets.virtual_desktop.connect_state_notify(move |switch| { + if let Ok(mut config) = config::get() { + config.game.wine.virtual_desktop.enabled = switch.state(); + + config::update(config); + } + }); + // HUD selection self.widgets.hud_combo.connect_selected_notify(move |row| { if let Ok(mut config) = config::get() { @@ -215,6 +250,29 @@ impl App { // Update wine language self.widgets.wine_lang.set_selected(config.game.wine.language.into()); + // Update borderless + self.widgets.borderless.set_state(config.game.wine.borderless); + + // Update virtual desktop + self.widgets.virtual_desktop.set_state(config.game.wine.virtual_desktop.enabled); + + let resolution = Resolution::from_pair( + config.game.wine.virtual_desktop.width, + config.game.wine.virtual_desktop.height + ); + + if let Resolution::Custom(_, _) = resolution { + self.widgets.virtual_desktop_row.set_selected(0); + } + + else { + for (i, res) in Resolution::list().into_iter().enumerate() { + if res == resolution { + self.widgets.virtual_desktop_row.set_selected(i as u32 + 1); + } + } + } + // Update HUD self.widgets.hud_combo.set_selected(config.game.enhancements.hud.into()); diff --git a/src/ui/preferences/gamescope.rs b/src/ui/preferences/gamescope.rs index 41677bb..3bd6358 100644 --- a/src/ui/preferences/gamescope.rs +++ b/src/ui/preferences/gamescope.rs @@ -26,7 +26,8 @@ pub struct AppWidgets { pub framerate_limit: gtk::Entry, pub framerate_unfocused_limit: gtk::Entry, pub integer_scaling: gtk::Switch, - pub nvidia_image_scaling: gtk::Switch, + pub fsr: gtk::Switch, + pub nis: gtk::Switch, pub borderless: gtk::ToggleButton, pub fullscreen: gtk::ToggleButton @@ -48,7 +49,8 @@ impl AppWidgets { framerate_limit: get_object(&builder, "framerate_limit")?, framerate_unfocused_limit: get_object(&builder, "framerate_unfocused_limit")?, integer_scaling: get_object(&builder, "integer_scaling")?, - nvidia_image_scaling: get_object(&builder, "nvidia_image_scaling")?, + fsr: get_object(&builder, "nis")?, + nis: get_object(&builder, "nis")?, borderless: get_object(&builder, "borderless")?, fullscreen: get_object(&builder, "fullscreen")? @@ -151,10 +153,19 @@ impl App { } }); - // Use NIS (Nvidia Image Scaling) - self.widgets.nvidia_image_scaling.connect_state_notify(move |switch| { + // Use FSR + self.widgets.fsr.connect_state_notify(move |switch| { if let Ok(mut config) = config::get() { - config.game.enhancements.gamescope.nvidia_image_scaling = switch.state(); + config.game.enhancements.gamescope.fsr = switch.state(); + + config::update(config); + } + }); + + // Use NIS (Nvidia Image Scaling) + self.widgets.nis.connect_state_notify(move |switch| { + if let Ok(mut config) = config::get() { + config.game.enhancements.gamescope.nis = switch.state(); config::update(config); } @@ -230,7 +241,8 @@ impl App { set_text(&self.widgets.framerate_unfocused_limit, config.game.enhancements.gamescope.framerate.unfocused); self.widgets.integer_scaling.set_state(config.game.enhancements.gamescope.integer_scaling); - self.widgets.nvidia_image_scaling.set_state(config.game.enhancements.gamescope.nvidia_image_scaling); + self.widgets.fsr.set_state(config.game.enhancements.gamescope.fsr); + self.widgets.nis.set_state(config.game.enhancements.gamescope.nis); match config.game.enhancements.gamescope.window_type { WindowType::Borderless => self.widgets.borderless.set_active(true),