1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
//! Utilities to get information about the operating system and hardware state.
/// System version information. This struct is used for both kernel and firmware versions.
///
/// # Example
/// ```
/// # let _runner = test_runner::GdbRunner::default();
/// let firm_version = ctru::os::firm_version();
/// assert_ne!(firm_version.major(), 0);
///
/// let kernel_version = ctru::os::kernel_version();
/// assert_ne!(kernel_version.major(), 0);
/// ```
#[derive(Clone, Copy)]
pub struct Version(u32);
impl Version {
/// Pack a system version from its components
pub fn new(major: u8, minor: u8, revision: u8) -> Self {
let major = u32::from(major);
let minor = u32::from(minor);
let revision = u32::from(revision);
Self(major << 24 | minor << 16 | revision << 8)
}
/// Get the major version from a packed system version.
pub fn major(&self) -> u8 {
(self.0 >> 24).try_into().unwrap()
}
/// Get the minor version from a packed system version.
pub fn minor(&self) -> u8 {
(self.0 >> 16 & 0xFF).try_into().unwrap()
}
/// Get the revision from a packed system version.
pub fn revision(&self) -> u8 {
(self.0 >> 8 & 0xFF).try_into().unwrap()
}
}
/// Get the system's FIRM version.
pub fn firm_version() -> Version {
Version(unsafe { ctru_sys::osGetFirmVersion() })
}
/// Get the system's kernel version.
pub fn kernel_version() -> Version {
Version(unsafe { ctru_sys::osGetKernelVersion() })
}
// TODO: I can't seem to find good documentation on it, but we could probably
// define enums for firmware type (NATIVE_FIRM, SAFE_FIRM etc.) as well as
// application memory layout. Leaving those as future enhancements for now
/// A region of memory. Most applications will only use [`Application`](MemRegion::Application)
/// memory, but the other types can be used to query memory usage information.
/// See <https://www.3dbrew.org/wiki/Memory_layout#FCRAM_memory-regions_layout>
/// for more details on the different types of memory.
///
/// # Example
/// ```
/// # let _runner = test_runner::GdbRunner::default();
/// let all_memory = ctru::os::MemRegion::All;
///
/// assert!(all_memory.size() > 0);
/// assert!(all_memory.used() > 0);
/// assert!(all_memory.free() > 0);
/// ```
#[derive(Clone, Copy, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum MemRegion {
/// All memory regions.
All = ctru_sys::MEMREGION_ALL,
/// APPLICATION memory.
Application = ctru_sys::MEMREGION_APPLICATION,
/// SYSTEM memory.
System = ctru_sys::MEMREGION_SYSTEM,
/// BASE memory.
Base = ctru_sys::MEMREGION_BASE,
}
impl MemRegion {
/// Get the total size of this memory region, in bytes.
pub fn size(&self) -> usize {
unsafe { ctru_sys::osGetMemRegionSize(*self as u8) }
.try_into()
.unwrap()
}
/// Get the number of bytes used within this memory region.
pub fn used(&self) -> usize {
unsafe { ctru_sys::osGetMemRegionUsed(*self as u8) }
.try_into()
.unwrap()
}
/// Get the number of bytes free within this memory region.
pub fn free(&self) -> usize {
unsafe { ctru_sys::osGetMemRegionFree(*self as u8) }
.try_into()
.unwrap()
}
}
/// WiFi signal strength. This enum's `u8` representation corresponds with
/// the number of bars displayed in the Home menu.
///
/// # Example
///
/// ```
/// let _runner = test_runner::GdbRunner::default();
/// let strength = ctru::os::WifiStrength::current();
/// assert!((strength as u8) < 4);
/// ```
#[derive(Clone, Copy, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum WifiStrength {
/// This may indicate a very poor signal quality even worse than `Bad`,
/// or that no network is connected at all.
Disconnected = 0,
/// Poor signal strength.
Bad = 1,
/// Medium signal strength.
Decent = 2,
/// Good signal strength.
Good = 3,
}
impl WifiStrength {
/// Get the current WiFi signal strength.
pub fn current() -> Self {
match unsafe { ctru_sys::osGetWifiStrength() } {
0 => Self::Disconnected,
1 => Self::Bad,
2 => Self::Decent,
3 => Self::Good,
other => panic!("Got unexpected WiFi strength value {other}"),
}
}
}
/// Get the current value of the stereoscopic 3D slider on a scale from 0.0–1.0.
pub fn current_3d_slider_state() -> f32 {
unsafe { ctru_sys::osGet3DSliderState() }
}
/// Whether or not a headset is currently plugged into the device.
pub fn is_headset_connected() -> bool {
unsafe { ctru_sys::osIsHeadsetConnected() }
}