diff --git a/src/profile.rs b/src/profile.rs index fc71c1c..b8e5cec 100644 --- a/src/profile.rs +++ b/src/profile.rs @@ -23,7 +23,7 @@ impl XRServiceType { } } - pub fn iter() -> Iter<'static, XRServiceType> { + pub fn iter() -> Iter<'static, Self> { [Self::Monado, Self::Wivrn].iter() } @@ -33,6 +33,14 @@ impl XRServiceType { Self::Wivrn => 1, } } + + pub fn from_number(i: u32) -> Self { + match i { + 0 => Self::Monado, + 1 => Self::Wivrn, + _ => panic!("XRServiceType index out of bounds"), + } + } } impl Display for XRServiceType { @@ -115,6 +123,63 @@ impl Default for ProfileFeatures { } } +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum LighthouseDriver { + Vive, + Survive, + SteamVR, +} + +impl Default for LighthouseDriver { + fn default() -> Self { + Self::Vive + } +} + +impl LighthouseDriver { + pub fn from_string(s: String) -> Self { + match s.trim().to_lowercase().as_str() { + "vive" => Self::Vive, + "survive" => Self::Survive, + "libsurvive" => Self::Survive, + "steam" => Self::SteamVR, + "steamvr" => Self::SteamVR, + _ => Self::Vive, + } + } + + pub fn iter() -> Iter<'static, Self> { + [Self::Vive, Self::Survive, Self::SteamVR].iter() + } + + pub fn as_number(&self) -> u32 { + match self { + Self::Vive => 0, + Self::Survive => 1, + Self::SteamVR => 2, + } + } + + pub fn from_number(i: u32) -> Self { + match i { + 0 => Self::Vive, + 1 => Self::Survive, + 2 => Self::SteamVR, + _ => panic!("LighthouseDriver index out of bounds"), + } + } +} + +impl Display for LighthouseDriver { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + Self::Vive => "Vive", + Self::Survive => "Survive", + Self::SteamVR => "SteamVR", + }) + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct Profile { pub uuid: String, @@ -131,6 +196,9 @@ pub struct Profile { pub can_be_built: bool, pub editable: bool, pub pull_on_build: bool, + #[serde(default = "LighthouseDriver::default")] + /** Only applicable for Monado */ + pub lighthouse_driver: LighthouseDriver, } impl Display for Profile { @@ -168,6 +236,7 @@ impl Default for Profile { xrservice_repo: None, opencomposite_repo: None, editable: true, + lighthouse_driver: LighthouseDriver::default(), } } } diff --git a/src/profiles/system_valve_index.rs b/src/profiles/system_valve_index.rs index 17b22fe..b2b211d 100644 --- a/src/profiles/system_valve_index.rs +++ b/src/profiles/system_valve_index.rs @@ -1,7 +1,7 @@ use crate::{ constants::APP_NAME, paths::{data_opencomposite_path, SYSTEM_PREFIX}, - profile::{Profile, ProfileFeatures, XRServiceType}, + profile::{LighthouseDriver, Profile, ProfileFeatures, XRServiceType}, }; use std::collections::HashMap; @@ -25,6 +25,7 @@ pub fn system_valve_index_profile() -> Profile { prefix: SYSTEM_PREFIX.into(), can_be_built: false, editable: false, + lighthouse_driver: LighthouseDriver::Survive, ..Default::default() } } diff --git a/src/profiles/valve_index.rs b/src/profiles/valve_index.rs index a5507ce..7efb685 100644 --- a/src/profiles/valve_index.rs +++ b/src/profiles/valve_index.rs @@ -1,7 +1,10 @@ use crate::{ constants::APP_NAME, paths::{data_libsurvive_path, data_monado_path, data_opencomposite_path, get_data_dir}, - profile::{Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures, XRServiceType}, + profile::{ + LighthouseDriver, Profile, ProfileFeature, ProfileFeatureType, ProfileFeatures, + XRServiceType, + }, }; use std::collections::HashMap; @@ -37,6 +40,7 @@ pub fn valve_index_profile() -> Profile { prefix, can_be_built: true, editable: false, + lighthouse_driver: LighthouseDriver::Survive, ..Default::default() } } diff --git a/src/runner.rs b/src/runner.rs index bf2e03c..0d61c41 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -90,6 +90,13 @@ impl Runner { } pub fn xrservice_runner_from_profile(profile: &Profile) -> Self { + let mut env = profile.environment.clone(); + if !env.contains_key("LH_DRIVER") { + env.insert( + "LH_DRIVER".into(), + profile.lighthouse_driver.to_string().to_lowercase(), + ); + } Self::new( Some(profile.environment.clone()), match profile.xrservice_type { @@ -143,11 +150,7 @@ impl Runner { return; } let mut proc = process.unwrap(); - let child_pid = Pid::from_raw( - proc.id() - .try_into() - .expect("Could not convert pid to u32"), - ); + let child_pid = Pid::from_raw(proc.id().try_into().expect("Could not convert pid to u32")); kill(child_pid, SIGTERM).expect("Could not send sigterm to process"); self.join_threads(); proc.wait().expect("Failed to wait for process"); diff --git a/src/ui/main_view.rs b/src/ui/main_view.rs index 9ecb981..d72c4aa 100644 --- a/src/ui/main_view.rs +++ b/src/ui/main_view.rs @@ -6,7 +6,7 @@ use super::steam_launch_options_box::{SteamLaunchOptionsBox, SteamLaunchOptionsB use crate::config::Config; use crate::constants::APP_NAME; use crate::file_utils::mount_has_nosuid; -use crate::profile::Profile; +use crate::profile::{Profile, LighthouseDriver}; use crate::ui::app::{ AboutAction, BuildProfileAction, BuildProfileCleanAction, DebugViewToggleAction, }; @@ -245,7 +245,7 @@ impl SimpleComponent for MainView { set_margin_top: 12, set_margin_bottom: 12, #[track = "model.changed(Self::selected_profile())"] - set_visible: model.selected_profile.features.libsurvive.enabled, + set_visible: model.selected_profile.lighthouse_driver == LighthouseDriver::Survive, gtk::Separator { set_orientation: gtk::Orientation::Horizontal, set_hexpand: true, diff --git a/src/ui/profile_editor.rs b/src/ui/profile_editor.rs index 153049e..f2e8df3 100644 --- a/src/ui/profile_editor.rs +++ b/src/ui/profile_editor.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::{ env_var_descriptions::env_var_descriptions_as_paragraph, - profile::{Profile, XRServiceType}, + profile::{LighthouseDriver, Profile, XRServiceType}, ui::preference_rows::{entry_row, path_row, switch_row}, withclones, }; @@ -101,14 +101,30 @@ impl SimpleComponent for ProfileEditor { .collect::>(), move |row| { prof.borrow_mut().xrservice_type = - match row.selected() { - 0 => XRServiceType::Monado, - 1 => XRServiceType::Wivrn, - _ => panic!("XRServiceType combo row cannot have more than 2 choices"), - }; + XRServiceType::from_number(row.selected()); }, ) }, + add: { + withclones![prof]; + &combo_row( + "Lighthouse Driver", + Some(concat!( + "Driver for lighhouse tracked XR devices (ie: Valve Index, HTC Vive...). Only applicable for Monado.\n\n", + "Vive: 3DOF tracking\n\n", + "Survive: 6DOF reverse engineered lighthouse tracking provided by Libsurvive\n\n", + "SteamVR: 6DOF lighthouse tracking using the proprietary SteamVR driver", + )), + model.profile.borrow().lighthouse_driver.to_string().as_str(), + LighthouseDriver::iter() + .map(LighthouseDriver::to_string) + .collect::>(), + move |row| { + prof.borrow_mut().lighthouse_driver = + LighthouseDriver::from_number(row.selected()); + } + ) + }, add: { withclones![prof]; &path_row(