From bf4c06ee2df1dae49c7d2277dfc2b8f8d621965f Mon Sep 17 00:00:00 2001 From: akanyan Date: Wed, 23 Apr 2025 17:17:59 +0200 Subject: [PATCH] fix: begin fixing linux support --- rust/src/cmd.rs | 11 ++++++--- rust/src/model/profile.rs | 5 +++- rust/src/modules/display_linux.rs | 8 +++++++ rust/src/modules/mod.rs | 5 +++- rust/src/profiles/mod.rs | 25 ++++++++++++++++---- rust/src/util.rs | 1 + src/components/App.vue | 1 - src/components/ProfileList.vue | 8 +++++++ src/components/StartButton.vue | 29 ++++++++++++++++++------ src/components/options/Display.vue | 27 ++++++++++++++-------- src/components/options/Segatools.vue | 34 +++++++++++++++++++++++++++- src/i18n/en.ts | 5 +++- src/types.ts | 6 +++++ 13 files changed, 135 insertions(+), 30 deletions(-) create mode 100644 rust/src/modules/display_linux.rs diff --git a/rust/src/cmd.rs b/rust/src/cmd.rs index a091bcc..05878cb 100644 --- a/rust/src/cmd.rs +++ b/rust/src/cmd.rs @@ -75,6 +75,7 @@ pub async fn startline(app: AppHandle, refresh: bool) -> Result<(), String> { &p.data.sgt.target.parent().unwrap().join("amdaemon.exe") ).map_err(|e| e.to_string())?; + #[cfg(target_os = "windows")] let info = p.prepare_display() .map_err(|e| e.to_string())?; let lineup_res = p.line_up(hash, refresh, patches_enabled).await @@ -408,10 +409,14 @@ pub async fn load_segatools_ini(state: State<'_, Mutex>, path: PathBuf) } #[tauri::command] -pub async fn create_shortcut(app: AppHandle, profile_meta: ProfileMeta) -> Result<(), String> { +pub async fn create_shortcut(_app: AppHandle, profile_meta: ProfileMeta) -> Result<(), String> { log::debug!("invoke: create_shortcut({:?})", profile_meta); - util::create_shortcut(app, &profile_meta).map_err(|e| e.to_string()) + #[cfg(target_os = "windows")] + return util::create_shortcut(_app, &profile_meta).map_err(|e| e.to_string()); + + #[cfg(not(target_os = "windows"))] + return Err("unsupported".to_owned()); } #[tauri::command] @@ -466,7 +471,7 @@ pub async fn list_platform_capabilities() -> Result, ()> { log::debug!("invoke: list_platform_capabilities"); #[cfg(target_os = "windows")] - return Ok(vec!["display".to_owned()]); + return Ok(vec!["display".to_owned(), "shortcut".to_owned(), "chunithm".to_owned()]); #[cfg(target_os = "linux")] return Ok(vec!["wine".to_owned()]); diff --git a/rust/src/model/profile.rs b/rust/src/model/profile.rs index 4ce819a..5c16776 100644 --- a/rust/src/model/profile.rs +++ b/rust/src/model/profile.rs @@ -108,7 +108,10 @@ impl Display { Game::Ongeki => 60, }, borderless_fullscreen: true, + #[cfg(target_os = "windows")] dont_switch_primary: false, + #[cfg(not(target_os = "windows"))] + dont_switch_primary: true, monitor_index_override: None, } } @@ -141,7 +144,7 @@ pub struct BepInEx { pub console: bool, } -#[derive(Deserialize, Serialize, Clone)] +#[derive(Deserialize, Serialize, Clone, Debug)] #[serde(default)] pub struct Wine { pub runtime: PathBuf, diff --git a/rust/src/modules/display_linux.rs b/rust/src/modules/display_linux.rs new file mode 100644 index 0000000..b3b5d52 --- /dev/null +++ b/rust/src/modules/display_linux.rs @@ -0,0 +1,8 @@ +use ini::Ini; +use crate::model::{misc::Game, profile::Display}; + +impl Display { + pub fn line_up(&self, _game: Game, _ini: &mut Ini) { + // nop + } +} \ No newline at end of file diff --git a/rust/src/modules/mod.rs b/rust/src/modules/mod.rs index c17bc6f..ea1ded7 100644 --- a/rust/src/modules/mod.rs +++ b/rust/src/modules/mod.rs @@ -7,4 +7,7 @@ pub mod keyboard; pub mod mempatcher; #[cfg(target_os = "windows")] -pub mod display_windows; \ No newline at end of file +pub mod display_windows; + +#[cfg(target_os = "linux")] +pub mod display_linux; \ No newline at end of file diff --git a/rust/src/profiles/mod.rs b/rust/src/profiles/mod.rs index 10141b8..209113a 100644 --- a/rust/src/profiles/mod.rs +++ b/rust/src/profiles/mod.rs @@ -1,6 +1,6 @@ pub use types::{Profile, ProfileData, ProfileMeta, ProfilePaths, StartPayload}; use std::{collections::{BTreeMap, BTreeSet}, path::{Path, PathBuf}}; -use crate::{model::{misc::Game, patch::{PatchList, PatchSelection}, profile::{Aime, ChunithmKeyboard, IOSelection, Keyboard, Mu3Ini, OngekiKeyboard, ProfileModule}}, modules::{display_windows::DisplayInfo, package::prepare_packages}, pkg::PkgKey, pkg_store::PackageStore, util}; +use crate::{model::{misc::Game, patch::{PatchList, PatchSelection}, profile::{Aime, ChunithmKeyboard, IOSelection, Keyboard, Mu3Ini, OngekiKeyboard, ProfileModule}}, modules::package::prepare_packages, pkg::PkgKey, pkg_store::PackageStore, util}; use tauri::Emitter; use std::process::Stdio; use crate::model::profile::BepInEx; @@ -10,9 +10,23 @@ use std::fs::File; use tokio::process::Command; use tokio::task::JoinSet; +#[cfg(target_os = "windows")] +use crate::modules::display_windows::DisplayInfo; + pub mod template; pub mod types; +#[cfg(target_os = "linux")] +pub trait RawArg { + fn raw_arg>(&mut self, arg: S) -> &mut Command; +} +#[cfg(target_os = "linux")] +impl RawArg for Command { + fn raw_arg>(&mut self, arg: S) -> &mut Command { + return self.arg::(arg); + } +} + impl Profile { pub fn new(mut meta: ProfileMeta) -> Result { meta.name = fixed_name(&meta, true); @@ -176,6 +190,7 @@ impl Profile { self.data.patches = source.patches; } } + #[cfg(target_os = "windows")] pub fn prepare_display(&self) -> Result> { let info = match &self.data.display { None => None, @@ -252,8 +267,8 @@ impl Profile { } #[cfg(target_os = "linux")] { - game_builder = Command::new(&self.wine.runtime); - amd_builder = Command::new(&self.wine.runtime); + game_builder = Command::new(&self.data.wine.runtime); + amd_builder = Command::new(&self.data.wine.runtime); game_builder.arg(sgt_dir.join(self.meta.game.inject_exe())); amd_builder.arg("cmd.exe"); @@ -349,8 +364,8 @@ impl Profile { #[cfg(target_os = "linux")] { - amd_builder.env("WINEPREFIX", &self.wine.prefix); - game_builder.env("WINEPREFIX", &self.wine.prefix); + amd_builder.env("WINEPREFIX", &self.data.wine.prefix); + game_builder.env("WINEPREFIX", &self.data.wine.prefix); } let amd_log = File::create(self.data_dir().join("amdaemon.exe.log"))?; diff --git a/rust/src/util.rs b/rust/src/util.rs index 3922fc1..3bf9fd2 100644 --- a/rust/src/util.rs +++ b/rust/src/util.rs @@ -152,6 +152,7 @@ impl PathStr for PathBuf { } } +#[allow(dead_code)] pub fn bool_to_01(val: bool) -> &'static str { return if val { "1" } else { "0" } } diff --git a/src/components/App.vue b/src/components/App.vue index 3e5733c..6817f8c 100644 --- a/src/components/App.vue +++ b/src/components/App.vue @@ -27,7 +27,6 @@ import { usePkgStore, usePrfStore, } from '../stores'; -import { Dirs } from '../types'; import { messageSplit, shouldPreferDark } from '../util'; document.documentElement.classList.toggle('use-dark-mode', shouldPreferDark()); diff --git a/src/components/ProfileList.vue b/src/components/ProfileList.vue index becbde4..c8db156 100644 --- a/src/components/ProfileList.vue +++ b/src/components/ProfileList.vue @@ -18,10 +18,17 @@ const prf = usePrfStore(); const client = useClientStore(); const general = useGeneralStore(); +const hasChunithm = ref(false); const exportVisible = ref(false); const exportKeychip = ref(false); const files = new Set(); +(async () => { + hasChunithm.value = ( + (await invoke('list_platform_capabilities')) as string[] + ).includes('chunithm'); +})(); + const exportTemplate = async () => { const fl = [...files.values()]; exportVisible.value = false; @@ -134,6 +141,7 @@ const importPick = async () => { @click="() => prf.create('ongeki')" />