diff --git a/Cargo.toml b/Cargo.toml index 200f94f..f872d06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,3 +31,7 @@ crate-type = ["cdylib"] [[example]] name = "menus" crate-type = ["cdylib"] + +[[example]] +name = "paths" +crate-type = ["cdylib"] diff --git a/examples/paths.rs b/examples/paths.rs new file mode 100644 index 0000000..74d81c6 --- /dev/null +++ b/examples/paths.rs @@ -0,0 +1,42 @@ +extern crate xplm; + +use xplm::paths::{aircraft_path, plugin_path, prefs_path, system_path}; +use xplm::plugin::{Plugin, PluginInfo}; +use xplm::{debugln, xplane_plugin}; + +struct PathsDemo; + +impl Plugin for PathsDemo { + type Error = std::convert::Infallible; + + fn start() -> Result { + debugln!( + "[Rust-XPLM] X-Plane root folder: {}", + system_path().unwrap().display() + ); + debugln!( + "[Rust-XPLM] X-Plane prefs file: {}", + prefs_path().unwrap().display() + ); + debugln!( + "[Rust-XPLM] Plugin path: {}", + plugin_path().unwrap().display() + ); + debugln!( + "[Rust-XPLM] Aircraft path: {}", + aircraft_path().unwrap().display() + ); + + Ok(PathsDemo) + } + + fn info(&self) -> PluginInfo { + PluginInfo { + name: String::from("Paths Demo Rust Plugin"), + signature: String::from("org.samcrow.xplm.examples.paths"), + description: String::from("Demonstrates paths functions"), + } + } +} + +xplane_plugin!(PathsDemo); diff --git a/src/internal.rs b/src/internal.rs index 9073126..4e374e4 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -2,6 +2,8 @@ use std::ffi::CString; use std::os::raw::c_char; use std::ptr; +use super::feature; + /// Copies up to 256 bytes (including null termination) to /// the provided destination. If the provided source string is too long, it will be /// truncated. @@ -14,7 +16,15 @@ pub unsafe fn copy_to_c_buffer(mut src: String, dest: *mut c_char) { ptr::copy_nonoverlapping(src_c.as_ptr(), dest, src_c_length); } +/// Enables native paths +pub fn path_init() { + // Feature specified to exist in SDK 2.1 + let native_path_feature = + feature::find_feature("XPLM_USE_NATIVE_PATHS").expect("No native paths feature"); + native_path_feature.set_enabled(true); +} + /// Performs initialization required for the XPLM crate to work correctly pub fn xplm_init() { - super::paths::path_init(); + path_init(); } diff --git a/src/lib.rs b/src/lib.rs index 10cb0dc..410b365 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,8 +8,6 @@ use std::ffi::CString; /// FFI utilities mod ffi; -/// Path conversion -mod paths; /// Plugin macro mod plugin_macro; @@ -34,6 +32,8 @@ pub mod flight_loop; pub mod geometry; /// User interface menus pub mod menu; +/// X-Plane and plugin paths +pub mod paths; /// Plugin creation and management pub mod plugin; /// X-Plane and XPLM version info diff --git a/src/paths.rs b/src/paths.rs index a08568f..720286a 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -1,9 +1,50 @@ -use super::feature; - -/// Enables native paths -pub fn path_init() { - // Feature specified to exist in SDK 2.1 - let native_path_feature = - feature::find_feature("XPLM_USE_NATIVE_PATHS").expect("No native paths feature"); - native_path_feature.set_enabled(true); +use std::{path::PathBuf, ptr::null_mut, str::Utf8Error}; + +use xplm_sys::{ + XPLMGetMyID, XPLMGetNthAircraftModel, XPLMGetPluginInfo, XPLMGetPrefsPath, XPLMGetSystemPath, +}; + +use super::ffi::StringBuffer; + +/// Get path to this plugin +pub fn plugin_path() -> Result { + let mut path = StringBuffer::new(512); + unsafe { + XPLMGetPluginInfo( + XPLMGetMyID(), + null_mut(), + path.as_mut_ptr(), + null_mut(), + null_mut(), + ); + } + Ok(PathBuf::from(path.as_str()?)) +} + +/// Get path to X-Plane's preferences file +/// (usually "Output/preferences/Set X-Plane.prf") +pub fn prefs_path() -> Result { + let mut path = StringBuffer::new(512); + unsafe { + XPLMGetPrefsPath(path.as_mut_ptr()); + } + Ok(PathBuf::from(path.as_str()?)) +} + +/// Get path to X-Plane root folder +pub fn system_path() -> Result { + let mut path = StringBuffer::new(512); + unsafe { + XPLMGetSystemPath(path.as_mut_ptr()); + } + Ok(PathBuf::from(path.as_str()?)) +} + +/// Get path to loaded aircraft's .acf file +pub fn aircraft_path() -> Result { + let mut path = StringBuffer::new(512); + unsafe { + XPLMGetNthAircraftModel(0, StringBuffer::new(256).as_mut_ptr(), path.as_mut_ptr()); + } + Ok(PathBuf::from(path.as_str()?)) }