From 911af1f635bb3d038ac38f04533dc5f0d690418a Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Sun, 21 May 2023 20:26:18 +0200 Subject: [PATCH] feat: initial enhancement settings rework - removed Futex2 - added setting of `LC_ALL` in wine lang setting - enabled fsr by default - added support of fsr qualities - added initial support of wine shared libraries --- Cargo.toml | 2 +- src/config/schema_blanks/fsr.rs | 66 ++++++++++++- src/config/schema_blanks/wine/mod.rs | 15 ++- .../schema_blanks/wine/shared_libraries.rs | 94 +++++++++++++++++++ src/config/schema_blanks/wine/wine_lang.rs | 9 +- src/config/schema_blanks/wine/wine_sync.rs | 14 +-- 6 files changed, 182 insertions(+), 18 deletions(-) create mode 100644 src/config/schema_blanks/wine/shared_libraries.rs diff --git a/Cargo.toml b/Cargo.toml index 48e06be..d9589b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies.anime-game-core] git = "https://github.com/an-anime-team/anime-game-core" -tag = "1.10.0" +tag = "1.10.1" features = ["all"] # path = "../anime-game-core" # ! for dev purposes only diff --git a/src/config/schema_blanks/fsr.rs b/src/config/schema_blanks/fsr.rs index 8018687..cbbf083 100644 --- a/src/config/schema_blanks/fsr.rs +++ b/src/config/schema_blanks/fsr.rs @@ -3,9 +3,41 @@ use std::collections::HashMap; use serde::{Serialize, Deserialize}; use serde_json::Value as JsonValue; +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum FsrQuality { + Default, + + /// `WINE_FULLSCREEN_FSR_MODE=ultra` + Ultra, + + /// `WINE_FULLSCREEN_FSR_MODE=quality` + Quality, + + /// `WINE_FULLSCREEN_FSR_MODE=balanced` + Balanced, + + /// `WINE_FULLSCREEN_FSR_MODE=performance` + Performance +} + +impl Default for FsrQuality { + #[inline] + fn default() -> Self { + Self::Default + } +} + +impl From<&JsonValue> for FsrQuality { + #[inline] + fn from(value: &JsonValue) -> Self { + serde_json::from_value(value.clone()).unwrap_or_default() + } +} + #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] pub struct Fsr { pub strength: u64, + pub quality: FsrQuality, pub enabled: bool } @@ -14,7 +46,8 @@ impl Default for Fsr { fn default() -> Self { Self { strength: 2, - enabled: false + quality: FsrQuality::default(), + enabled: true } } } @@ -29,6 +62,11 @@ impl From<&JsonValue> for Fsr { None => default.strength }, + quality: match value.get("quality") { + Some(value) => FsrQuality::from(value), + None => default.quality + }, + enabled: match value.get("enabled") { Some(value) => value.as_bool().unwrap_or(default.enabled), None => default.enabled @@ -41,14 +79,32 @@ impl Fsr { /// Get environment variables corresponding to used amd fsr options pub fn get_env_vars(&self) -> HashMap<&str, String> { if self.enabled { - HashMap::from([ + let mut env = HashMap::from([ ("WINE_FULLSCREEN_FSR", String::from("1")), ("WINE_FULLSCREEN_FSR_STRENGTH", self.strength.to_string()) - ]) + ]); + + // Set FSR quality mode if some is selected + // https://github.com/GloriousEggroll/wine-ge-custom/releases/tag/GE-Proton7-25 + if self.quality != FsrQuality::Default { + env.insert("WINE_FULLSCREEN_FSR_MODE", match self.quality { + FsrQuality::Default => String::from("balanced"), + FsrQuality::Ultra => String::from("ultra"), + FsrQuality::Quality => String::from("quality"), + FsrQuality::Balanced => String::from("balanced"), + FsrQuality::Performance => String::from("performance") + }); + } + + env } - + else { - HashMap::new() + // FSR is enabled by default, so if it's disabled in the launcher + // I should use this variable to really disable it + HashMap::from([ + ("WINE_FULLSCREEN_FSR", String::from("0")) + ]) } } } diff --git a/src/config/schema_blanks/wine/mod.rs b/src/config/schema_blanks/wine/mod.rs index 1251533..cba95aa 100644 --- a/src/config/schema_blanks/wine/mod.rs +++ b/src/config/schema_blanks/wine/mod.rs @@ -1,11 +1,13 @@ pub mod wine_lang; pub mod wine_sync; pub mod virtual_desktop; +pub mod shared_libraries; pub mod prelude { pub use super::wine_lang::WineLang; pub use super::wine_sync::WineSync; pub use super::virtual_desktop::VirtualDesktop; + pub use super::shared_libraries::SharedLibraries; } #[macro_export] @@ -19,7 +21,8 @@ macro_rules! config_impl_wine_schema { pub sync: WineSync, pub language: WineLang, pub borderless: bool, - pub virtual_desktop: VirtualDesktop + pub virtual_desktop: VirtualDesktop, + pub shared_libraries: SharedLibraries } impl Default for Wine { @@ -34,7 +37,8 @@ macro_rules! config_impl_wine_schema { sync: WineSync::default(), language: WineLang::default(), borderless: false, - virtual_desktop: VirtualDesktop::default() + virtual_desktop: VirtualDesktop::default(), + shared_libraries: SharedLibraries::default() } } } @@ -92,7 +96,12 @@ macro_rules! config_impl_wine_schema { virtual_desktop: match value.get("virtual_desktop") { Some(value) => VirtualDesktop::from(value), None => default.virtual_desktop - } + }, + + shared_libraries: match value.get("shared_libraries") { + Some(value) => SharedLibraries::from(value), + None => default.shared_libraries + }, } } } diff --git a/src/config/schema_blanks/wine/shared_libraries.rs b/src/config/schema_blanks/wine/shared_libraries.rs new file mode 100644 index 0000000..37ffec3 --- /dev/null +++ b/src/config/schema_blanks/wine/shared_libraries.rs @@ -0,0 +1,94 @@ +use std::collections::HashMap; +use std::path::PathBuf; + +use serde::{Serialize, Deserialize}; +use serde_json::Value as JsonValue; + +// https://github.com/bottlesdevs/Bottles/blob/8d4cb54e4645166e21fec7b0686dbdb89e0fd2c2/bottles/backend/wine/winecommand.py#L228 + +const WINE_LIBS: &[&str] = &[ + "lib", + "lib64", + "lib/wine/x86_64-unix", + "lib32/wine/x86_64-unix", + "lib64/wine/x86_64-unix", + "lib/wine/i386-unix", + "lib32/wine/i386-unix", + "lib64/wine/i386-unix" +]; + +const GST_LIBS: &[&str] = &[ + "lib64/gstreamer-1.0", + "lib/gstreamer-1.0", + "lib32/gstreamer-1.0" +]; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub struct SharedLibraries { + /// Set `LD_LIBRARY_PATH` variable with paths to the wine shared libraries + pub wine: bool, + + /// Set `GST_PLUGIN_PATH` variable with paths to gstreamer shared libraries + /// + /// https://gstreamer.freedesktop.org/documentation/gstreamer/gstregistry.html?gi-language=c + pub gstreamer: bool +} + +impl Default for SharedLibraries { + #[inline] + fn default() -> Self { + Self { + wine: true, + gstreamer: true + } + } +} + +impl From<&JsonValue> for SharedLibraries { + #[inline] + fn from(value: &JsonValue) -> Self { + serde_json::from_value(value.clone()).unwrap_or_default() + } +} + +impl SharedLibraries { + /// Get environment variables corresponding to selected shared variables options + pub fn get_env_vars(&self, wine_folder: impl Into) -> HashMap<&str, String> { + let mut env = HashMap::new(); + let wine_folder: PathBuf = wine_folder.into(); + + // Setup `LD_LIBRARY_PATH` + + if self.wine { + let mut ld_libs = Vec::with_capacity(WINE_LIBS.len()); + + for folder in WINE_LIBS { + let folder = wine_folder.join(folder); + + if folder.exists() { + ld_libs.push(folder.to_string_lossy().to_string()); + } + } + + env.insert("LD_LIBRARY_PATH", ld_libs.join(":")); + } + + // Setup `GST_PLUGIN_PATH` + + if self.gstreamer { + let mut gst_libs = Vec::with_capacity(GST_LIBS.len()); + + for folder in GST_LIBS { + let folder = wine_folder.join(folder); + + if folder.exists() { + gst_libs.push(folder.to_string_lossy().to_string()); + } + } + + env.insert("GST_PLUGIN_PATH", gst_libs.join(":")); + } + + env + } +} diff --git a/src/config/schema_blanks/wine/wine_lang.rs b/src/config/schema_blanks/wine/wine_lang.rs index 20e1901..1601c7f 100644 --- a/src/config/schema_blanks/wine/wine_lang.rs +++ b/src/config/schema_blanks/wine/wine_lang.rs @@ -37,7 +37,7 @@ impl From<&JsonValue> for WineLang { impl WineLang { /// Get environment variables corresponding to used wine language pub fn get_env_vars(&self) -> HashMap<&str, &str> { - HashMap::from([("LANG", match self { + let lang = match self { Self::System => return HashMap::new(), Self::English => "en_US.UTF-8", @@ -50,7 +50,12 @@ impl WineLang { Self::Chinese => "zh_CN.UTF-8", Self::Japanese => "ja_JP.UTF-8", Self::Korean => "ko_KR.UTF-8" - })]) + }; + + HashMap::from([ + ("LANG", lang), + ("LC_ALL", lang) + ]) } } diff --git a/src/config/schema_blanks/wine/wine_sync.rs b/src/config/schema_blanks/wine/wine_sync.rs index b7e4f58..9fabb78 100644 --- a/src/config/schema_blanks/wine/wine_sync.rs +++ b/src/config/schema_blanks/wine/wine_sync.rs @@ -9,8 +9,7 @@ use enum_ordinalize::Ordinalize; pub enum WineSync { None, ESync, - FSync, - Futex2 + FSync } impl Default for WineSync { @@ -30,12 +29,13 @@ impl From<&JsonValue> for WineSync { impl WineSync { /// Get environment variables corresponding to used wine sync pub fn get_env_vars(&self) -> HashMap<&str, &str> { - HashMap::from([(match self { + let key = match self { Self::None => return HashMap::new(), - Self::ESync => "WINEESYNC", - Self::FSync => "WINEFSYNC", - Self::Futex2 => "WINEFSYNC_FUTEX2" - }, "1")]) + Self::ESync => "WINEESYNC", + Self::FSync => "WINEFSYNC" + }; + + HashMap::from([(key, "1")]) } }