From e47af5264697e67753ed71b37c08d224bca0922b Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Thu, 9 Mar 2023 15:00:36 +0200 Subject: [PATCH] feat: added experimental `compact_launch` wine feature --- src/components/wine.rs | 11 +++++++ src/config/game/wine/virtual_desktop.rs | 1 + src/game.rs | 43 +++++++++++++++---------- 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/components/wine.rs b/src/components/wine.rs index b03c558..1f826f8 100644 --- a/src/components/wine.rs +++ b/src/components/wine.rs @@ -37,6 +37,11 @@ pub struct Features { /// Whether this wine group needs DXVK pub need_dxvk: bool, + /// Create temp bat file with `launcher.bat` call and its flags + /// + /// Extremely helpful when your custom `command` feature can't handle multiline arguments (e.g. in GE-Proton) + pub compact_launch: bool, + /// Command used to launch the game /// /// Available keywords: @@ -62,6 +67,7 @@ impl Default for Features { fn default() -> Self { Self { need_dxvk: true, + compact_launch: false, command: None, env: HashMap::new() } @@ -78,6 +84,11 @@ impl From<&JsonValue> for Features { None => default.need_dxvk }, + compact_launch: match value.get("compact_launch") { + Some(value) => value.as_bool().unwrap_or(default.compact_launch), + None => default.compact_launch + }, + command: match value.get("command") { Some(value) => value.as_str().map(|value| value.to_string()), None => default.command diff --git a/src/config/game/wine/virtual_desktop.rs b/src/config/game/wine/virtual_desktop.rs index ed84686..21a9f8e 100644 --- a/src/config/game/wine/virtual_desktop.rs +++ b/src/config/game/wine/virtual_desktop.rs @@ -48,6 +48,7 @@ impl VirtualDesktop { Resolution::from_pair(self.width, self.height) } + /// `explorer /desktop=animegame,[width]x[height]` pub fn get_command(&self) -> Option { if self.enabled { Some(format!("explorer /desktop=animegame,{}x{}", self.width, self.height)) diff --git a/src/game.rs b/src/game.rs index d988b74..66fa88e 100644 --- a/src/game.rs +++ b/src/game.rs @@ -89,7 +89,7 @@ pub fn run() -> anyhow::Result<()> { return Err(anyhow::anyhow!("Failed to update FPS unlocker config: {err}")); } - let bat_path = config.game.path.join("fpsunlocker.bat"); + let bat_path = config.game.path.join("fps_unlocker.bat"); let original_bat_path = config.game.path.join("launcher.bat"); // Generate fpsunlocker.bat from launcher.bat @@ -100,10 +100,11 @@ pub fn run() -> anyhow::Result<()> { // Prepare bash -c '' - let mut bash_chain = String::new(); + let mut bash_command = String::new(); + let mut windows_command = String::new(); if config.game.enhancements.gamemode { - bash_chain += "gamemoderun "; + bash_command += "gamemoderun "; } let wine_build = config.game.wine.builds.join(&wine.name); @@ -112,42 +113,50 @@ pub fn run() -> anyhow::Result<()> { .map(|command| replace_keywords(command, &config)) .unwrap_or(format!("'{}'", wine_build.join(wine.files.wine64.unwrap_or(wine.files.wine)).to_string_lossy())); - bash_chain += &run_command; - bash_chain += " "; + bash_command += &run_command; + bash_command += " "; if let Some(virtual_desktop) = config.game.wine.virtual_desktop.get_command() { - bash_chain += &format!("{virtual_desktop} "); + windows_command += &virtual_desktop; + windows_command += " "; } - bash_chain += if config.game.enhancements.fps_unlocker.enabled && cfg!(feature = "fps-unlocker") { - "fpsunlocker.bat " + windows_command += if config.game.enhancements.fps_unlocker.enabled && cfg!(feature = "fps-unlocker") { + "fps_unlocker.bat " } else { "launcher.bat " }; if config.game.wine.borderless { - bash_chain += "-screen-fullscreen 0 -popupwindow "; + windows_command += "-screen-fullscreen 0 -popupwindow "; } // https://notabug.org/Krock/dawn/src/master/TWEAKS.md if config.game.enhancements.fsr.enabled { - bash_chain += "-window-mode exclusive "; + windows_command += "-window-mode exclusive "; } // gamescope -- if let Some(gamescope) = config.game.enhancements.gamescope.get_command() { - bash_chain = format!("{gamescope} -- {bash_chain}"); + bash_command = format!("{gamescope} -- {bash_command}"); } - let bash_chain = match &config.game.command { - Some(command) => replace_keywords(command, &config).replace("%command%", &bash_chain), - None => bash_chain - }; + // Bundle all windows arguments used to run the game into a single file + if features.compact_launch { + std::fs::write(config.game.path.join("compact_launch.bat"), format!("start {}\nexit", windows_command))?; + + windows_command = String::from("compact_launch.bat"); + } + + let bash_command = match &config.game.command { + Some(command) => replace_keywords(command, &config).replace("%command%", &bash_command), + None => bash_command + } + &windows_command; let mut command = Command::new("bash"); command.arg("-c"); - command.arg(&bash_chain); + command.arg(&bash_command); // Setup environment @@ -188,7 +197,7 @@ pub fn run() -> anyhow::Result<()> { .map(|(key, value)| format!("{}=\"{}\"", key.to_string_lossy(), value.unwrap_or_default().to_string_lossy())) .fold(String::new(), |acc, env| acc + " " + &env); - tracing::info!("Running the game with command: {variables} bash -c \"{bash_chain}\""); + tracing::info!("Running the game with command: {variables} bash -c \"{bash_command}\""); command.current_dir(config.game.path).spawn()?.wait_with_output()?;