Browse Source

Merge pull request #116 from rust3ds/improve/api

Second wave of API changes
pull/126/head
Meziu 2 years ago committed by GitHub
parent
commit
ca8f13d28c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 14
      ctru-rs/examples/audio-filters.rs
  2. 11
      ctru-rs/examples/buttons.rs
  3. 34
      ctru-rs/examples/camera-image.rs
  4. 16
      ctru-rs/examples/file-explorer.rs
  5. 10
      ctru-rs/examples/futures-basic.rs
  6. 10
      ctru-rs/examples/futures-tokio.rs
  7. 22
      ctru-rs/examples/gfx-3d-mode.rs
  8. 74
      ctru-rs/examples/gfx-bitmap.rs
  9. 12
      ctru-rs/examples/gfx-wide-mode.rs
  10. 14
      ctru-rs/examples/graphics-bitmap.rs
  11. 10
      ctru-rs/examples/hashmaps.rs
  12. 12
      ctru-rs/examples/hello-both-screens.rs
  13. 11
      ctru-rs/examples/hello-world.rs
  14. 11
      ctru-rs/examples/linear-memory.rs
  15. 13
      ctru-rs/examples/mii-selector.rs
  16. 10
      ctru-rs/examples/network-sockets.rs
  17. 11
      ctru-rs/examples/output-3dslink.rs
  18. 13
      ctru-rs/examples/romfs.rs
  19. 12
      ctru-rs/examples/software-keyboard.rs
  20. 13
      ctru-rs/examples/system-configuration.rs
  21. 10
      ctru-rs/examples/thread-basic.rs
  22. 10
      ctru-rs/examples/thread-info.rs
  23. 10
      ctru-rs/examples/thread-locals.rs
  24. 12
      ctru-rs/examples/time-rtc.rs
  25. 16
      ctru-rs/examples/title-info.rs
  26. 49
      ctru-rs/examples/touch-screen.rs
  27. 54
      ctru-rs/src/applets/mii_selector.rs
  28. 13
      ctru-rs/src/applets/swkbd.rs
  29. 6
      ctru-rs/src/console.rs
  30. 2
      ctru-rs/src/lib.rs
  31. 3
      ctru-rs/src/services/am.rs
  32. 2
      ctru-rs/src/services/apt.rs
  33. 27
      ctru-rs/src/services/cam.rs
  34. 32
      ctru-rs/src/services/cfgu.rs
  35. 33
      ctru-rs/src/services/fs.rs
  36. 173
      ctru-rs/src/services/gfx.rs
  37. 4
      ctru-rs/src/services/gspgpu.rs
  38. 75
      ctru-rs/src/services/hid.rs
  39. 12
      ctru-rs/src/services/ndsp/mod.rs
  40. 2
      ctru-rs/src/services/ndsp/wave.rs
  41. 4
      ctru-rs/src/services/ps.rs
  42. 4
      ctru-rs/src/services/romfs.rs
  43. 6
      ctru-rs/src/services/soc.rs
  44. 13
      ctru-rs/src/services/sslc.rs
  45. 10
      ctru-rs/src/test_runner.rs

14
ctru-rs/examples/audio-filters.rs

