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