Browse Source

Add `Title` struct

pull/95/head
Maccraft123 2 years ago
parent
commit
0fd7a340c8
  1. 24
      ctru-rs/examples/title-info.rs
  2. 72
      ctru-rs/src/services/am.rs

24
ctru-rs/examples/title-info.rs

@ -59,18 +59,18 @@ fn main() { @@ -59,18 +59,18 @@ fn main() {
}
if refresh {
let mut selected_title = 0;
let mut selected_title = cur_list.iter().skip(offset).next().unwrap();
// Clear top screen and write title ids to it
top_screen.select();
print!("\x1b[2J");
// Top screen seems to have only 30 rows
for (i, id) in cur_list.iter().skip(offset).take(29).enumerate() {
for (i, title) in cur_list.iter().skip(offset).take(29).enumerate() {
if i == 0 {
selected_title = *id;
println!("=> {id:x}");
selected_title = title;
println!("=> {:x}", title.id());
} else {
println!(" {id:x}");
println!(" {:x}", title.id());
}
}
@ -79,21 +79,19 @@ fn main() { @@ -79,21 +79,19 @@ fn main() {
println!("\x1b[2J");
// Move cursor to top left
println!("\x1b[1;1");
let media = if use_nand {
FsMediaType::Nand
} else {
FsMediaType::Sd
};
match am.get_title_info(media, &mut [selected_title]) {
match selected_title.get_title_info() {
Ok(info) => {
// Vec returned by Am::get_title_info always has same length as inputed slice
let info = info[0];
println!("Size: {} KB", info.size_bytes() / 1024);
println!("Version: 0x{:x}", info.version());
println!("Type: 0x{:x}", info.type_());
}
Err(e) => println!("Failed to get title info: {}", e),
}
match selected_title.get_product_code() {
Ok(code) => println!("Product code: \"{code}\""),
Err(e) => println!("Failed to get product code: {}", e),
}
println!("\x1b[26;0HPress START to exit");
if use_nand {

72
ctru-rs/src/services/am.rs

@ -1,5 +1,7 @@ @@ -1,5 +1,7 @@
use crate::error::ResultCode;
use crate::services::fs::FsMediaType;
use std::marker::PhantomData;
use std::mem::MaybeUninit;
#[derive(Copy, Clone, Debug)]
#[repr(C)]
@ -29,6 +31,46 @@ impl TitleInfo { @@ -29,6 +31,46 @@ impl TitleInfo {
}
}
pub struct Title<'a> {
id: u64,
mediatype: FsMediaType,
_am: PhantomData<&'a Am>,
}
impl<'a> Title<'a> {
pub fn id(&self) -> u64 {
self.id
}
pub fn get_product_code(&self) -> crate::Result<String> {
let mut buf: [u8; 16] = [0; 16];
unsafe {
ResultCode(ctru_sys::AM_GetTitleProductCode(
self.mediatype as u32,
self.id,
buf.as_mut_ptr(),
))?;
}
Ok(String::from_utf8_lossy(&buf).to_string())
}
pub fn get_title_info(&self) -> crate::Result<TitleInfo> {
let mut info = MaybeUninit::zeroed();
unsafe {
ResultCode(ctru_sys::AM_GetTitleInfo(
self.mediatype as u32,
1,
&mut self.id.clone(),
info.as_mut_ptr() as _,
))?;
Ok(info.assume_init())
}
}
}
pub struct Am(());
impl Am {
@ -47,7 +89,7 @@ impl Am { @@ -47,7 +89,7 @@ impl Am {
}
}
pub fn get_title_list(&self, mediatype: FsMediaType) -> crate::Result<Vec<u64>> {
pub fn get_title_list(&self, mediatype: FsMediaType) -> crate::Result<Vec<Title>> {
let count = self.get_title_count(mediatype)?;
let mut buf = Vec::with_capacity(count as usize);
let mut read_amount = 0;
@ -61,26 +103,14 @@ impl Am { @@ -61,26 +103,14 @@ impl Am {
buf.set_len(read_amount as usize);
}
Ok(buf)
}
pub fn get_title_info(
&self,
mediatype: FsMediaType,
id_list: &mut [u64],
) -> crate::Result<Vec<TitleInfo>> {
let mut info = Vec::with_capacity(id_list.len());
unsafe {
ResultCode(ctru_sys::AM_GetTitleInfo(
mediatype as u32,
id_list.len() as u32,
id_list.as_mut_ptr(),
info.as_mut_ptr() as _,
))?;
info.set_len(id_list.len());
}
Ok(info)
Ok(buf
.into_iter()
.map(|id| Title {
id,
mediatype,
_am: PhantomData,
})
.collect())
}
}

Loading…
Cancel
Save