From 044cbeecc982dee6a300e02b73eaa9652530248d Mon Sep 17 00:00:00 2001 From: Maccraft123 Date: Tue, 28 Feb 2023 14:42:36 +0100 Subject: [PATCH] Add a basic AM service wrapper and an example that uses it --- ctru-rs/examples/title-info.rs | 37 +++++++++++++++++++++++++++++ ctru-rs/src/services/am.rs | 43 ++++++++++++++++++++++++++++++++++ ctru-rs/src/services/fs.rs | 8 +++++++ ctru-rs/src/services/mod.rs | 1 + 4 files changed, 89 insertions(+) create mode 100644 ctru-rs/examples/title-info.rs create mode 100644 ctru-rs/src/services/am.rs diff --git a/ctru-rs/examples/title-info.rs b/ctru-rs/examples/title-info.rs new file mode 100644 index 0000000..2abb085 --- /dev/null +++ b/ctru-rs/examples/title-info.rs @@ -0,0 +1,37 @@ +use ctru::prelude::*; +use ctru::services::am::Am; +use ctru::services::fs::FsMediaType; + +fn main() { + 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"); + let am = Am::init().expect("Couldn't obtain AM controller"); + let _console = Console::init(gfx.top_screen.borrow_mut()); + + let title_count = am.get_title_count(FsMediaType::Sd).expect("Failed to get title count"); + println!("This 3DS has {title_count} titles on its SD Card:"); + + let title_list = am.get_title_list(FsMediaType::Sd).expect("Failed to get title list"); + for id in title_list { + println!("{id:x}"); + } + + // Main loop + while apt.main_loop() { + //Scan all the inputs. This should be done once for each frame + hid.scan_input(); + + if hid.keys_down().contains(KeyPad::KEY_START) { + break; + } + // Flush and swap framebuffers + gfx.flush_buffers(); + gfx.swap_buffers(); + + //Wait for VBlank + gfx.wait_for_vblank(); + } +} diff --git a/ctru-rs/src/services/am.rs b/ctru-rs/src/services/am.rs new file mode 100644 index 0000000..aea3927 --- /dev/null +++ b/ctru-rs/src/services/am.rs @@ -0,0 +1,43 @@ +use crate::error::ResultCode; +use crate::services::fs::FsMediaType; + +pub struct Am(()); + +impl Am { + pub fn init() -> crate::Result { + unsafe { + ResultCode(ctru_sys::amInit())?; + Ok(Am(())) + } + } + + pub fn get_title_count(&self, mediatype: FsMediaType) -> crate::Result { + unsafe { + let mut count = 0; + ResultCode(ctru_sys::AM_GetTitleCount(mediatype as u32, &mut count))?; + Ok(count) + } + } + + pub fn get_title_list(&self, mediatype: FsMediaType) -> crate::Result> { + unsafe { + let count = self.get_title_count(mediatype)?; + let mut buf = Vec::with_capacity(count as usize); + let mut read_amount = 0; + ResultCode(ctru_sys::AM_GetTitleList( + &mut read_amount, + mediatype as u32, + count, + buf.as_mut_ptr(), + ))?; + buf.set_len(read_amount as usize); + Ok(buf) + } + } +} + +impl Drop for Am { + fn drop(&mut self) { + unsafe { ctru_sys::amExit() }; + } +} diff --git a/ctru-rs/src/services/fs.rs b/ctru-rs/src/services/fs.rs index 64da9c3..6cd3728 100644 --- a/ctru-rs/src/services/fs.rs +++ b/ctru-rs/src/services/fs.rs @@ -43,6 +43,14 @@ bitflags! { } } +#[derive(Copy, Clone, Debug)] +#[repr(u32)] +pub enum FsMediaType { + Nand = ctru_sys::MEDIATYPE_NAND, + Sd = ctru_sys::MEDIATYPE_SD, + GameCard = ctru_sys::MEDIATYPE_GAME_CARD, +} + #[derive(Copy, Clone, Debug)] pub enum PathType { Invalid, diff --git a/ctru-rs/src/services/mod.rs b/ctru-rs/src/services/mod.rs index b0cc8ef..8346ea7 100644 --- a/ctru-rs/src/services/mod.rs +++ b/ctru-rs/src/services/mod.rs @@ -6,6 +6,7 @@ //! Some include: button input, audio playback, graphics rendering, built-in cameras, etc. pub mod apt; +pub mod am; pub mod cam; pub mod cfgu; pub mod fs;