|
|
@ -9,19 +9,26 @@ fn main() { |
|
|
|
let hid = Hid::init().expect("Couldn't obtain HID controller"); |
|
|
|
let hid = Hid::init().expect("Couldn't obtain HID controller"); |
|
|
|
let apt = Apt::init().expect("Couldn't obtain APT controller"); |
|
|
|
let apt = Apt::init().expect("Couldn't obtain APT controller"); |
|
|
|
let am = Am::init().expect("Couldn't obtain AM controller"); |
|
|
|
let am = Am::init().expect("Couldn't obtain AM controller"); |
|
|
|
let _console = Console::init(gfx.top_screen.borrow_mut()); |
|
|
|
let top_screen = Console::init(gfx.top_screen.borrow_mut()); |
|
|
|
|
|
|
|
let bottom_screen = Console::init(gfx.bottom_screen.borrow_mut()); |
|
|
|
|
|
|
|
|
|
|
|
let title_count = am |
|
|
|
let sd_count = am |
|
|
|
.get_title_count(FsMediaType::Sd) |
|
|
|
.get_title_count(FsMediaType::Sd) |
|
|
|
.expect("Failed to get title count"); |
|
|
|
.expect("Failed to get sd title count"); |
|
|
|
println!("This 3DS has {title_count} titles on its SD Card:"); |
|
|
|
let sd_list = am |
|
|
|
|
|
|
|
|
|
|
|
let title_list = am |
|
|
|
|
|
|
|
.get_title_list(FsMediaType::Sd) |
|
|
|
.get_title_list(FsMediaType::Sd) |
|
|
|
.expect("Failed to get title list"); |
|
|
|
.expect("Failed to get sd title list"); |
|
|
|
for id in title_list { |
|
|
|
|
|
|
|
println!("{id:x}"); |
|
|
|
let nand_count = am |
|
|
|
} |
|
|
|
.get_title_count(FsMediaType::Nand) |
|
|
|
|
|
|
|
.expect("Failed to get nand title count"); |
|
|
|
|
|
|
|
let nand_list = am |
|
|
|
|
|
|
|
.get_title_list(FsMediaType::Nand) |
|
|
|
|
|
|
|
.expect("Failed to get nand title list"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut offset = 0; |
|
|
|
|
|
|
|
let mut refresh = true; |
|
|
|
|
|
|
|
let mut use_nand = false; |
|
|
|
|
|
|
|
|
|
|
|
// Main loop
|
|
|
|
// Main loop
|
|
|
|
while apt.main_loop() { |
|
|
|
while apt.main_loop() { |
|
|
@ -31,6 +38,77 @@ fn main() { |
|
|
|
if hid.keys_down().contains(KeyPad::KEY_START) { |
|
|
|
if hid.keys_down().contains(KeyPad::KEY_START) { |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if hid.keys_down().contains(KeyPad::KEY_SELECT) { |
|
|
|
|
|
|
|
refresh = true; |
|
|
|
|
|
|
|
offset = 0; |
|
|
|
|
|
|
|
use_nand = !use_nand; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let cur_list = if use_nand { &nand_list } else { &sd_list }; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if hid.keys_down().intersects(KeyPad::KEY_DOWN) { |
|
|
|
|
|
|
|
if offset + 1 < cur_list.len() { |
|
|
|
|
|
|
|
offset = offset + 1; |
|
|
|
|
|
|
|
refresh = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} else if hid.keys_down().intersects(KeyPad::KEY_UP) { |
|
|
|
|
|
|
|
if offset > 0 { |
|
|
|
|
|
|
|
offset = offset - 1; |
|
|
|
|
|
|
|
refresh = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if refresh { |
|
|
|
|
|
|
|
let mut selected_title = 0; |
|
|
|
|
|
|
|
// 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() { |
|
|
|
|
|
|
|
if i == 0 { |
|
|
|
|
|
|
|
selected_title = *id; |
|
|
|
|
|
|
|
println!("=> {id:x}"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
println!(" {id:x}"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Clear bottom screen and write properties of selected title to it
|
|
|
|
|
|
|
|
bottom_screen.select(); |
|
|
|
|
|
|
|
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]) { |
|
|
|
|
|
|
|
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), |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
println!("\x1b[26;0HPress START to exit"); |
|
|
|
|
|
|
|
if use_nand { |
|
|
|
|
|
|
|
println!("Press SELECT to choose SD Card"); |
|
|
|
|
|
|
|
println!("Current medium: NAND"); |
|
|
|
|
|
|
|
println!("Title count: {}", nand_count); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
println!("Press SELECT to choose NAND"); |
|
|
|
|
|
|
|
println!("Current medium: SD Card"); |
|
|
|
|
|
|
|
println!("Title count: {}", sd_count); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
refresh = false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Flush and swap framebuffers
|
|
|
|
// Flush and swap framebuffers
|
|
|
|
gfx.flush_buffers(); |
|
|
|
gfx.flush_buffers(); |
|
|
|
gfx.swap_buffers(); |
|
|
|
gfx.swap_buffers(); |
|
|
|