@ -37,10 +37,10 @@ fn fill_buffer(audio_data: &mut [u8], frequency: f32) { @@ -37,10 +37,10 @@ fn fill_buffer(audio_data: &mut [u8], frequency: f32) {
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
let mut note: usize = 4;
@ -68,7 +68,7 @@ fn main() { @@ -68,7 +68,7 @@ fn main() {
let mut wave_info1 = Wave::new(audio_data1, AudioFormat::PCM16Stereo, false);
let mut wave_info2 = Wave::new(audio_data2, AudioFormat::PCM16Stereo, false);
let mut ndsp = Ndsp::init().expect("Couldn't obtain NDSP controller");
let mut ndsp = Ndsp::new().expect("Couldn't obtain NDSP controller");
// This line isn't needed since the default NDSP configuration already sets the output mode to `Stereo`
ndsp.set_output_mode(OutputMode::Stereo);
@ -154,10 +154,6 @@ fn main() { @@ -154,10 +154,6 @@ fn main() {
altern = !altern;
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();
}

11
ctru-rs/examples/buttons.rs

@ -3,10 +3,10 @@ use ctru::prelude::*; @@ -3,10 +3,10 @@ use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let apt = Apt::init().unwrap();
let mut hid = Hid::init().unwrap();
let gfx = Gfx::init().unwrap();
let console = Console::init(gfx.top_screen.borrow_mut());
let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
let console = Console::new(gfx.top_screen.borrow_mut());
println!("Hi there! Try pressing a button");
println!("\x1b[29;16HPress Start to exit");
@ -63,9 +63,6 @@ fn main() { @@ -63,9 +63,6 @@ fn main() {
// Save our current key presses for the next frame
old_keys = keys;
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

34
ctru-rs/examples/camera-image.rs

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
use ctru::prelude::*;
use ctru::services::cam::{Cam, Camera, OutputFormat, ShutterSound, ViewSize};
use ctru::services::gfx::Screen;
use ctru::services::gfx::{Flush, Screen, Swap};
use ctru::services::gspgpu::FramebufferFormat;
use std::time::Duration;
@ -16,22 +16,21 @@ const WAIT_TIMEOUT: Duration = Duration::from_millis(300); @@ -16,22 +16,21 @@ const WAIT_TIMEOUT: Duration = Duration::from_millis(300);
fn main() {
ctru::use_panic_handler();
let apt = Apt::init().expect("Failed to initialize Apt service.");
let mut hid = Hid::init().expect("Failed to initialize Hid service.");
let gfx = Gfx::init().expect("Failed to initialize GFX service.");
let apt = Apt::new().expect("Failed to initialize Apt service.");
let mut hid = Hid::new().expect("Failed to initialize Hid service.");
let gfx = Gfx::new().expect("Failed to initialize GFX service.");
gfx.top_screen.borrow_mut().set_double_buffering(true);
gfx.top_screen
.borrow_mut()
.set_framebuffer_format(FramebufferFormat::Rgb565);
gfx.bottom_screen.borrow_mut().set_double_buffering(false);
let _console = Console::init(gfx.bottom_screen.borrow_mut());
let mut top_screen = gfx.top_screen.borrow_mut();
top_screen.set_double_buffering(true);
top_screen.set_framebuffer_format(FramebufferFormat::Rgb565);
let _console = Console::new(gfx.bottom_screen.borrow_mut());
let mut keys_down;
println!("Initializing camera");
let mut cam = Cam::init().expect("Failed to initialize CAM service.");
let mut cam = Cam::new().expect("Failed to initialize CAM service.");
{
let camera = &mut cam.outer_right_cam;
@ -86,15 +85,12 @@ fn main() { @@ -86,15 +85,12 @@ fn main() {
cam.play_shutter_sound(ShutterSound::Normal)
.expect("Failed to play shutter sound");
rotate_image_to_screen(
&buf,
gfx.top_screen.borrow_mut().raw_framebuffer().ptr,
WIDTH,
HEIGHT,
);
rotate_image_to_screen(&buf, top_screen.raw_framebuffer().ptr, WIDTH, HEIGHT);
// We will only flush the "camera" screen, since the other screen is handled by `Console`
top_screen.flush_buffers();
top_screen.swap_buffers();
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

16
ctru-rs/examples/file-explorer.rs

@ -11,14 +11,14 @@ use std::path::{Path, PathBuf}; @@ -11,14 +11,14 @@ use std::path::{Path, PathBuf};
fn main() {
ctru::use_panic_handler();
let apt = Apt::init().unwrap();
let mut hid = Hid::init().unwrap();
let gfx = Gfx::init().unwrap();
let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
#[cfg(all(feature = "romfs", romfs_exists))]
let _romfs = ctru::services::romfs::RomFS::init().unwrap();
let _romfs = ctru::services::romfs::RomFS::new().unwrap();
FileExplorer::init(&apt, &mut hid, &gfx).run();
FileExplorer::new(&apt, &mut hid, &gfx).run();
}
struct FileExplorer<'a> {
@ -32,10 +32,10 @@ struct FileExplorer<'a> { @@ -32,10 +32,10 @@ struct FileExplorer<'a> {
}
impl<'a> FileExplorer<'a> {
fn init(apt: &'a Apt, hid: &'a mut Hid, gfx: &'a Gfx) -> Self {
fn new(apt: &'a Apt, hid: &'a mut Hid, gfx: &'a Gfx) -> Self {
let mut top_screen = gfx.top_screen.borrow_mut();
top_screen.set_wide_mode(true);
let console = Console::init(top_screen);
let console = Console::new(top_screen);
FileExplorer {
apt,
@ -68,8 +68,6 @@ impl<'a> FileExplorer<'a> { @@ -68,8 +68,6 @@ impl<'a> FileExplorer<'a> {
self.get_input_and_run(Self::set_exact_path);
}
self.gfx.flush_buffers();
self.gfx.swap_buffers();
self.gfx.wait_for_vblank();
}
}

10
ctru-rs/examples/futures-basic.rs

@ -15,10 +15,10 @@ use std::os::horizon::thread::BuilderExt; @@ -15,10 +15,10 @@ use std::os::horizon::thread::BuilderExt;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
// Give ourselves up to 30% of the system core's time
apt.set_app_cpu_time_limit(30)
@ -68,8 +68,6 @@ fn main() { @@ -68,8 +68,6 @@ fn main() {
frame_count = 0;
}
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

10
ctru-rs/examples/futures-tokio.rs

@ -8,10 +8,10 @@ use std::time::Duration; @@ -8,10 +8,10 @@ use std::time::Duration;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
// Give ourselves up to 30% of the system core's time
apt.set_app_cpu_time_limit(30)
@ -63,8 +63,6 @@ fn main() { @@ -63,8 +63,6 @@ fn main() {
break;
}
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

22
ctru-rs/examples/gfx-3d-mode.rs

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
use ctru::prelude::*;
use ctru::services::gfx::{Screen, Side, TopScreen3D};
use ctru::services::gfx::{Flush, Screen, Side, Swap, TopScreen3D};
/// See `graphics-bitmap.rs` for details on how the image is generated.
///
@ -12,17 +12,16 @@ static ZERO: &[u8] = &[0; IMAGE.len()]; @@ -12,17 +12,16 @@ static ZERO: &[u8] = &[0; IMAGE.len()];
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.bottom_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.bottom_screen.borrow_mut());
println!("Press Start to exit.\nPress A to switch sides (be sure to have 3D mode enabled).");
gfx.top_screen.borrow_mut().set_double_buffering(true);
let top_screen = TopScreen3D::from(&gfx.top_screen);
let (mut left, mut right) = top_screen.split_mut();
let mut top_screen = TopScreen3D::from(&gfx.top_screen);
let mut current_side = Side::Left;
@ -35,6 +34,8 @@ fn main() { @@ -35,6 +34,8 @@ fn main() {
break;
}
let (mut left, mut right) = top_screen.split_mut();
let left_buf = left.raw_framebuffer();
let right_buf = right.raw_framebuffer();
@ -61,9 +62,10 @@ fn main() { @@ -61,9 +62,10 @@ fn main() {
buf.copy_from(IMAGE.as_ptr(), IMAGE.len());
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
drop((left, right));
top_screen.flush_buffers();
top_screen.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();

74
ctru-rs/examples/gfx-bitmap.rs

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
use ctru::prelude::*;
use ctru::services::gfx::{Flush, Screen, Swap};
/// Ferris image taken from <https://rustacean.net> and scaled down to 320x240px.
/// To regenerate the data, you will need to install `imagemagick` and run this
/// command from the `examples` directory:
///
/// ```sh
/// magick assets/ferris.png -channel-fx "red<=>blue" -rotate 90 assets/ferris.rgb
/// ```
///
/// This creates an image appropriate for the default frame buffer format of
/// [`Bgr8`](ctru::services::gspgpu::FramebufferFormat::Bgr8)
/// and rotates the image 90° to account for the portrait mode screen.
static IMAGE: &[u8] = include_bytes!("assets/ferris.rgb");
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
println!("\x1b[21;4HPress Start to exit, or A to flip the image.");
let mut bottom_screen = gfx.bottom_screen.borrow_mut();
// We don't need double buffering in this example.
// In this way we can draw our image only once on screen.
bottom_screen.set_double_buffering(false);
// Swapping buffers commits the change from the line above.
bottom_screen.swap_buffers();
// 3 bytes per pixel, we just want to reverse the pixels but not individual bytes
let flipped_image: Vec<_> = IMAGE.chunks(3).rev().flatten().copied().collect();
let mut image_bytes = IMAGE;
// 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::START) {
break;
}
// We assume the image is the correct size already, so we drop width + height.
let frame_buffer = bottom_screen.raw_framebuffer();
if hid.keys_down().contains(KeyPad::A) {
image_bytes = if std::ptr::eq(image_bytes, IMAGE) {
&flipped_image[..]
} else {
IMAGE
};
}
// this copies more than necessary (once per frame) but it's fine...
unsafe {
frame_buffer
.ptr
.copy_from(image_bytes.as_ptr(), image_bytes.len());
}
// Flush framebuffers. Since we're not using double buffering,
// this will render the pixels immediately
bottom_screen.flush_buffers();
//Wait for VBlank
gfx.wait_for_vblank();
}
}

12
ctru-rs/examples/gfx-wide-mode.rs

@ -3,10 +3,10 @@ use ctru::prelude::*; @@ -3,10 +3,10 @@ use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let apt = Apt::init().unwrap();
let mut hid = Hid::init().unwrap();
let gfx = Gfx::init().unwrap();
let mut console = Console::init(gfx.top_screen.borrow_mut());
let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
let mut console = Console::new(gfx.top_screen.borrow_mut());
println!("Press A to enable/disable wide screen mode.");
@ -23,12 +23,10 @@ fn main() { @@ -23,12 +23,10 @@ fn main() {
let wide_mode = gfx.top_screen.borrow().is_wide();
gfx.top_screen.borrow_mut().set_wide_mode(!wide_mode);
console = Console::init(gfx.top_screen.borrow_mut());
console = Console::new(gfx.top_screen.borrow_mut());
println!("Press A to enable/disable wide screen mode.");
}
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

14
ctru-rs/examples/graphics-bitmap.rs

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
use ctru::prelude::*;
use ctru::services::gfx::Screen;
use ctru::services::gfx::{Flush, Screen, Swap};
/// Ferris image taken from <https://rustacean.net> and scaled down to 320x240px.
/// To regenerate the data, you will need to install `imagemagick` and run this
@ -17,10 +17,10 @@ static IMAGE: &[u8] = include_bytes!("assets/ferris.rgb"); @@ -17,10 +17,10 @@ static IMAGE: &[u8] = include_bytes!("assets/ferris.rgb");
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
println!("\x1b[21;16HPress Start to exit.");
@ -48,8 +48,8 @@ fn main() { @@ -48,8 +48,8 @@ fn main() {
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
bottom_screen.flush_buffers();
bottom_screen.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();

10
ctru-rs/examples/hashmaps.rs

@ -8,10 +8,10 @@ fn main() { @@ -8,10 +8,10 @@ fn main() {
// 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.
let apt = Apt::init().unwrap();
let mut hid = Hid::init().unwrap();
let gfx = Gfx::init().unwrap();
let _console = Console::init(gfx.top_screen.borrow_mut());
let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
let _console = Console::new(gfx.top_screen.borrow_mut());
let mut map = std::collections::HashMap::new();
map.insert("A Key!", 102);
@ -21,8 +21,6 @@ fn main() { @@ -21,8 +21,6 @@ fn main() {
println!("{map:#?}");
while apt.main_loop() {
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
hid.scan_input();

12
ctru-rs/examples/hello-both-screens.rs

@ -3,16 +3,16 @@ use ctru::prelude::*; @@ -3,16 +3,16 @@ use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let apt = Apt::init().unwrap();
let mut hid = Hid::init().unwrap();
let gfx = Gfx::init().unwrap();
let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
// Start a console on the top screen
let top_screen = Console::init(gfx.top_screen.borrow_mut());
let top_screen = Console::new(gfx.top_screen.borrow_mut());
// Start a console on the bottom screen.
// The most recently initialized console will be active by default
let bottom_screen = Console::init(gfx.bottom_screen.borrow_mut());
let bottom_screen = Console::new(gfx.bottom_screen.borrow_mut());
// Let's print on the top screen first
top_screen.select();
@ -27,8 +27,6 @@ fn main() { @@ -27,8 +27,6 @@ fn main() {
println!("\x1b[29;16HPress Start to exit");
while apt.main_loop() {
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
hid.scan_input();

11
ctru-rs/examples/hello-world.rs

@ -5,10 +5,10 @@ use std::io::BufWriter; @@ -5,10 +5,10 @@ use std::io::BufWriter;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
let out = b"Hello fellow Rustaceans, I'm on the Nintendo 3DS!";
let width = 24;
@ -29,9 +29,6 @@ fn main() { @@ -29,9 +29,6 @@ fn main() {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();

11
ctru-rs/examples/linear-memory.rs

@ -6,10 +6,10 @@ use ctru::prelude::*; @@ -6,10 +6,10 @@ use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
let linear_space_before = LinearAllocator::free_space();
@ -37,9 +37,6 @@ fn main() { @@ -37,9 +37,6 @@ fn main() {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();

13
ctru-rs/examples/mii-selector.rs

@ -4,12 +4,12 @@ use ctru::prelude::*; @@ -4,12 +4,12 @@ use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
let mut mii_selector = MiiSelector::init();
let mut mii_selector = MiiSelector::new();
mii_selector.set_initial_index(3);
mii_selector.blacklist_user_mii(0.into());
mii_selector.set_title("Great Mii Selector!");
@ -33,9 +33,6 @@ fn main() { @@ -33,9 +33,6 @@ fn main() {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();

10
ctru-rs/examples/network-sockets.rs

@ -7,14 +7,14 @@ use std::time::Duration; @@ -7,14 +7,14 @@ use std::time::Duration;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().unwrap();
let _console = Console::init(gfx.top_screen.borrow_mut());
let mut hid = Hid::init().unwrap();
let apt = Apt::init().unwrap();
let gfx = Gfx::new().unwrap();
let _console = Console::new(gfx.top_screen.borrow_mut());
let mut hid = Hid::new().unwrap();
let apt = Apt::new().unwrap();
println!("\nlibctru sockets demo\n");
let soc = Soc::init().unwrap();
let soc = Soc::new().unwrap();
let server = TcpListener::bind("0.0.0.0:80").unwrap();
server.set_nonblocking(true).unwrap();

11
ctru-rs/examples/output-3dslink.rs

@ -13,11 +13,11 @@ use ctru::prelude::*; @@ -13,11 +13,11 @@ use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let mut soc = Soc::init().expect("Couldn't obtain SOC controller");
let mut soc = Soc::new().expect("Couldn't obtain SOC controller");
soc.redirect_to_3dslink(true, true)
.expect("unable to redirect stdout/err to 3dslink server");
@ -33,9 +33,6 @@ fn main() { @@ -33,9 +33,6 @@ fn main() {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();

13
ctru-rs/examples/romfs.rs

@ -3,17 +3,17 @@ use ctru::prelude::*; @@ -3,17 +3,17 @@ use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
cfg_if::cfg_if! {
// Run this code if RomFS are wanted and available
// This never fails as `ctru-rs` examples inherit all of the `ctru` features,
// but it might if a normal user application wasn't setup correctly
if #[cfg(all(feature = "romfs", romfs_exists))] {
let _romfs = ctru::services::romfs::RomFS::init().unwrap();
let _romfs = ctru::services::romfs::RomFS::new().unwrap();
let f = std::fs::read_to_string("romfs:/test-file.txt").unwrap();
println!("Contents of test-file.txt: \n{f}\n");
@ -36,9 +36,6 @@ fn main() { @@ -36,9 +36,6 @@ fn main() {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();

12
ctru-rs/examples/software-keyboard.rs

@ -4,23 +4,21 @@ use ctru::prelude::*; @@ -4,23 +4,21 @@ use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let apt = Apt::init().unwrap();
let mut hid = Hid::init().unwrap();
let gfx = Gfx::init().unwrap();
let _console = Console::init(gfx.top_screen.borrow_mut());
let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
let _console = Console::new(gfx.top_screen.borrow_mut());
println!("Press A to enter some text or press Start to quit");
while apt.main_loop() {
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
hid.scan_input();
if hid.keys_down().contains(KeyPad::A) {
// Prepares a software keyboard with two buttons: One to cancel input and one
// to accept it. You can also use `Swkbd::init()` to launch the keyboard in different
// to accept it. You can also use `Swkbd::new()` to launch the keyboard in different
// configurations.
let mut keyboard = Swkbd::default();

13
ctru-rs/examples/system-configuration.rs

@ -4,11 +4,11 @@ use ctru::services::cfgu::Cfgu; @@ -4,11 +4,11 @@ use ctru::services::cfgu::Cfgu;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let cfgu = Cfgu::init().expect("Couldn't obtain CFGU controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let cfgu = Cfgu::new().expect("Couldn't obtain CFGU controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
println!("\x1b[0;0HRegion: {:?}", cfgu.region().unwrap());
println!("\x1b[10;0HLanguage: {:?}", cfgu.language().unwrap());
@ -22,9 +22,6 @@ fn main() { @@ -22,9 +22,6 @@ fn main() {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();

10
ctru-rs/examples/thread-basic.rs

@ -8,10 +8,10 @@ use std::time::Duration; @@ -8,10 +8,10 @@ use std::time::Duration;
fn main() {
ctru::use_panic_handler();
let apt = Apt::init().unwrap();
let mut hid = Hid::init().unwrap();
let gfx = Gfx::init().unwrap();
let _console = Console::init(gfx.top_screen.borrow_mut());
let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
let _console = Console::new(gfx.top_screen.borrow_mut());
let prio = std::os::horizon::thread::current_priority();
println!("Main thread prio: {}\n", prio);
@ -34,8 +34,6 @@ fn main() { @@ -34,8 +34,6 @@ fn main() {
}
while apt.main_loop() {
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
hid.scan_input();

10
ctru-rs/examples/thread-info.rs

@ -9,10 +9,10 @@ use std::os::horizon::thread::BuilderExt; @@ -9,10 +9,10 @@ use std::os::horizon::thread::BuilderExt;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
// Give ourselves up to 30% of the system core's time
apt.set_app_cpu_time_limit(30)
@ -45,8 +45,6 @@ fn main() { @@ -45,8 +45,6 @@ fn main() {
break;
}
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

10
ctru-rs/examples/thread-locals.rs

@ -12,11 +12,11 @@ std::thread_local! { @@ -12,11 +12,11 @@ std::thread_local! {
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
gfx.top_screen.borrow_mut().set_wide_mode(true);
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::new(gfx.top_screen.borrow_mut());
// Give ourselves up to 30% of the system core's time
apt.set_app_cpu_time_limit(30)
@ -61,8 +61,6 @@ fn main() { @@ -61,8 +61,6 @@ fn main() {
break;
}
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
}
}

12
ctru-rs/examples/time-rtc.rs

@ -3,11 +3,11 @@ use ctru::prelude::*; @@ -3,11 +3,11 @@ use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut hid = Hid::init().expect("Couldn't obtain HID controller");
let apt = Apt::init().expect("Couldn't obtain APT controller");
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
let _console = Console::new(gfx.top_screen.borrow_mut());
print!("\x1b[30;16HPress Start to exit.");
@ -36,10 +36,6 @@ fn main() { @@ -36,10 +36,6 @@ fn main() {
println!("\x1b[1;1H{hours:0>2}:{minutes:0>2}:{seconds:0>2}");
println!("{weekday} {month} {day} {year}");
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();
}

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

@ -5,12 +5,12 @@ use ctru::services::fs::FsMediaType; @@ -5,12 +5,12 @@ use ctru::services::fs::FsMediaType;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::init().expect("Couldn't obtain GFX controller");
let mut 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 top_screen = Console::init(gfx.top_screen.borrow_mut());
let bottom_screen = Console::init(gfx.bottom_screen.borrow_mut());
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let am = Am::new().expect("Couldn't obtain AM controller");
let top_screen = Console::new(gfx.top_screen.borrow_mut());
let bottom_screen = Console::new(gfx.bottom_screen.borrow_mut());
let sd_count = am
.title_count(FsMediaType::Sd)
@ -106,10 +106,6 @@ fn main() { @@ -106,10 +106,6 @@ fn main() {
refresh = false;
}
// Flush and swap framebuffers
gfx.flush_buffers();
gfx.swap_buffers();
//Wait for VBlank
gfx.wait_for_vblank();
}

49
ctru-rs/examples/touch-screen.rs

@ -0,0 +1,49 @@ @@ -0,0 +1,49 @@
use ctru::prelude::*;
fn main() {
ctru::use_panic_handler();
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
let console = Console::new(gfx.top_screen.borrow_mut());
// We'll hold the previous touch position for comparison.
let mut old_touch: (u16, u16) = (0, 0);
println!("\x1b[29;16HPress Start to exit");
while apt.main_loop() {
hid.scan_input();
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Get X and Y coordinates of the touch point.
// The touch screen is 320x240.
let touch: (u16, u16) = hid.touch_position();
// We only want to print the position when it's different
// from what it was on the previous frame
if touch != old_touch {
// Special case for when the user lifts the stylus/finger from the screen.
// This is done to avoid some screen tearing.
if touch == (0, 0) {
console.clear();
// Print again because we just cleared the screen
println!("\x1b[29;16HPress Start to exit");
}
// Move the cursor back to the top of the screen and print the coordinates
print!("\x1b[1;1HTouch Screen position: {:#?}", touch);
}
// Save our current touch position for the next frame
old_touch = touch;
gfx.wait_for_vblank();
}
}

54
ctru-rs/src/applets/mii_selector.rs

@ -8,14 +8,14 @@ use std::ffi::CString; @@ -8,14 +8,14 @@ use std::ffi::CString;
/// Index of a Mii used to configure some parameters of the Mii Selector
/// Can be either a single index, or _all_ Miis
#[derive(Debug, Clone)]
pub enum MiiConfigIndex {
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum Index {
Index(u32),
All,
}
/// The type of a Mii with their respective data
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum MiiType {
Guest { index: u32, name: String },
User,
@ -41,7 +41,7 @@ bitflags! { @@ -41,7 +41,7 @@ bitflags! {
/// ```
/// use ctru::applets::mii_selector::MiiSelector;
///
/// let mut mii_selector = MiiSelector::init();
/// let mut mii_selector = MiiSelector::new();
/// mii_selector.set_title("Example Mii selector");
///
/// let result = mii_selector.launch().unwrap();
@ -54,7 +54,7 @@ pub struct MiiSelector { @@ -54,7 +54,7 @@ pub struct MiiSelector {
/// Return value from a MiiSelector's launch
#[non_exhaustive]
#[derive(Clone, Debug)]
pub struct MiiSelectorReturn {
pub struct SelectionResult {
pub mii_data: MiiData,
pub is_mii_selected: bool,
pub mii_type: MiiType,
@ -62,13 +62,13 @@ pub struct MiiSelectorReturn { @@ -62,13 +62,13 @@ pub struct MiiSelectorReturn {
/// Error type for the Mii selector
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum MiiLaunchError {
pub enum LaunchError {
InvalidChecksum,
}
impl MiiSelector {
/// Initializes a Mii Selector
pub fn init() -> Self {
pub fn new() -> Self {
let mut config = Box::<ctru_sys::MiiSelectorConf>::default();
unsafe {
ctru_sys::miiSelectorInit(config.as_mut());
@ -94,40 +94,40 @@ impl MiiSelector { @@ -94,40 +94,40 @@ impl MiiSelector {
}
/// Whitelist a guest Mii
pub fn whitelist_guest_mii(&mut self, mii_index: MiiConfigIndex) {
pub fn whitelist_guest_mii(&mut self, mii_index: Index) {
let index = match mii_index {
MiiConfigIndex::Index(i) => i,
MiiConfigIndex::All => ctru_sys::MIISELECTOR_GUESTMII_SLOTS,
Index::Index(i) => i,
Index::All => ctru_sys::MIISELECTOR_GUESTMII_SLOTS,
};
unsafe { ctru_sys::miiSelectorWhitelistGuestMii(self.config.as_mut(), index) }
}
/// Blacklist a guest Mii
pub fn blacklist_guest_mii(&mut self, mii_index: MiiConfigIndex) {
pub fn blacklist_guest_mii(&mut self, mii_index: Index) {
let index = match mii_index {
MiiConfigIndex::Index(i) => i,
MiiConfigIndex::All => ctru_sys::MIISELECTOR_GUESTMII_SLOTS,
Index::Index(i) => i,
Index::All => ctru_sys::MIISELECTOR_GUESTMII_SLOTS,
};
unsafe { ctru_sys::miiSelectorBlacklistGuestMii(self.config.as_mut(), index) }
}
/// Whitelist a user Mii
pub fn whitelist_user_mii(&mut self, mii_index: MiiConfigIndex) {
pub fn whitelist_user_mii(&mut self, mii_index: Index) {
let index = match mii_index {
MiiConfigIndex::Index(i) => i,
MiiConfigIndex::All => ctru_sys::MIISELECTOR_USERMII_SLOTS,
Index::Index(i) => i,
Index::All => ctru_sys::MIISELECTOR_USERMII_SLOTS,
};
unsafe { ctru_sys::miiSelectorWhitelistUserMii(self.config.as_mut(), index) }
}
/// Blacklist a user Mii
pub fn blacklist_user_mii(&mut self, mii_index: MiiConfigIndex) {
pub fn blacklist_user_mii(&mut self, mii_index: Index) {
let index = match mii_index {
MiiConfigIndex::Index(i) => i,
MiiConfigIndex::All => ctru_sys::MIISELECTOR_USERMII_SLOTS,
Index::Index(i) => i,
Index::All => ctru_sys::MIISELECTOR_USERMII_SLOTS,
};
unsafe { ctru_sys::miiSelectorBlacklistUserMii(self.config.as_mut(), index) }
@ -143,24 +143,30 @@ impl MiiSelector { @@ -143,24 +143,30 @@ impl MiiSelector {
/// Launch the Mii Selector.
/// Returns an error when the checksum of the Mii is invalid.
pub fn launch(&mut self) -> Result<MiiSelectorReturn, MiiLaunchError> {
pub fn launch(&mut self) -> Result<SelectionResult, LaunchError> {
let mut return_val = Box::<ctru_sys::MiiSelectorReturn>::default();
unsafe { ctru_sys::miiSelectorLaunch(self.config.as_mut(), return_val.as_mut()) }
if unsafe { ctru_sys::miiSelectorChecksumIsValid(return_val.as_mut()) } {
Ok((*return_val).into())
} else {
Err(MiiLaunchError::InvalidChecksum)
Err(LaunchError::InvalidChecksum)
}
}
}
impl From<ctru_sys::MiiSelectorReturn> for MiiSelectorReturn {
impl Default for MiiSelector {
fn default() -> Self {
Self::new()
}
}
impl From<ctru_sys::MiiSelectorReturn> for SelectionResult {
fn from(ret: ctru_sys::MiiSelectorReturn) -> Self {
let raw_mii_data = ret.mii;
let mut guest_mii_name = ret.guest_mii_name;
MiiSelectorReturn {
SelectionResult {
mii_data: raw_mii_data.into(),
is_mii_selected: ret.no_mii_selected == 0,
mii_type: if ret.guest_mii_index != 0xFFFFFFFF {
@ -179,7 +185,7 @@ impl From<ctru_sys::MiiSelectorReturn> for MiiSelectorReturn { @@ -179,7 +185,7 @@ impl From<ctru_sys::MiiSelectorReturn> for MiiSelectorReturn {
}
}
impl From<u32> for MiiConfigIndex {
impl From<u32> for Index {
fn from(v: u32) -> Self {
Self::Index(v)
}

13
ctru-rs/src/applets/swkbd.rs

@ -7,6 +7,7 @@ use std::iter::once; @@ -7,6 +7,7 @@ use std::iter::once;
use std::str;
/// An instance of the software keyboard.
#[derive(Clone)]
pub struct Swkbd {
state: Box<SwkbdState>,
}
@ -18,7 +19,7 @@ pub struct Swkbd { @@ -18,7 +19,7 @@ pub struct Swkbd {
/// Numpad is a number pad.
/// Western is a text keyboard without japanese symbols (only applies to JPN systems). For other
/// systems it's the same as a Normal keyboard.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Kind {
Normal = ctru_sys::SWKBD_TYPE_NORMAL,
@ -28,7 +29,7 @@ pub enum Kind { @@ -28,7 +29,7 @@ pub enum Kind {
}
/// Represents which button the user pressed to close the software keyboard.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Button {
Left = ctru_sys::SWKBD_BUTTON_LEFT,
@ -37,7 +38,7 @@ pub enum Button { @@ -37,7 +38,7 @@ pub enum Button {
}
/// Error type for the software keyboard.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(i32)]
pub enum Error {
InvalidInput = ctru_sys::SWKBD_INVALID_INPUT,
@ -51,7 +52,7 @@ pub enum Error { @@ -51,7 +52,7 @@ pub enum Error {
}
/// Restrictions on keyboard input
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum ValidInput {
Anything = ctru_sys::SWKBD_ANYTHING,
@ -89,7 +90,7 @@ bitflags! { @@ -89,7 +90,7 @@ bitflags! {
impl Swkbd {
/// Initializes a software keyboard of the specified type and the chosen number of buttons
/// (from 1-3).
pub fn init(keyboard_type: Kind, num_buttons: i32) -> Self {
pub fn new(keyboard_type: Kind, num_buttons: i32) -> Self {
unsafe {
let mut state = Box::<SwkbdState>::default();
swkbdInit(state.as_mut(), keyboard_type.into(), num_buttons, -1);
@ -207,7 +208,7 @@ impl Swkbd { @@ -207,7 +208,7 @@ impl Swkbd {
impl Default for Swkbd {
fn default() -> Self {
Swkbd::init(Kind::Normal, 2)
Swkbd::new(Kind::Normal, 2)
}
}

6
ctru-rs/src/console.rs

@ -16,7 +16,11 @@ impl<'screen> Console<'screen> { @@ -16,7 +16,11 @@ impl<'screen> Console<'screen> {
/// Initialize a console on the chosen screen, overwriting whatever was on the screen
/// previously (including other consoles). The new console is automatically selected for
/// printing.
pub fn init(screen: RefMut<'screen, dyn Screen>) -> Self {
///
/// # Notes
///
/// [Console] automatically takes care of flushing and swapping buffers for its screen when printing.
pub fn new(screen: RefMut<'screen, dyn Screen>) -> Self {
let mut context = Box::<PrintConsole>::default();
unsafe { consoleInit(screen.as_raw(), context.as_mut()) };

2
ctru-rs/src/lib.rs

@ -54,7 +54,7 @@ fn panic_hook_setup() { @@ -54,7 +54,7 @@ fn panic_hook_setup() {
if main_thread == std::thread::current().id() && console::Console::exists() {
println!("\nPress SELECT to exit the software");
match Hid::init() {
match Hid::new() {
Ok(mut hid) => loop {
hid.scan_input();
let keys = hid.keys_down();

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

@ -6,6 +6,7 @@ use std::mem::MaybeUninit; @@ -6,6 +6,7 @@ use std::mem::MaybeUninit;
#[derive(Copy, Clone, Debug)]
#[repr(transparent)]
pub struct TitleInfo(ctru_sys::AM_TitleEntry);
impl TitleInfo {
pub fn id(&self) -> u64 {
self.0.titleID
@ -61,7 +62,7 @@ impl<'a> Title<'a> { @@ -61,7 +62,7 @@ impl<'a> Title<'a> {
pub struct Am(());
impl Am {
pub fn init() -> crate::Result<Am> {
pub fn new() -> crate::Result<Am> {
unsafe {
ResultCode(ctru_sys::amInit())?;
Ok(Am(()))

2
ctru-rs/src/services/apt.rs

@ -3,7 +3,7 @@ use crate::error::ResultCode; @@ -3,7 +3,7 @@ use crate::error::ResultCode;
pub struct Apt(());
impl Apt {
pub fn init() -> crate::Result<Apt> {
pub fn new() -> crate::Result<Apt> {
unsafe {
ResultCode(ctru_sys::aptInit())?;
Ok(Apt(()))

27
ctru-rs/src/services/cam.rs

@ -21,7 +21,7 @@ pub struct Cam { @@ -21,7 +21,7 @@ pub struct Cam {
}
/// Flag to pass to [Camera::flip_image]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum FlipMode {
None = ctru_sys::FLIP_NONE,
@ -31,7 +31,7 @@ pub enum FlipMode { @@ -31,7 +31,7 @@ pub enum FlipMode {
}
/// Flag to pass to [Camera::set_view_size]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum ViewSize {
TopLCD = ctru_sys::SIZE_CTR_TOP_LCD,
@ -48,7 +48,7 @@ pub enum ViewSize { @@ -48,7 +48,7 @@ pub enum ViewSize {
}
/// Flag to pass to [Camera::set_frame_rate]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum FrameRate {
Fps15 = ctru_sys::FRAME_RATE_15,
@ -68,7 +68,7 @@ pub enum FrameRate { @@ -68,7 +68,7 @@ pub enum FrameRate {
/// Flag to pass to [Camera::set_white_balance] or
/// [Camera::set_white_balance_without_base_up]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum WhiteBalance {
/// Normal
@ -86,7 +86,7 @@ pub enum WhiteBalance { @@ -86,7 +86,7 @@ pub enum WhiteBalance {
}
/// Flag to pass to [Camera::set_photo_mode]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum PhotoMode {
Normal = ctru_sys::PHOTO_MODE_NORMAL,
@ -97,7 +97,7 @@ pub enum PhotoMode { @@ -97,7 +97,7 @@ pub enum PhotoMode {
}
/// Flag to pass to [Camera::set_effect]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Effect {
None = ctru_sys::EFFECT_NONE,
@ -109,7 +109,7 @@ pub enum Effect { @@ -109,7 +109,7 @@ pub enum Effect {
}
/// Flag to pass to [Camera::set_contrast]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Contrast {
/// OFF
@ -121,7 +121,7 @@ pub enum Contrast { @@ -121,7 +121,7 @@ pub enum Contrast {
}
/// Flag to pass to [Camera::set_lens_correction]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum LensCorrection {
Off = ctru_sys::LENS_CORRECTION_DARK,
@ -130,7 +130,7 @@ pub enum LensCorrection { @@ -130,7 +130,7 @@ pub enum LensCorrection {
}
/// Flag to pass to [Camera::set_output_format]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum OutputFormat {
Yuv422 = ctru_sys::OUTPUT_YUV_422,
@ -138,7 +138,7 @@ pub enum OutputFormat { @@ -138,7 +138,7 @@ pub enum OutputFormat {
}
/// Flag to pass to [Cam::play_shutter_sound]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum ShutterSound {
Normal = ctru_sys::SHUTTER_SOUND_TYPE_NORMAL,
@ -169,6 +169,7 @@ impl TryFrom<OutputFormat> for FramebufferFormat { @@ -169,6 +169,7 @@ impl TryFrom<OutputFormat> for FramebufferFormat {
}
/// Struct containing coordinates passed to [Camera::set_trimming_params].
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct TrimmingParams {
x_start: i16,
y_start: i16,
@ -193,11 +194,11 @@ impl TrimmingParams { @@ -193,11 +194,11 @@ impl TrimmingParams {
}
/// Represents data used by the camera to calibrate image quality
#[derive(Default)]
#[derive(Default, Clone, Copy, Debug)]
pub struct ImageQualityCalibrationData(pub ctru_sys::CAMU_ImageQualityCalibrationData);
/// Represents data used by the camera to calibrate image quality when using both outward cameras
#[derive(Default)]
#[derive(Default, Clone, Copy, Debug)]
pub struct StereoCameraCalibrationData(pub ctru_sys::CAMU_StereoCameraCalibrationData);
/// Represents the camera on the inside of the 3DS
@ -770,7 +771,7 @@ impl Cam { @@ -770,7 +771,7 @@ impl Cam {
/// This function will return an error if the service was unable to be initialized.
/// Since this service requires no special or elevated permissions, errors are
/// rare in practice.
pub fn init() -> crate::Result<Cam> {
pub fn new() -> crate::Result<Cam> {
unsafe {
ResultCode(ctru_sys::camInit())?;
Ok(Cam {

32
ctru-rs/src/services/cfgu.rs

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
use crate::error::ResultCode;
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Region {
Japan = ctru_sys::CFG_REGION_JPN,
@ -16,7 +16,7 @@ pub enum Region { @@ -16,7 +16,7 @@ pub enum Region {
Taiwan = ctru_sys::CFG_REGION_TWN,
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Language {
Japanese = ctru_sys::CFG_LANGUAGE_JP,
@ -33,15 +33,15 @@ pub enum Language { @@ -33,15 +33,15 @@ pub enum Language {
TraditionalChinese = ctru_sys::CFG_LANGUAGE_TW,
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum SystemModel {
Model3DS = ctru_sys::CFG_MODEL_3DS,
Model3DSXL = ctru_sys::CFG_MODEL_3DSXL,
ModelNew3DS = ctru_sys::CFG_MODEL_N3DS,
Model2DS = ctru_sys::CFG_MODEL_2DS,
ModelNew3DSXL = ctru_sys::CFG_MODEL_N3DSXL,
ModelNew2DSXL = ctru_sys::CFG_MODEL_N2DSXL,
Old3DS = ctru_sys::CFG_MODEL_3DS,
Old3DSXL = ctru_sys::CFG_MODEL_3DSXL,
New3DS = ctru_sys::CFG_MODEL_N3DS,
Old2DS = ctru_sys::CFG_MODEL_2DS,
New3DSXL = ctru_sys::CFG_MODEL_N3DSXL,
New2DSXL = ctru_sys::CFG_MODEL_N2DSXL,
}
/// Represents the configuration service. No actions can be performed
@ -61,7 +61,7 @@ impl Cfgu { @@ -61,7 +61,7 @@ impl Cfgu {
/// ctrulib services are reference counted, so this function may be called
/// as many times as desired and the service will not exit until all
/// instances of Cfgu drop out of scope.
pub fn init() -> crate::Result<Cfgu> {
pub fn new() -> crate::Result<Cfgu> {
ResultCode(unsafe { ctru_sys::cfguInit() })?;
Ok(Cfgu(()))
}
@ -163,12 +163,12 @@ impl TryFrom<u8> for SystemModel { @@ -163,12 +163,12 @@ impl TryFrom<u8> for SystemModel {
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value as u32 {
ctru_sys::CFG_MODEL_3DS => Ok(SystemModel::Model3DS),
ctru_sys::CFG_MODEL_3DSXL => Ok(SystemModel::Model3DSXL),
ctru_sys::CFG_MODEL_N3DS => Ok(SystemModel::ModelNew3DS),
ctru_sys::CFG_MODEL_2DS => Ok(SystemModel::Model2DS),
ctru_sys::CFG_MODEL_N3DSXL => Ok(SystemModel::ModelNew3DSXL),
ctru_sys::CFG_MODEL_N2DSXL => Ok(SystemModel::ModelNew2DSXL),
ctru_sys::CFG_MODEL_3DS => Ok(SystemModel::Old3DS),
ctru_sys::CFG_MODEL_3DSXL => Ok(SystemModel::Old3DSXL),
ctru_sys::CFG_MODEL_N3DS => Ok(SystemModel::New3DS),
ctru_sys::CFG_MODEL_2DS => Ok(SystemModel::Old2DS),
ctru_sys::CFG_MODEL_N3DSXL => Ok(SystemModel::New3DSXL),
ctru_sys::CFG_MODEL_N2DSXL => Ok(SystemModel::New2DSXL),
_ => Err(()),
}
}

33
ctru-rs/src/services/fs.rs

@ -23,17 +23,13 @@ bitflags! { @@ -23,17 +23,13 @@ bitflags! {
const FS_OPEN_WRITE = 2;
const FS_OPEN_CREATE = 4;
}
}
bitflags! {
#[derive(Default)]
struct FsWrite: u32 {
const FS_WRITE_FLUSH = 1;
const FS_WRITE_UPDATE_TIME = 256;
}
}
bitflags! {
#[derive(Default)]
struct FsAttribute: u32 {
const FS_ATTRIBUTE_DIRECTORY = 1;
@ -43,7 +39,7 @@ bitflags! { @@ -43,7 +39,7 @@ bitflags! {
}
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum FsMediaType {
Nand = ctru_sys::MEDIATYPE_NAND,
@ -51,7 +47,7 @@ pub enum FsMediaType { @@ -51,7 +47,7 @@ pub enum FsMediaType {
GameCard = ctru_sys::MEDIATYPE_GAME_CARD,
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum PathType {
Invalid = ctru_sys::PATH_INVALID,
@ -61,7 +57,7 @@ pub enum PathType { @@ -61,7 +57,7 @@ pub enum PathType {
UTF16 = ctru_sys::PATH_UTF16,
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum ArchiveID {
RomFS = ctru_sys::ARCHIVE_ROMFS,
@ -103,7 +99,7 @@ pub struct Fs(()); @@ -103,7 +99,7 @@ pub struct Fs(());
/// ```no_run
/// use ctru::services::fs::Fs;
///
/// let mut fs = Fs::init().unwrap();
/// let mut fs = Fs::new().unwrap();
/// let sdmc_archive = fs.sdmc().unwrap();
/// ```
pub struct Archive {
@ -129,11 +125,8 @@ pub struct Archive { @@ -129,11 +125,8 @@ pub struct Archive {
/// use std::io::prelude::*;
/// use ctru::services::fs::{Fs, File};
///
/// let mut fs = Fs::init()?;
/// let mut fs = Fs::new()?;
/// let mut sdmc = fs.sdmc()?;
///
/// let mut file = File::create(&mut sdmc, "/foo.txt")?;
/// file.write_all(b"Hello, world!")?;
/// #
/// # Ok(())
/// # }
@ -148,7 +141,7 @@ pub struct Archive { @@ -148,7 +141,7 @@ pub struct Archive {
/// use std::io::prelude::*;
/// use ctru::services::fs::{Fs, File};
///
/// let mut fs = Fs::init()?;
/// let mut fs = Fs::new()?;
/// let mut sdmc = fs.sdmc()?;
///
/// let mut file = File::open(&sdmc, "/foo.txt")?;
@ -171,7 +164,7 @@ pub struct Archive { @@ -171,7 +164,7 @@ pub struct Archive {
/// use std::io::prelude::*;
/// use ctru::services::fs::{Fs, File};
///
/// let mut fs = Fs::init()?;
/// let mut fs = Fs::new()?;
/// let mut sdmc = fs.sdmc()?;
///
/// let file = File::open(&sdmc, "/foo.txt")?;
@ -227,7 +220,7 @@ pub struct Metadata { @@ -227,7 +220,7 @@ pub struct Metadata {
/// ```no_run
/// use ctru::services::fs::{Fs, OpenOptions};
///
/// let mut fs = Fs::init().unwrap();
/// let mut fs = Fs::new().unwrap();
/// let mut sdmc_archive = fs.sdmc().unwrap();
/// let file = OpenOptions::new()
/// .read(true)
@ -242,7 +235,7 @@ pub struct Metadata { @@ -242,7 +235,7 @@ pub struct Metadata {
/// ```no_run
/// use ctru::services::fs::{Fs, OpenOptions};
///
/// let mut fs = Fs::init().unwrap();
/// let mut fs = Fs::new().unwrap();
/// let mut sdmc_archive = fs.sdmc().unwrap();
/// let file = OpenOptions::new()
/// .read(true)
@ -252,7 +245,7 @@ pub struct Metadata { @@ -252,7 +245,7 @@ pub struct Metadata {
/// .open("foo.txt")
/// .unwrap();
/// ```
#[derive(Clone, Default)]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct OpenOptions {
read: bool,
write: bool,
@ -316,7 +309,7 @@ impl Fs { @@ -316,7 +309,7 @@ impl Fs {
/// ctrulib services are reference counted, so this function may be called
/// as many times as desired and the service will not exit until all
/// instances of Fs drop out of scope.
pub fn init() -> crate::Result<Fs> {
pub fn new() -> crate::Result<Fs> {
unsafe {
let r = ctru_sys::fsInit();
if r < 0 {
@ -369,7 +362,7 @@ impl File { @@ -369,7 +362,7 @@ impl File {
/// ```no_run
/// use ctru::services::fs::{Fs, File};
///
/// let mut fs = Fs::init().unwrap();
/// let mut fs = Fs::new().unwrap();
/// let mut sdmc_archive = fs.sdmc().unwrap();
/// let mut f = File::open(&sdmc_archive, "/foo.txt").unwrap();
/// ```
@ -398,7 +391,7 @@ impl File { @@ -398,7 +391,7 @@ impl File {
/// ```no_run
/// use ctru::services::fs::{Fs, File};
///
/// let mut fs = Fs::init().unwrap();
/// let mut fs = Fs::new().unwrap();
/// let mut sdmc_archive = fs.sdmc().unwrap();
/// let mut f = File::create(&mut sdmc_archive, "/foo.txt").unwrap();
/// ```

173
ctru-rs/src/services/gfx.rs

@ -9,11 +9,12 @@ use crate::services::gspgpu::{self, FramebufferFormat}; @@ -9,11 +9,12 @@ use crate::services::gspgpu::{self, FramebufferFormat};
use crate::services::ServiceReference;
mod private {
use super::{BottomScreen, TopScreen, TopScreenLeft, TopScreenRight};
use super::{BottomScreen, TopScreen, TopScreen3D, TopScreenLeft, TopScreenRight};
pub trait Sealed {}
impl Sealed for TopScreen {}
impl Sealed for TopScreen3D<'_> {}
impl Sealed for TopScreenLeft {}
impl Sealed for TopScreenRight {}
impl Sealed for BottomScreen {}
@ -34,33 +35,36 @@ pub trait Screen: private::Sealed { @@ -34,33 +35,36 @@ pub trait Screen: private::Sealed {
/// Note that the pointer of the framebuffer returned by this function can
/// change after each call to this function if double buffering is enabled.
fn raw_framebuffer(&mut self) -> RawFrameBuffer {
let mut width = 0;
let mut height = 0;
let mut width: u16 = 0;
let mut height: u16 = 0;
let ptr = unsafe {
ctru_sys::gfxGetFramebuffer(self.as_raw(), self.side().into(), &mut width, &mut height)
};
RawFrameBuffer {
ptr,
width,
height,
width: width.into(),
height: height.into(),
screen: PhantomData,
}
}
/// Sets whether to use double buffering. Enabled by default.
///
/// Note that even when double buffering is disabled, one should still use the `swap_buffers`
/// method on each frame to keep the gsp configuration up to date
/// [`Swap::swap_buffers`] must be called after this function for the configuration
/// change to take effect.
fn set_double_buffering(&mut self, enabled: bool) {
unsafe { ctru_sys::gfxSetDoubleBuffering(self.as_raw(), enabled) }
}
/// Gets the framebuffer format
/// Gets the framebuffer format.
fn framebuffer_format(&self) -> FramebufferFormat {
unsafe { ctru_sys::gfxGetScreenFormat(self.as_raw()) }.into()
}
/// Change the framebuffer format
/// Change the framebuffer format.
///
/// [`Swap::swap_buffers`] must be called after this method for the configuration
/// change to take effect.
fn set_framebuffer_format(&mut self, fmt: FramebufferFormat) {
unsafe { ctru_sys::gfxSetScreenFormat(self.as_raw(), fmt.into()) }
}
@ -75,17 +79,98 @@ pub struct TopScreen { @@ -75,17 +79,98 @@ pub struct TopScreen {
/// A helper container for both sides of the top screen. Once the [`TopScreen`] is
/// converted into this, 3D mode will be enabled until this struct is dropped.
pub struct TopScreen3D<'top_screen> {
screen: &'top_screen RefCell<TopScreen>,
pub struct TopScreen3D<'screen> {
screen: &'screen RefCell<TopScreen>,
}
/// A screen that can have its frame buffers swapped, if double buffering is enabled.
///
/// This trait applies to all [`Screen`]s that have swappable frame buffers.
pub trait Swap: private::Sealed {
/// Swaps the video buffers.
///
/// If double buffering is disabled, "swapping" the buffers has the side effect
/// of committing any configuration changes to the buffers (e.g. [`set_wide_mode`],
/// [`set_framebuffer_format`], [`set_double_buffering`]).
///
/// This should be called once per frame at most.
///
/// [`set_wide_mode`]: TopScreen::set_wide_mode
/// [`set_framebuffer_format`]: Screen::set_framebuffer_format
/// [`set_double_buffering`]: Screen::set_double_buffering
fn swap_buffers(&mut self);
}
impl Swap for TopScreen3D<'_> {
fn swap_buffers(&mut self) {
unsafe {
ctru_sys::gfxScreenSwapBuffers(ctru_sys::GFX_TOP, true);
}
}
}
impl Swap for TopScreen {
fn swap_buffers(&mut self) {
unsafe {
ctru_sys::gfxScreenSwapBuffers(ctru_sys::GFX_TOP, false);
}
}
}
impl Swap for BottomScreen {
fn swap_buffers(&mut self) {
unsafe {
ctru_sys::gfxScreenSwapBuffers(ctru_sys::GFX_BOTTOM, false);
}
}
}
/// A screen with buffers that can be flushed. This trait applies to any [`Screen`]
/// that has data written to its frame buffer.
pub trait Flush: private::Sealed {
/// Flushes the video buffer(s) for this screen. Note that you must still call
/// [`Swap::swap_buffers`] after this method for the buffer contents to be displayed.
fn flush_buffers(&mut self);
}
impl<S: Screen> Flush for S {
fn flush_buffers(&mut self) {
let framebuffer = self.raw_framebuffer();
// Flush the data array. `self.raw_framebuffer` should get the correct parameters for all kinds of screens
unsafe {
ctru_sys::GSPGPU_FlushDataCache(
framebuffer.ptr.cast(),
(framebuffer.height * framebuffer.width) as u32,
)
};
}
}
struct TopScreenLeft;
impl Flush for TopScreen3D<'_> {
/// Unlike most other implementations of [`Flush`], this flushes the buffers for both
/// the left and right sides of the top screen.
fn flush_buffers(&mut self) {
let (mut left, mut right) = self.split_mut();
left.flush_buffers();
right.flush_buffers();
}
}
struct TopScreenRight;
/// The left side of the top screen, when using 3D mode.
#[derive(Debug)]
#[non_exhaustive]
pub struct TopScreenLeft;
/// The right side of the top screen, when using 3D mode.
#[derive(Debug)]
#[non_exhaustive]
pub struct TopScreenRight;
/// The bottom screen. Mutable access to this struct is required to write to the
/// bottom screen's frame buffer.
#[derive(Debug)]
#[non_exhaustive]
pub struct BottomScreen;
/// Representation of a framebuffer for one [`Side`] of the top screen, or the
@ -96,14 +181,14 @@ pub struct RawFrameBuffer<'screen> { @@ -96,14 +181,14 @@ pub struct RawFrameBuffer<'screen> {
/// Pointer to graphics data to be rendered.
pub ptr: *mut u8,
/// The width of the framebuffer in pixels.
pub width: u16,
pub width: usize,
/// The height of the framebuffer in pixels.
pub height: u16,
pub height: usize,
/// Keep a mutable reference to the Screen for which this framebuffer is tied.
screen: PhantomData<&'screen mut dyn Screen>,
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
/// Side of top screen framebuffer
///
@ -128,10 +213,17 @@ pub struct Gfx { @@ -128,10 +213,17 @@ pub struct Gfx {
static GFX_ACTIVE: Mutex<usize> = Mutex::new(0);
impl Gfx {
/// Creates a new [Gfx] instance with default init values
/// It's the same as calling:
/// `Gfx::with_formats(FramebufferFormat::Bgr8, FramebufferFormat::Bgr8, false)`
pub fn new() -> Result<Self> {
Gfx::with_formats(FramebufferFormat::Bgr8, FramebufferFormat::Bgr8, false)
}
/// Initialize the Gfx module with the chosen framebuffer formats for the top and bottom
/// screens
///
/// Use `Gfx::init()` instead of this function to initialize the module with default parameters
/// Use `Gfx::new()` instead of this function to initialize the module with default parameters
pub fn with_formats(
top_fb_fmt: FramebufferFormat,
bottom_fb_fmt: FramebufferFormat,
@ -155,32 +247,6 @@ impl Gfx { @@ -155,32 +247,6 @@ impl Gfx {
})
}
/// Creates a new [Gfx] instance with default init values
/// It's the same as calling:
/// `Gfx::with_formats(FramebufferFormat::Bgr8, FramebufferFormat::Bgr8, false)`
pub fn init() -> Result<Self> {
Gfx::with_formats(FramebufferFormat::Bgr8, FramebufferFormat::Bgr8, false)
}
/// Flushes the current framebuffers
pub fn flush_buffers(&self) {
unsafe { ctru_sys::gfxFlushBuffers() };
}
/// Swaps the framebuffers and sets the gsp state
///
/// Use this function when working with software rendering
pub fn swap_buffers(&self) {
unsafe { ctru_sys::gfxSwapBuffers() };
}
/// Swaps the framebuffers without manipulating the gsp state
///
/// Use this function when working with GPU rendering
pub fn swap_buffers_gpu(&self) {
unsafe { ctru_sys::gfxSwapBuffersGpu() };
}
/// Waits for the vertical blank interrupt
///
/// Use this to synchronize your application with the refresh rate of the LCD screens
@ -191,22 +257,20 @@ impl Gfx { @@ -191,22 +257,20 @@ impl Gfx {
impl TopScreen3D<'_> {
/// Immutably borrow the two sides of the screen as `(left, right)`.
pub fn split(&self) -> (Ref<dyn Screen>, Ref<dyn Screen>) {
Ref::map_split(self.screen.borrow(), |screen| {
(&screen.left as _, &screen.right as _)
})
pub fn split(&self) -> (Ref<TopScreenLeft>, Ref<TopScreenRight>) {
Ref::map_split(self.screen.borrow(), |screen| (&screen.left, &screen.right))
}
/// Mutably borrow the two sides of the screen as `(left, right)`.
pub fn split_mut(&self) -> (RefMut<dyn Screen>, RefMut<dyn Screen>) {
pub fn split_mut(&self) -> (RefMut<TopScreenLeft>, RefMut<TopScreenRight>) {
RefMut::map_split(self.screen.borrow_mut(), |screen| {
(&mut screen.left as _, &mut screen.right as _)
(&mut screen.left, &mut screen.right)
})
}
}
impl<'top_screen> From<&'top_screen RefCell<TopScreen>> for TopScreen3D<'top_screen> {
fn from(top_screen: &'top_screen RefCell<TopScreen>) -> Self {
impl<'screen> From<&'screen RefCell<TopScreen>> for TopScreen3D<'screen> {
fn from(top_screen: &'screen RefCell<TopScreen>) -> Self {
unsafe {
ctru_sys::gfxSet3D(true);
}
@ -232,6 +296,9 @@ impl TopScreen { @@ -232,6 +296,9 @@ impl TopScreen {
}
/// Enable or disable wide mode on the top screen.
///
/// [`Swap::swap_buffers`] must be called after this method for the configuration
/// to take effect.
pub fn set_wide_mode(&mut self, enable: bool) {
unsafe {
ctru_sys::gfxSetWide(enable);
@ -244,6 +311,8 @@ impl TopScreen { @@ -244,6 +311,8 @@ impl TopScreen {
}
}
// When 3D mode is disabled, only the left side is used, so this Screen impl
// just forwards everything to the TopScreenLeft.
impl Screen for TopScreen {
fn as_raw(&self) -> ctru_sys::gfxScreen_t {
self.left.as_raw()
@ -294,6 +363,6 @@ mod tests { @@ -294,6 +363,6 @@ mod tests {
#[test]
fn gfx_duplicate() {
// We don't need to build a `Gfx` because the test runner has one already
assert!(matches!(Gfx::init(), Err(Error::ServiceAlreadyActive)));
assert!(matches!(Gfx::new(), Err(Error::ServiceAlreadyActive)));
}
}

4
ctru-rs/src/services/gspgpu.rs

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
//! GSPGPU service
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum Event {
Psc0 = ctru_sys::GSPGPU_EVENT_PSC0,
@ -13,7 +13,7 @@ pub enum Event { @@ -13,7 +13,7 @@ pub enum Event {
}
/// Framebuffer formats supported by the 3DS
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum FramebufferFormat {
/// RGBA8. 4 bytes per pixel

75
ctru-rs/src/services/hid.rs

@ -8,16 +8,15 @@ use crate::error::ResultCode; @@ -8,16 +8,15 @@ use crate::error::ResultCode;
bitflags::bitflags! {
/// A set of flags corresponding to the button and directional pad
/// inputs on the 3DS
#[derive(Default)]
pub struct KeyPad: u32 {
const A = ctru_sys::KEY_A;
const B = ctru_sys::KEY_B;
const SELECT = ctru_sys::KEY_SELECT;
const START = ctru_sys::KEY_START;
const DRIGHT = ctru_sys::KEY_DRIGHT;
const DLEFT = ctru_sys::KEY_DLEFT;
const DUP = ctru_sys::KEY_DUP;
const DDOWN = ctru_sys::KEY_DDOWN;
const DPAD_RIGHT = ctru_sys::KEY_DRIGHT;
const DPAD_LEFT = ctru_sys::KEY_DLEFT;
const DPAD_UP = ctru_sys::KEY_DUP;
const DPAD_DOWN = ctru_sys::KEY_DDOWN;
const R = ctru_sys::KEY_R;
const L = ctru_sys::KEY_L;
const X = ctru_sys::KEY_X;
@ -34,10 +33,10 @@ bitflags::bitflags! { @@ -34,10 +33,10 @@ bitflags::bitflags! {
const CPAD_UP = ctru_sys::KEY_CPAD_UP;
const CPAD_DOWN = ctru_sys::KEY_CPAD_DOWN;
// Convenience catch-all for the dpad and cpad
const UP = KeyPad::DUP.bits() | KeyPad::CPAD_UP.bits();
const DOWN = KeyPad::DDOWN.bits() | KeyPad::CPAD_DOWN.bits();
const LEFT = KeyPad::DLEFT.bits() | KeyPad::CPAD_LEFT.bits();
const RIGHT = KeyPad::DRIGHT.bits() | KeyPad::CPAD_RIGHT.bits();
const UP = KeyPad::DPAD_UP.bits() | KeyPad::CPAD_UP.bits();
const DOWN = KeyPad::DPAD_DOWN.bits() | KeyPad::CPAD_DOWN.bits();
const LEFT = KeyPad::DPAD_LEFT.bits() | KeyPad::CPAD_LEFT.bits();
const RIGHT = KeyPad::DPAD_RIGHT.bits() | KeyPad::CPAD_RIGHT.bits();
}
}
@ -47,12 +46,6 @@ bitflags::bitflags! { @@ -47,12 +46,6 @@ bitflags::bitflags! {
/// This service requires no special permissions to use.
pub struct Hid(());
/// Represents user input to the touchscreen.
pub struct TouchPosition(ctru_sys::touchPosition);
/// Represents the current position of the 3DS circle pad.
pub struct CirclePosition(ctru_sys::circlePosition);
/// Initializes the HID service.
///
/// # Errors
@ -61,7 +54,7 @@ pub struct CirclePosition(ctru_sys::circlePosition); @@ -61,7 +54,7 @@ pub struct CirclePosition(ctru_sys::circlePosition);
/// Since this service requires no special or elevated permissions, errors are
/// rare in practice.
impl Hid {
pub fn init() -> crate::Result<Hid> {
pub fn new() -> crate::Result<Hid> {
unsafe {
ResultCode(ctru_sys::hidInit())?;
Ok(Hid(()))
@ -101,47 +94,33 @@ impl Hid { @@ -101,47 +94,33 @@ impl Hid {
KeyPad::from_bits_truncate(keys)
}
}
}
impl Default for TouchPosition {
fn default() -> Self {
TouchPosition(ctru_sys::touchPosition { px: 0, py: 0 })
}
}
impl TouchPosition {
/// Create a new TouchPosition instance.
pub fn new() -> Self {
Self::default()
}
/// Returns the current touch position in pixels (x, y).
///
/// # Notes
///
/// (0, 0) represents the top left corner of the screen.
pub fn touch_position(&mut self) -> (u16, u16) {
let mut res = ctru_sys::touchPosition { px: 0, py: 0 };
/// Returns the current touch position in pixels.
pub fn get(&mut self) -> (u16, u16) {
unsafe {
ctru_sys::hidTouchRead(&mut self.0);
}
(self.0.px, self.0.py)
}
}
impl Default for CirclePosition {
fn default() -> Self {
CirclePosition(ctru_sys::circlePosition { dx: 0, dy: 0 })
ctru_sys::hidTouchRead(&mut res);
}
(res.px, res.py)
}
impl CirclePosition {
/// Create a new CirclePosition instance.
pub fn new() -> Self {
Self::default()
}
/// Returns the current circle pad position in relative (x, y).
///
/// # Notes
///
/// (0, 0) represents the center of the circle pad.
pub fn circlepad_position(&mut self) -> (i16, i16) {
let mut res = ctru_sys::circlePosition { dx: 0, dy: 0 };
/// Returns the current circle pad position in (x, y) form.
pub fn get(&mut self) -> (i16, i16) {
unsafe {
ctru_sys::hidCircleRead(&mut self.0);
ctru_sys::hidCircleRead(&mut res);
}
(self.0.dx, self.0.dy)
(res.dx, res.dy)
}
}

12
ctru-rs/src/services/ndsp/mod.rs

@ -14,7 +14,7 @@ use std::sync::Mutex; @@ -14,7 +14,7 @@ use std::sync::Mutex;
const NUMBER_OF_CHANNELS: u8 = 24;
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum OutputMode {
Mono = ctru_sys::NDSP_OUTPUT_MONO,
@ -22,7 +22,7 @@ pub enum OutputMode { @@ -22,7 +22,7 @@ pub enum OutputMode {
Surround = ctru_sys::NDSP_OUTPUT_SURROUND,
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum AudioFormat {
PCM8Mono = ctru_sys::NDSP_FORMAT_MONO_PCM8,
@ -32,12 +32,12 @@ pub enum AudioFormat { @@ -32,12 +32,12 @@ pub enum AudioFormat {
}
/// Representation of volume mix for a channel.
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub struct AudioMix {
raw: [f32; 12],
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u32)]
pub enum InterpolationType {
Polyphase = ctru_sys::NDSP_INTERP_POLYPHASE,
@ -45,7 +45,7 @@ pub enum InterpolationType { @@ -45,7 +45,7 @@ pub enum InterpolationType {
None = ctru_sys::NDSP_INTERP_NONE,
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum NdspError {
/// Channel ID
InvalidChannel(u8),
@ -80,7 +80,7 @@ impl Ndsp { @@ -80,7 +80,7 @@ impl Ndsp {
///
/// This function will return an error if an instance of the `Ndsp` struct already exists
/// or if there are any issues during initialization.
pub fn init() -> crate::Result<Self> {
pub fn new() -> crate::Result<Self> {
let _service_handler = ServiceReference::new(
&NDSP_ACTIVE,
false,

2
ctru-rs/src/services/ndsp/wave.rs

@ -11,7 +11,7 @@ pub struct Wave { @@ -11,7 +11,7 @@ pub struct Wave {
played_on_channel: Option<u8>,
}
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[repr(u8)]
/// Enum representing the playback status of a [Wave].
pub enum WaveStatus {

4
ctru-rs/src/services/ps.rs

@ -6,6 +6,7 @@ @@ -6,6 +6,7 @@
use crate::error::ResultCode;
use crate::Result;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum AESAlgorithm {
CbcEnc = ctru_sys::PS_ALGORITHM_CBC_ENC,
@ -16,6 +17,7 @@ pub enum AESAlgorithm { @@ -16,6 +17,7 @@ pub enum AESAlgorithm {
CcmDec = ctru_sys::PS_ALGORITHM_CCM_DEC,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum AESKeyType {
Keyslot0D = ctru_sys::PS_KEYSLOT_0D,
@ -56,7 +58,7 @@ impl Ps { @@ -56,7 +58,7 @@ impl Ps {
pub fn generate_random_bytes(&self, out: &mut [u8]) -> crate::Result<()> {
ResultCode(unsafe {
ctru_sys::PS_GenerateRandomBytes(out as *mut _ as *mut _, out.len())
ctru_sys::PS_GenerateRandomBytes(out.as_mut_ptr().cast(), out.len())
})?;
Ok(())
}

4
ctru-rs/src/services/romfs.rs

@ -25,7 +25,7 @@ pub struct RomFS { @@ -25,7 +25,7 @@ pub struct RomFS {
static ROMFS_ACTIVE: Mutex<usize> = Mutex::new(0);
impl RomFS {
pub fn init() -> crate::Result<Self> {
pub fn new() -> crate::Result<Self> {
let _service_handler = ServiceReference::new(
&ROMFS_ACTIVE,
true,
@ -50,7 +50,7 @@ mod tests { @@ -50,7 +50,7 @@ mod tests {
#[test]
fn romfs_counter() {
let _romfs = RomFS::init().unwrap();
let _romfs = RomFS::new().unwrap();
let value = *ROMFS_ACTIVE.lock().unwrap();
assert_eq!(value, 1);

6
ctru-rs/src/services/soc.rs

@ -25,7 +25,7 @@ impl Soc { @@ -25,7 +25,7 @@ impl Soc {
/// # Errors
///
/// This function will return an error if the `Soc` service is already initialized
pub fn init() -> crate::Result<Self> {
pub fn new() -> crate::Result<Self> {
Self::init_with_buffer_size(0x100000)
}
@ -107,8 +107,8 @@ mod tests { @@ -107,8 +107,8 @@ mod tests {
#[test]
fn soc_duplicate() {
let _soc = Soc::init().unwrap();
let _soc = Soc::new().unwrap();
assert!(matches!(Soc::init(), Err(Error::ServiceAlreadyActive)))
assert!(matches!(Soc::new(), Err(Error::ServiceAlreadyActive)))
}
}

13
ctru-rs/src/services/sslc.rs

@ -8,23 +8,12 @@ pub struct SslC(()); @@ -8,23 +8,12 @@ pub struct SslC(());
impl SslC {
/// Initialize the service
pub fn init() -> crate::Result<Self> {
pub fn new() -> crate::Result<Self> {
unsafe {
ResultCode(ctru_sys::sslcInit(0))?;
Ok(SslC(()))
}
}
/// Fill `buf` with `buf.len()` random bytes
pub fn generate_random_data(&self, buf: &mut [u8]) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::sslcGenerateRandomData(
buf.as_ptr() as _,
buf.len() as u32,
))?;
Ok(())
}
}
}
impl Drop for SslC {

10
ctru-rs/src/test_runner.rs

@ -12,13 +12,13 @@ use crate::prelude::*; @@ -12,13 +12,13 @@ use crate::prelude::*;
/// 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]) {
let gfx = Gfx::init().unwrap();
let mut hid = Hid::init().unwrap();
let apt = Apt::init().unwrap();
let gfx = Gfx::new().unwrap();
let mut hid = Hid::new().unwrap();
let apt = Apt::new().unwrap();
let mut top_screen = gfx.top_screen.borrow_mut();
top_screen.set_wide_mode(true);
let _console = Console::init(top_screen);
let _console = Console::new(top_screen);
let opts = TestOpts {
force_run_in_process: true,
@ -39,8 +39,6 @@ pub(crate) fn run(tests: &[&TestDescAndFn]) { @@ -39,8 +39,6 @@ pub(crate) fn run(tests: &[&TestDescAndFn]) {
println!("Press START to exit.");
while apt.main_loop() {
gfx.flush_buffers();
gfx.swap_buffers();
gfx.wait_for_vblank();
hid.scan_input();

Loading…
Cancel
Save