diff --git a/ctru-rs/examples/audio-filters.rs b/ctru-rs/examples/audio-filters.rs index d171dc0..616b8d4 100644 --- a/ctru-rs/examples/audio-filters.rs +++ b/ctru-rs/examples/audio-filters.rs @@ -35,7 +35,8 @@ fn fill_buffer(audio_data: &mut [u8], frequency: f32) { } fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/buttons.rs b/ctru-rs/examples/buttons.rs index 60cfba2..c8f9f71 100644 --- a/ctru-rs/examples/buttons.rs +++ b/ctru-rs/examples/buttons.rs @@ -1,8 +1,8 @@ use ctru::prelude::*; fn main() { - // Setup services - ctru::init(); + ctru::use_panic_handler(); + let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::init().unwrap(); diff --git a/ctru-rs/examples/camera-image.rs b/ctru-rs/examples/camera-image.rs index 7eb6252..2ac283a 100644 --- a/ctru-rs/examples/camera-image.rs +++ b/ctru-rs/examples/camera-image.rs @@ -15,7 +15,7 @@ const BUF_SIZE: usize = WIDTH * HEIGHT * 2 * 2; const WAIT_TIMEOUT: Duration = Duration::from_micros(300); fn main() { - ctru::init(); + ctru::use_panic_handler(); let apt = Apt::init().expect("Failed to initialize Apt service."); let hid = Hid::init().expect("Failed to initialize Hid service."); diff --git a/ctru-rs/examples/file-explorer.rs b/ctru-rs/examples/file-explorer.rs index 6594f16..74a94eb 100644 --- a/ctru-rs/examples/file-explorer.rs +++ b/ctru-rs/examples/file-explorer.rs @@ -9,7 +9,8 @@ use std::os::horizon::fs::MetadataExt; use std::path::{Path, PathBuf}; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::init().unwrap(); diff --git a/ctru-rs/examples/futures-basic.rs b/ctru-rs/examples/futures-basic.rs index c96c65e..bfcf053 100644 --- a/ctru-rs/examples/futures-basic.rs +++ b/ctru-rs/examples/futures-basic.rs @@ -13,7 +13,8 @@ use futures::StreamExt; use std::os::horizon::thread::BuilderExt; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/futures-tokio.rs b/ctru-rs/examples/futures-tokio.rs index 2d4ff5a..48edc14 100644 --- a/ctru-rs/examples/futures-tokio.rs +++ b/ctru-rs/examples/futures-tokio.rs @@ -6,7 +6,8 @@ use std::os::horizon::thread::BuilderExt; use std::time::Duration; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/gfx-3d-mode.rs b/ctru-rs/examples/gfx-3d-mode.rs index df0593f..dfdc028 100644 --- a/ctru-rs/examples/gfx-3d-mode.rs +++ b/ctru-rs/examples/gfx-3d-mode.rs @@ -10,7 +10,8 @@ const IMAGE: &[u8] = include_bytes!("assets/ferris.rgb"); static ZERO: &[u8] = &[0; IMAGE.len()]; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/gfx-wide-mode.rs b/ctru-rs/examples/gfx-wide-mode.rs index e9026ab..2d25f7f 100644 --- a/ctru-rs/examples/gfx-wide-mode.rs +++ b/ctru-rs/examples/gfx-wide-mode.rs @@ -1,7 +1,8 @@ use ctru::prelude::*; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::init().unwrap(); diff --git a/ctru-rs/examples/graphics-bitmap.rs b/ctru-rs/examples/graphics-bitmap.rs index a034218..b6842f1 100644 --- a/ctru-rs/examples/graphics-bitmap.rs +++ b/ctru-rs/examples/graphics-bitmap.rs @@ -15,7 +15,8 @@ use ctru::prelude::*; static IMAGE: &[u8] = include_bytes!("assets/ferris.rgb"); fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/hashmaps.rs b/ctru-rs/examples/hashmaps.rs index 694752c..42efee2 100644 --- a/ctru-rs/examples/hashmaps.rs +++ b/ctru-rs/examples/hashmaps.rs @@ -1,12 +1,13 @@ use ctru::prelude::*; fn main() { + ctru::use_panic_handler(); + // Initialize services // // HashMaps generate hashes thanks to the 3DS' cryptografically secure generator. // This generator is only active when activating the `PS` service. - // This service is automatically initialized in `ctru::init` - ctru::init(); + // This service is automatically initialized. let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::init().unwrap(); diff --git a/ctru-rs/examples/hello-both-screens.rs b/ctru-rs/examples/hello-both-screens.rs index 4dcd588..38934d3 100644 --- a/ctru-rs/examples/hello-both-screens.rs +++ b/ctru-rs/examples/hello-both-screens.rs @@ -1,8 +1,8 @@ use ctru::prelude::*; fn main() { - // Initialize services - ctru::init(); + ctru::use_panic_handler(); + let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::init().unwrap(); diff --git a/ctru-rs/examples/hello-world.rs b/ctru-rs/examples/hello-world.rs index 5b7e8ee..910813a 100644 --- a/ctru-rs/examples/hello-world.rs +++ b/ctru-rs/examples/hello-world.rs @@ -3,7 +3,8 @@ use ctru::prelude::*; use std::io::BufWriter; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/linear-memory.rs b/ctru-rs/examples/linear-memory.rs index 11d13d3..440e62b 100644 --- a/ctru-rs/examples/linear-memory.rs +++ b/ctru-rs/examples/linear-memory.rs @@ -4,7 +4,8 @@ use ctru::linear::LinearAllocator; use ctru::prelude::*; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/mii-selector.rs b/ctru-rs/examples/mii-selector.rs index 975fda0..84115b6 100644 --- a/ctru-rs/examples/mii-selector.rs +++ b/ctru-rs/examples/mii-selector.rs @@ -2,7 +2,7 @@ use ctru::applets::mii_selector::MiiSelector; use ctru::prelude::*; fn main() { - ctru::init(); + ctru::use_panic_handler(); let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); diff --git a/ctru-rs/examples/network-sockets.rs b/ctru-rs/examples/network-sockets.rs index 89a1212..e53ef42 100644 --- a/ctru-rs/examples/network-sockets.rs +++ b/ctru-rs/examples/network-sockets.rs @@ -5,7 +5,8 @@ use std::net::{Shutdown, TcpListener}; use std::time::Duration; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().unwrap(); let _console = Console::init(gfx.top_screen.borrow_mut()); let hid = Hid::init().unwrap(); diff --git a/ctru-rs/examples/output-3dslink.rs b/ctru-rs/examples/output-3dslink.rs index 9f4a0ea..2d6b147 100644 --- a/ctru-rs/examples/output-3dslink.rs +++ b/ctru-rs/examples/output-3dslink.rs @@ -11,7 +11,8 @@ use ctru::prelude::*; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/romfs.rs b/ctru-rs/examples/romfs.rs index f8549bf..45a7add 100644 --- a/ctru-rs/examples/romfs.rs +++ b/ctru-rs/examples/romfs.rs @@ -1,7 +1,8 @@ use ctru::prelude::*; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/software-keyboard.rs b/ctru-rs/examples/software-keyboard.rs index 888a157..0415b10 100644 --- a/ctru-rs/examples/software-keyboard.rs +++ b/ctru-rs/examples/software-keyboard.rs @@ -2,7 +2,8 @@ use ctru::applets::swkbd::{Button, Swkbd}; use ctru::prelude::*; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::init().unwrap(); diff --git a/ctru-rs/examples/system-configuration.rs b/ctru-rs/examples/system-configuration.rs index ed1eacf..284e3f1 100644 --- a/ctru-rs/examples/system-configuration.rs +++ b/ctru-rs/examples/system-configuration.rs @@ -2,7 +2,8 @@ use ctru::prelude::*; use ctru::services::cfgu::Cfgu; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/thread-basic.rs b/ctru-rs/examples/thread-basic.rs index 069d0a2..a6c3a6b 100644 --- a/ctru-rs/examples/thread-basic.rs +++ b/ctru-rs/examples/thread-basic.rs @@ -6,8 +6,8 @@ use std::os::horizon::thread::BuilderExt; use std::time::Duration; fn main() { - // Initialize services - ctru::init(); + ctru::use_panic_handler(); + let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::init().unwrap(); diff --git a/ctru-rs/examples/thread-info.rs b/ctru-rs/examples/thread-info.rs index b504b69..06e2864 100644 --- a/ctru-rs/examples/thread-info.rs +++ b/ctru-rs/examples/thread-info.rs @@ -7,7 +7,8 @@ use ctru::prelude::*; use std::os::horizon::thread::BuilderExt; fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); let apt = Apt::init().expect("Couldn't obtain APT controller"); diff --git a/ctru-rs/examples/thread-locals.rs b/ctru-rs/examples/thread-locals.rs index ae46823..70f2aaa 100644 --- a/ctru-rs/examples/thread-locals.rs +++ b/ctru-rs/examples/thread-locals.rs @@ -10,7 +10,8 @@ std::thread_local! { } fn main() { - ctru::init(); + ctru::use_panic_handler(); + let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); gfx.top_screen.borrow_mut().set_wide_mode(true); let hid = Hid::init().expect("Couldn't obtain HID controller"); diff --git a/ctru-rs/examples/time-rtc.rs b/ctru-rs/examples/time-rtc.rs index 219abda..b7ff399 100644 --- a/ctru-rs/examples/time-rtc.rs +++ b/ctru-rs/examples/time-rtc.rs @@ -1,7 +1,7 @@ use ctru::prelude::*; fn main() { - ctru::init(); + ctru::use_panic_handler(); let gfx = Gfx::init().expect("Couldn't obtain GFX controller"); let hid = Hid::init().expect("Couldn't obtain HID controller"); diff --git a/ctru-rs/src/applets/swkbd.rs b/ctru-rs/src/applets/swkbd.rs index 715c2de..976bdec 100644 --- a/ctru-rs/src/applets/swkbd.rs +++ b/ctru-rs/src/applets/swkbd.rs @@ -3,7 +3,6 @@ use ctru_sys::{ self, swkbdInit, swkbdInputText, swkbdSetButton, swkbdSetFeatures, swkbdSetHintText, SwkbdState, }; use libc; -use std::convert::TryInto; use std::iter::once; use std::str; @@ -127,11 +126,7 @@ impl Swkbd { /// the output will be truncated but should still be well-formed UTF-8 pub fn get_bytes(&mut self, buf: &mut [u8]) -> Result { unsafe { - match swkbdInputText( - self.state.as_mut(), - buf.as_mut_ptr(), - buf.len().try_into().unwrap(), - ) { + match swkbdInputText(self.state.as_mut(), buf.as_mut_ptr(), buf.len()) { ctru_sys::SWKBD_BUTTON_NONE => Err(self.parse_swkbd_error()), ctru_sys::SWKBD_BUTTON_LEFT => Ok(Button::Left), ctru_sys::SWKBD_BUTTON_MIDDLE => Ok(Button::Middle), diff --git a/ctru-rs/src/lib.rs b/ctru-rs/src/lib.rs index 490b268..8dd8abf 100644 --- a/ctru-rs/src/lib.rs +++ b/ctru-rs/src/lib.rs @@ -7,40 +7,25 @@ #![feature(nonnull_slice_from_raw_parts)] #![test_runner(test_runner::run)] -extern "C" fn services_deinit() { - unsafe { - ctru_sys::psExit(); - } -} +// Nothing is imported from these crates but their inclusion here assures correct linking of the missing implementations. +extern crate linker_fix_3ds; +extern crate pthread_3ds; #[no_mangle] #[cfg(feature = "big-stack")] static __stacksize__: usize = 2 * 1024 * 1024; // 2MB -/// Call this somewhere to force Rust to link some required crates -/// This is also a setup for some crate integration only available at runtime +/// Activate ´ctru-rs´' default panic handler. /// -/// See -pub fn init() { - linker_fix_3ds::init(); - pthread_3ds::init(); - +/// With this implementation, the main thread will stop and try to print debug info to an available [console::Console]. +/// In case it fails to find an active [console::Console], the program will just exit. +/// +/// # Notes +/// +/// When ´test´ is enabled, this function won't do anything, as it should be overridden by the ´test´ environment. +pub fn use_panic_handler() { #[cfg(not(test))] panic_hook_setup(); - - // Initialize the PS service for random data generation - unsafe { - let ps_ret = ctru_sys::psInit(); - if ctru_sys::R_FAILED(ps_ret) { - panic!( - "Failed to initialize random data generation: {:?}", - Error::from(ps_ret) - ) - } - - // Setup the deconstruction at the program's end - libc::atexit(services_deinit); - } } #[cfg(not(test))] diff --git a/ctru-rs/src/services/ps.rs b/ctru-rs/src/services/ps.rs index d87cda4..79ebcd7 100644 --- a/ctru-rs/src/services/ps.rs +++ b/ctru-rs/src/services/ps.rs @@ -1,10 +1,10 @@ //! Process Services (PS) module. This is used for miscellaneous utility tasks, but //! is particularly important because it is used to generate random data, which //! is required for common things like [`HashMap`](std::collections::HashMap). -//! As such, it is initialized by default in `ctru::init` instead of having a safety handler //! See also use crate::error::ResultCode; +use crate::Result; #[repr(u32)] pub enum AESAlgorithm { @@ -30,23 +30,44 @@ pub enum AESKeyType { Keyslot39Nfc, } -pub fn local_friend_code_seed() -> crate::Result { - let mut seed: u64 = 0; +pub struct Ps(()); - ResultCode(unsafe { ctru_sys::PS_GetLocalFriendCodeSeed(&mut seed) })?; - Ok(seed) -} +impl Ps { + pub fn new() -> Result { + unsafe { + ResultCode(ctru_sys::psInit())?; + Ok(Ps(())) + } + } + + pub fn local_friend_code_seed(&self) -> crate::Result { + let mut seed: u64 = 0; + + ResultCode(unsafe { ctru_sys::PS_GetLocalFriendCodeSeed(&mut seed) })?; + Ok(seed) + } -pub fn device_id() -> crate::Result { - let mut id: u32 = 0; + pub fn device_id(&self) -> crate::Result { + let mut id: u32 = 0; - ResultCode(unsafe { ctru_sys::PS_GetDeviceId(&mut id) })?; - Ok(id) + ResultCode(unsafe { ctru_sys::PS_GetDeviceId(&mut id) })?; + Ok(id) + } + + pub fn generate_random_bytes(&self, out: &mut [u8]) -> crate::Result<()> { + ResultCode(unsafe { + ctru_sys::PS_GenerateRandomBytes(out as *mut _ as *mut _, out.len()) + })?; + Ok(()) + } } -pub fn generate_random_bytes(out: &mut [u8]) -> crate::Result<()> { - ResultCode(unsafe { ctru_sys::PS_GenerateRandomBytes(out as *mut _ as *mut _, out.len()) })?; - Ok(()) +impl Drop for Ps { + fn drop(&mut self) { + unsafe { + ctru_sys::psExit(); + } + } } #[cfg(test)] diff --git a/ctru-rs/src/test_runner.rs b/ctru-rs/src/test_runner.rs index ebec899..192483f 100644 --- a/ctru-rs/src/test_runner.rs +++ b/ctru-rs/src/test_runner.rs @@ -15,8 +15,6 @@ use crate::services::Apt; /// runs all tests in series, "failing" on the first one to panic (really, the /// panic is just treated the same as any normal application panic). pub(crate) fn run(tests: &[&TestDescAndFn]) { - crate::init(); - let gfx = Gfx::init().unwrap(); let hid = Hid::init().unwrap(); let apt = Apt::init().unwrap();