Browse Source

Merge pull request #107 from rust3ds/improve/api

Improve general API
pull/114/head
Meziu 2 years ago committed by GitHub
parent
commit
474cb2e0c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      ctru-rs/examples/audio-filters.rs
  2. 10
      ctru-rs/examples/buttons.rs
  3. 16
      ctru-rs/examples/camera-image.rs
  4. 25
      ctru-rs/examples/file-explorer.rs
  5. 10
      ctru-rs/examples/gfx-3d-mode.rs
  6. 6
      ctru-rs/examples/gfx-wide-mode.rs
  7. 6
      ctru-rs/examples/graphics-bitmap.rs
  8. 2
      ctru-rs/examples/hashmaps.rs
  9. 2
      ctru-rs/examples/hello-both-screens.rs
  10. 2
      ctru-rs/examples/hello-world.rs
  11. 2
      ctru-rs/examples/linear-memory.rs
  12. 2
      ctru-rs/examples/mii-selector.rs
  13. 2
      ctru-rs/examples/network-sockets.rs
  14. 2
      ctru-rs/examples/output-3dslink.rs
  15. 4
      ctru-rs/examples/romfs.rs
  16. 15
      ctru-rs/examples/software-keyboard.rs
  17. 8
      ctru-rs/examples/system-configuration.rs
  18. 2
      ctru-rs/examples/time-rtc.rs
  19. 20
      ctru-rs/examples/title-info.rs
  20. 4
      ctru-rs/src/applets/mii_selector.rs
  21. 109
      ctru-rs/src/applets/swkbd.rs
  22. 2
      ctru-rs/src/console.rs
  23. 36
      ctru-rs/src/lib.rs
  24. 3
      ctru-rs/src/prelude.rs
  25. 18
      ctru-rs/src/services/am.rs
  26. 387
      ctru-rs/src/services/cam.rs
  27. 22
      ctru-rs/src/services/cfgu.rs
  28. 109
      ctru-rs/src/services/fs.rs
  29. 22
      ctru-rs/src/services/gfx.rs
  30. 59
      ctru-rs/src/services/gspgpu.rs
  31. 56
      ctru-rs/src/services/hid.rs
  32. 20
      ctru-rs/src/services/mod.rs
  33. 10
      ctru-rs/src/services/ndsp/mod.rs
  34. 35
      ctru-rs/src/services/ps.rs
  35. 2
      ctru-rs/src/services/romfs.rs
  36. 8
      ctru-rs/src/services/soc.rs
  37. 4
      ctru-rs/src/services/sslc.rs
  38. 7
      ctru-rs/src/test_runner.rs

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

@ -99,23 +99,23 @@ fn main() { @@ -99,23 +99,23 @@ fn main() {
hid.scan_input();
let keys_down = hid.keys_down();
if keys_down.contains(KeyPad::KEY_START) {
if keys_down.contains(KeyPad::START) {
break;
} // break in order to return to hbmenu
if keys_down.intersects(KeyPad::KEY_DOWN) {
if keys_down.intersects(KeyPad::DOWN) {
note = note.saturating_sub(1);
} else if keys_down.intersects(KeyPad::KEY_UP) {
} else if keys_down.intersects(KeyPad::UP) {
note = std::cmp::min(note + 1, NOTEFREQ.len() - 1);
}
let mut update_params = false;
if keys_down.intersects(KeyPad::KEY_LEFT) {
if keys_down.intersects(KeyPad::LEFT) {
filter -= 1;
filter = filter.rem_euclid(filter_names.len() as _);
update_params = true;
} else if keys_down.intersects(KeyPad::KEY_RIGHT) {
} else if keys_down.intersects(KeyPad::RIGHT) {
filter += 1;
filter = filter.rem_euclid(filter_names.len() as _);

10
ctru-rs/examples/buttons.rs

@ -42,19 +42,19 @@ fn main() { @@ -42,19 +42,19 @@ fn main() {
// You can also use the .bits() method to do direct comparisons on
// the underlying bits
if keys.contains(KeyPad::KEY_A) {
if keys.contains(KeyPad::A) {
println!("You held A!");
}
if keys.bits() & KeyPad::KEY_B.bits() != 0 {
if keys.bits() & KeyPad::B.bits() != 0 {
println!("You held B!");
}
if keys.contains(KeyPad::KEY_X | KeyPad::KEY_Y) {
if keys.contains(KeyPad::X | KeyPad::Y) {
println!("You held X and Y!");
}
if keys.intersects(KeyPad::KEY_L | KeyPad::KEY_R | KeyPad::KEY_ZL | KeyPad::KEY_ZR) {
if keys.intersects(KeyPad::L | KeyPad::R | KeyPad::ZL | KeyPad::ZR) {
println!("You held a shoulder button!");
}
if keys.intersects(KeyPad::KEY_START) {
if keys.intersects(KeyPad::START) {
println!("See ya!");
break;
}

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

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
use ctru::gfx::Screen;
use ctru::prelude::*;
use ctru::services::cam::{Cam, CamOutputFormat, CamShutterSoundType, CamSize, Camera};
use ctru::services::cam::{Cam, Camera, OutputFormat, ShutterSound, ViewSize};
use ctru::services::gfx::Screen;
use ctru::services::gspgpu::FramebufferFormat;
use std::time::Duration;
@ -37,10 +37,10 @@ fn main() { @@ -37,10 +37,10 @@ fn main() {
let camera = &mut cam.outer_right_cam;
camera
.set_view_size(CamSize::CTR_TOP_LCD)
.set_view_size(ViewSize::TopLCD)
.expect("Failed to set camera size");
camera
.set_output_format(CamOutputFormat::RGB_565)
.set_output_format(OutputFormat::Rgb565)
.expect("Failed to set camera output format");
camera
.set_noise_filter(true)
@ -65,11 +65,11 @@ fn main() { @@ -65,11 +65,11 @@ fn main() {
hid.scan_input();
keys_down = hid.keys_down();
if keys_down.contains(KeyPad::KEY_START) {
if keys_down.contains(KeyPad::START) {
break;
}
if keys_down.contains(KeyPad::KEY_R) {
if keys_down.contains(KeyPad::R) {
println!("Capturing new image");
let camera = &mut cam.outer_right_cam;
@ -83,12 +83,12 @@ fn main() { @@ -83,12 +83,12 @@ fn main() {
)
.expect("Failed to take picture");
cam.play_shutter_sound(CamShutterSoundType::NORMAL)
cam.play_shutter_sound(ShutterSound::Normal)
.expect("Failed to play shutter sound");
rotate_image_to_screen(
&buf,
gfx.top_screen.borrow_mut().get_raw_framebuffer().ptr,
gfx.top_screen.borrow_mut().raw_framebuffer().ptr,
WIDTH,
HEIGHT,
);

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

@ -16,7 +16,7 @@ fn main() { @@ -16,7 +16,7 @@ fn main() {
let gfx = Gfx::init().unwrap();
#[cfg(all(feature = "romfs", romfs_exists))]
let _romfs = ctru::romfs::RomFS::init().unwrap();
let _romfs = ctru::services::romfs::RomFS::init().unwrap();
FileExplorer::init(&apt, &hid, &gfx).run();
}
@ -56,15 +56,15 @@ impl<'a> FileExplorer<'a> { @@ -56,15 +56,15 @@ impl<'a> FileExplorer<'a> {
self.hid.scan_input();
let input = self.hid.keys_down();
if input.contains(KeyPad::KEY_START) {
if input.contains(KeyPad::START) {
break;
} else if input.contains(KeyPad::KEY_B) && self.path.components().count() > 1 {
} else if input.contains(KeyPad::B) && self.path.components().count() > 1 {
self.path.pop();
self.console.clear();
self.print_menu();
} else if input.contains(KeyPad::KEY_A) {
} else if input.contains(KeyPad::A) {
self.get_input_and_run(Self::set_next_path);
} else if input.contains(KeyPad::KEY_X) {
} else if input.contains(KeyPad::X) {
self.get_input_and_run(Self::set_exact_path);
}
@ -147,11 +147,11 @@ impl<'a> FileExplorer<'a> { @@ -147,11 +147,11 @@ impl<'a> FileExplorer<'a> {
self.hid.scan_input();
let input = self.hid.keys_down();
if input.contains(KeyPad::KEY_A) {
if input.contains(KeyPad::A) {
break;
}
if input.contains(KeyPad::KEY_START) {
if input.contains(KeyPad::START) {
self.running = false;
return;
}
@ -162,17 +162,16 @@ impl<'a> FileExplorer<'a> { @@ -162,17 +162,16 @@ impl<'a> FileExplorer<'a> {
fn get_input_and_run(&mut self, action: impl FnOnce(&mut Self, String)) {
let mut keyboard = Swkbd::default();
let mut new_path_str = String::new();
match keyboard.get_utf8(&mut new_path_str) {
Ok(Button::Right) => {
match keyboard.get_string(2048) {
Ok((path, Button::Right)) => {
// Clicked "OK"
action(self, new_path_str);
action(self, path);
}
Ok(Button::Left) => {
Ok((_, Button::Left)) => {
// Clicked "Cancel"
}
Ok(Button::Middle) => {
Ok((_, Button::Middle)) => {
// This button wasn't shown
unreachable!()
}

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
use ctru::gfx::{Screen, Side, TopScreen3D};
use ctru::prelude::*;
use ctru::services::gfx::{Screen, Side, TopScreen3D};
/// See `graphics-bitmap.rs` for details on how the image is generated.
///
@ -31,12 +31,12 @@ fn main() { @@ -31,12 +31,12 @@ fn main() {
//Scan all the inputs. This should be done once for each frame
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
let left_buf = left.get_raw_framebuffer();
let right_buf = right.get_raw_framebuffer();
let left_buf = left.raw_framebuffer();
let right_buf = right.raw_framebuffer();
// Clear both buffers every time, in case the user switches sides this loop
unsafe {
@ -44,7 +44,7 @@ fn main() { @@ -44,7 +44,7 @@ fn main() {
right_buf.ptr.copy_from(ZERO.as_ptr(), ZERO.len());
}
if hid.keys_down().contains(KeyPad::KEY_A) {
if hid.keys_down().contains(KeyPad::A) {
// flip which buffer we're writing to
current_side = match current_side {
Side::Left => Side::Right,

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

@ -13,14 +13,14 @@ fn main() { @@ -13,14 +13,14 @@ fn main() {
while apt.main_loop() {
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
if hid.keys_down().contains(KeyPad::KEY_A) {
if hid.keys_down().contains(KeyPad::A) {
drop(console);
let wide_mode = gfx.top_screen.borrow().get_wide_mode();
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());

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

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
use ctru::gfx::Screen as _;
use ctru::prelude::*;
use ctru::services::gfx::Screen;
/// 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
@ -31,7 +31,7 @@ fn main() { @@ -31,7 +31,7 @@ fn main() {
bottom_screen.set_double_buffering(false);
// We assume the image is the correct size already, so we drop width + height.
let frame_buffer = bottom_screen.get_raw_framebuffer();
let frame_buffer = bottom_screen.raw_framebuffer();
// Copy the image into the frame buffer
unsafe {
@ -43,7 +43,7 @@ fn main() { @@ -43,7 +43,7 @@ fn main() {
//Scan all the inputs. This should be done once for each frame
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}

2
ctru-rs/examples/hashmaps.rs

@ -26,7 +26,7 @@ fn main() { @@ -26,7 +26,7 @@ fn main() {
gfx.wait_for_vblank();
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
}

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

@ -32,7 +32,7 @@ fn main() { @@ -32,7 +32,7 @@ fn main() {
gfx.wait_for_vblank();
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
}

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

@ -26,7 +26,7 @@ fn main() { @@ -26,7 +26,7 @@ fn main() {
//Scan all the inputs. This should be done once for each frame
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers

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

@ -34,7 +34,7 @@ fn main() { @@ -34,7 +34,7 @@ fn main() {
//Scan all the inputs. This should be done once for each frame
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers

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

@ -30,7 +30,7 @@ fn main() { @@ -30,7 +30,7 @@ fn main() {
//Scan all the inputs. This should be done once for each frame
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers

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

@ -61,7 +61,7 @@ fn main() { @@ -61,7 +61,7 @@ fn main() {
}
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
};
}

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

@ -30,7 +30,7 @@ fn main() { @@ -30,7 +30,7 @@ fn main() {
//Scan all the inputs. This should be done once for each frame
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers

4
ctru-rs/examples/romfs.rs

@ -13,7 +13,7 @@ fn main() { @@ -13,7 +13,7 @@ fn main() {
// 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::romfs::RomFS::init().unwrap();
let _romfs = ctru::services::romfs::RomFS::init().unwrap();
let f = std::fs::read_to_string("romfs:/test-file.txt").unwrap();
println!("Contents of test-file.txt: \n{f}\n");
@ -33,7 +33,7 @@ fn main() { @@ -33,7 +33,7 @@ fn main() {
//Scan all the inputs. This should be done once for each frame
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers

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

@ -18,26 +18,23 @@ fn main() { @@ -18,26 +18,23 @@ fn main() {
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_A) {
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
// configurations.
let mut keyboard = Swkbd::default();
// String used to store text received from the keyboard
let mut text = String::new();
// Raise the software keyboard. You can perform different actions depending on which
// software button the user pressed
match keyboard.get_utf8(&mut text) {
Ok(Button::Right) => println!("You entered: {text}"),
Ok(Button::Left) => println!("Cancelled"),
Ok(Button::Middle) => println!("How did you even press this?"),
match keyboard.get_string(2048) {
Ok((text, Button::Right)) => println!("You entered: {text}"),
Ok((_, Button::Left)) => println!("Cancelled"),
Ok((_, Button::Middle)) => println!("How did you even press this?"),
Err(_) => println!("Oh noes, an error happened!"),
}
}
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
}

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

@ -10,16 +10,16 @@ fn main() { @@ -10,16 +10,16 @@ fn main() {
let cfgu = Cfgu::init().expect("Couldn't obtain CFGU controller");
let _console = Console::init(gfx.top_screen.borrow_mut());
println!("\x1b[0;0HRegion: {:?}", cfgu.get_region().unwrap());
println!("\x1b[10;0HLanguage: {:?}", cfgu.get_language().unwrap());
println!("\x1b[20;0HModel: {:?}", cfgu.get_model().unwrap());
println!("\x1b[0;0HRegion: {:?}", cfgu.region().unwrap());
println!("\x1b[10;0HLanguage: {:?}", cfgu.language().unwrap());
println!("\x1b[20;0HModel: {:?}", cfgu.model().unwrap());
// 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) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
// Flush and swap framebuffers

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

@ -16,7 +16,7 @@ fn main() { @@ -16,7 +16,7 @@ fn main() {
// Scan all the inputs. This should be done once for each frame
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}

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

@ -13,17 +13,17 @@ fn main() { @@ -13,17 +13,17 @@ fn main() {
let bottom_screen = Console::init(gfx.bottom_screen.borrow_mut());
let sd_count = am
.get_title_count(FsMediaType::Sd)
.title_count(FsMediaType::Sd)
.expect("Failed to get sd title count");
let sd_list = am
.get_title_list(FsMediaType::Sd)
.title_list(FsMediaType::Sd)
.expect("Failed to get sd title list");
let nand_count = am
.get_title_count(FsMediaType::Nand)
.title_count(FsMediaType::Nand)
.expect("Failed to get nand title count");
let nand_list = am
.get_title_list(FsMediaType::Nand)
.title_list(FsMediaType::Nand)
.expect("Failed to get nand title list");
let mut offset = 0;
@ -35,10 +35,10 @@ fn main() { @@ -35,10 +35,10 @@ fn main() {
//Scan all the inputs. This should be done once for each frame
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
if hid.keys_down().contains(KeyPad::KEY_SELECT) {
if hid.keys_down().contains(KeyPad::SELECT) {
refresh = true;
offset = 0;
use_nand = !use_nand;
@ -46,12 +46,12 @@ fn main() { @@ -46,12 +46,12 @@ fn main() {
let cur_list = if use_nand { &nand_list } else { &sd_list };
if hid.keys_down().intersects(KeyPad::KEY_DOWN) {
if hid.keys_down().intersects(KeyPad::DOWN) {
if offset + 1 < cur_list.len() {
offset = offset + 1;
refresh = true;
}
} else if hid.keys_down().intersects(KeyPad::KEY_UP) {
} else if hid.keys_down().intersects(KeyPad::UP) {
if offset > 0 {
offset = offset - 1;
refresh = true;
@ -80,14 +80,14 @@ fn main() { @@ -80,14 +80,14 @@ fn main() {
// Move cursor to top left
println!("\x1b[1;1");
match selected_title.get_title_info() {
match selected_title.title_info() {
Ok(info) => {
println!("Size: {} KB", info.size_bytes() / 1024);
println!("Version: 0x{:x}", info.version());
}
Err(e) => println!("Failed to get title info: {}", e),
}
match selected_title.get_product_code() {
match selected_title.product_code() {
Ok(code) => println!("Product code: \"{code}\""),
Err(e) => println!("Failed to get product code: {}", e),
}

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

@ -135,10 +135,10 @@ impl MiiSelector { @@ -135,10 +135,10 @@ impl MiiSelector {
/// Set where the cursor will be.
/// If there's no Mii at that index, the cursor will start at the Mii with the index 0
pub fn set_initial_index(&mut self, index: u32) {
pub fn set_initial_index(&mut self, index: usize) {
// This function is static inline in libctru
// https://github.com/devkitPro/libctru/blob/af5321c78ee5c72a55b526fd2ed0d95ca1c05af9/libctru/include/3ds/applets/miiselector.h#L155
self.config.initial_index = index
self.config.initial_index = index as u32;
}
/// Launch the Mii Selector.

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

@ -19,68 +19,70 @@ pub struct Swkbd { @@ -19,68 +19,70 @@ pub struct Swkbd {
/// 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)]
#[repr(u32)]
pub enum Kind {
Normal,
Qwerty,
Numpad,
Western,
Normal = ctru_sys::SWKBD_TYPE_NORMAL,
Qwerty = ctru_sys::SWKBD_TYPE_QWERTY,
Numpad = ctru_sys::SWKBD_TYPE_NUMPAD,
Western = ctru_sys::SWKBD_TYPE_WESTERN,
}
/// Represents which button the user pressed to close the software keyboard.
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum Button {
Left,
Middle,
Right,
Left = ctru_sys::SWKBD_BUTTON_LEFT,
Middle = ctru_sys::SWKBD_BUTTON_MIDDLE,
Right = ctru_sys::SWKBD_BUTTON_RIGHT,
}
/// Error type for the software keyboard.
#[derive(Copy, Clone, Debug)]
#[repr(i32)]
pub enum Error {
InvalidInput,
OutOfMem,
HomePressed,
ResetPressed,
PowerPressed,
ParentalOk,
ParentalFail,
BannedInput,
InvalidInput = ctru_sys::SWKBD_INVALID_INPUT,
OutOfMem = ctru_sys::SWKBD_OUTOFMEM,
HomePressed = ctru_sys::SWKBD_HOMEPRESSED,
ResetPressed = ctru_sys::SWKBD_RESETPRESSED,
PowerPressed = ctru_sys::SWKBD_POWERPRESSED,
ParentalOk = ctru_sys::SWKBD_PARENTAL_OK,
ParentalFail = ctru_sys::SWKBD_PARENTAL_FAIL,
BannedInput = ctru_sys::SWKBD_BANNED_INPUT,
}
/// Restrictions on keyboard input
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum ValidInput {
Anything,
NotEmpty,
NotEmptyNotBlank,
NotBlank,
FixedLen,
Anything = ctru_sys::SWKBD_ANYTHING,
NotEmpty = ctru_sys::SWKBD_NOTEMPTY,
NotEmptyNotBlank = ctru_sys::SWKBD_NOTEMPTY_NOTBLANK,
NotBlank = ctru_sys::SWKBD_NOTBLANK,
FixedLen = ctru_sys::SWKBD_FIXEDLEN,
}
bitflags! {
/// Keyboard feature flags
pub struct Features: u32 {
const PARENTAL_PIN = 1 << 0;
const DARKEN_TOP_SCREEN = 1 << 1;
const PREDICTIVE_INPUT = 1 << 2;
const MULTILINE = 1 << 3;
const FIXED_WIDTH = 1 << 4;
const ALLOW_HOME = 1 << 5;
const ALLOW_RESET = 1 << 6;
const ALLOW_POWER = 1 << 7;
const DEFAULT_QWERTY = 1 << 8;
}
const PARENTAL_PIN = ctru_sys::SWKBD_PARENTAL;
const DARKEN_TOP_SCREEN = ctru_sys::SWKBD_DARKEN_TOP_SCREEN;
const PREDICTIVE_INPUT = ctru_sys::SWKBD_PREDICTIVE_INPUT;
const MULTILINE = ctru_sys::SWKBD_MULTILINE;
const FIXED_WIDTH = ctru_sys::SWKBD_FIXED_WIDTH;
const ALLOW_HOME = ctru_sys::SWKBD_ALLOW_HOME;
const ALLOW_RESET = ctru_sys::SWKBD_ALLOW_RESET;
const ALLOW_POWER = ctru_sys::SWKBD_ALLOW_POWER;
const DEFAULT_QWERTY = ctru_sys::SWKBD_DEFAULT_QWERTY;
}
bitflags! {
/// Keyboard input filtering flags
pub struct Filters: u32 {
const DIGITS = 1 << 0;
const AT = 1 << 1;
const PERCENT = 1 << 2;
const BACKSLASH = 1 << 3;
const PROFANITY = 1 << 4;
const CALLBACK = 1 << 5;
const DIGITS = ctru_sys::SWKBD_FILTER_DIGITS;
const AT = ctru_sys::SWKBD_FILTER_AT;
const PERCENT = ctru_sys::SWKBD_FILTER_PERCENT;
const BACKSLASH = ctru_sys::SWKBD_FILTER_BACKSLASH;
const PROFANITY = ctru_sys::SWKBD_FILTER_PROFANITY;
const CALLBACK = ctru_sys::SWKBD_FILTER_CALLBACK;
}
}
@ -90,41 +92,39 @@ impl Swkbd { @@ -90,41 +92,39 @@ impl Swkbd {
pub fn init(keyboard_type: Kind, num_buttons: i32) -> Self {
unsafe {
let mut state = Box::<SwkbdState>::default();
swkbdInit(state.as_mut(), keyboard_type as u32, num_buttons, -1);
swkbdInit(state.as_mut(), keyboard_type.into(), num_buttons, -1);
Swkbd { state }
}
}
/// Gets input from this keyboard and appends it to the provided string.
///
/// The text received from the keyboard will be truncated if it is greater than 2048 bytes
/// in length.
pub fn get_utf8(&mut self, buf: &mut String) -> Result<Button, Error> {
/// The text received from the keyboard will be truncated if it is longer than `max_bytes`.
pub fn get_string(&mut self, max_bytes: usize) -> Result<(String, Button), Error> {
// Unfortunately the libctru API doesn't really provide a way to get the exact length
// of the string that it receieves from the software keyboard. Instead it expects you
// to pass in a buffer and hope that it's big enough to fit the entire string, so
// you have to set some upper limit on the potential size of the user's input.
const MAX_BYTES: usize = 2048;
let mut tmp = [0u8; MAX_BYTES];
let button = self.get_bytes(&mut tmp)?;
let mut tmp = vec![0u8; max_bytes];
let button = self.write_exact(&mut tmp)?;
// libctru does, however, seem to ensure that the buffer will always contain a properly
// terminated UTF-8 sequence even if the input has to be truncated, so these operations
// should be safe.
let len = unsafe { libc::strlen(tmp.as_ptr()) };
let utf8 = unsafe { str::from_utf8_unchecked(&tmp[..len]) };
tmp.truncate(len);
// Copy the input into the user's `String`
*buf += utf8;
Ok(button)
let res = unsafe { String::from_utf8_unchecked(tmp) };
Ok((res, button))
}
/// Fills the provided buffer with a UTF-8 encoded, NUL-terminated sequence of bytes from
/// this software keyboard.
///
/// If the buffer is too small to contain the entire sequence received from the keyboard,
/// the output will be truncated but should still be well-formed UTF-8
pub fn get_bytes(&mut self, buf: &mut [u8]) -> Result<Button, Error> {
/// the output will be truncated but should still be well-formed UTF-8.
pub fn write_exact(&mut self, buf: &mut [u8]) -> Result<Button, Error> {
unsafe {
match swkbdInputText(self.state.as_mut(), buf.as_mut_ptr(), buf.len()) {
ctru_sys::SWKBD_BUTTON_NONE => Err(self.parse_swkbd_error()),
@ -143,7 +143,7 @@ impl Swkbd { @@ -143,7 +143,7 @@ impl Swkbd {
/// Configures input validation for this keyboard
pub fn set_validation(&mut self, validation: ValidInput, filters: Filters) {
self.state.valid_input = validation as i32;
self.state.valid_input = validation.into();
self.state.filter_flags = filters.bits;
}
@ -173,7 +173,7 @@ impl Swkbd { @@ -173,7 +173,7 @@ impl Swkbd {
let nul_terminated: String = text.chars().chain(once('\0')).collect();
swkbdSetButton(
self.state.as_mut(),
button as u32,
button.into(),
nul_terminated.as_ptr(),
submit,
);
@ -210,3 +210,8 @@ impl Default for Swkbd { @@ -210,3 +210,8 @@ impl Default for Swkbd {
Swkbd::init(Kind::Normal, 2)
}
}
from_impl!(Kind, ctru_sys::SwkbdType);
from_impl!(Button, ctru_sys::SwkbdButton);
from_impl!(Error, ctru_sys::SwkbdResult);
from_impl!(ValidInput, i32);

2
ctru-rs/src/console.rs

@ -3,7 +3,7 @@ use std::default::Default; @@ -3,7 +3,7 @@ use std::default::Default;
use ctru_sys::{consoleClear, consoleInit, consoleSelect, consoleSetWindow, PrintConsole};
use crate::gfx::Screen;
use crate::services::gfx::Screen;
static mut EMPTY_CONSOLE: PrintConsole = unsafe { const_zero::const_zero!(PrintConsole) };

36
ctru-rs/src/lib.rs

@ -15,10 +15,20 @@ extern crate pthread_3ds; @@ -15,10 +15,20 @@ extern crate pthread_3ds;
#[cfg(feature = "big-stack")]
static __stacksize__: usize = 2 * 1024 * 1024; // 2MB
/// Activate ´ctru-rs´' default panic handler.
macro_rules! from_impl {
($from_type:ty, $into_type:ty) => {
impl From<$from_type> for $into_type {
fn from(v: $from_type) -> Self {
v as $into_type
}
}
};
}
/// Activate the default panic handler.
///
/// 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.
/// In case it fails to find an active [console::Console] the program will just exit.
///
/// # Notes
///
@ -48,7 +58,7 @@ fn panic_hook_setup() { @@ -48,7 +58,7 @@ fn panic_hook_setup() {
Ok(hid) => loop {
hid.scan_input();
let keys = hid.keys_down();
if keys.contains(KeyPad::KEY_SELECT) {
if keys.contains(KeyPad::SELECT) {
break;
}
},
@ -62,31 +72,11 @@ fn panic_hook_setup() { @@ -62,31 +72,11 @@ fn panic_hook_setup() {
pub mod applets;
pub mod console;
pub mod error;
pub mod gfx;
pub mod linear;
pub mod mii;
pub mod prelude;
pub mod services;
cfg_if::cfg_if! {
if #[cfg(all(feature = "romfs", romfs_exists))] {
pub mod romfs;
} else {
pub mod romfs {
//! The RomFS folder has not been detected and/or the `romfs` feature has not been enabled.
//!
//! Configure the path in Cargo.toml (the default path is "romfs"). Paths are relative to the
//! `CARGO_MANIFEST_DIR` environment variable, which is the directory containing the manifest of
//! your package.
//!
//! ```toml
//! [package.metadata.cargo-3ds]
//! romfs_dir = "romfs"
//! ```
}
}
}
#[cfg(test)]
mod test_runner;

3
ctru-rs/src/prelude.rs

@ -1,3 +1,2 @@ @@ -1,3 +1,2 @@
pub use crate::console::Console;
pub use crate::gfx::Gfx;
pub use crate::services::{hid::KeyPad, soc::Soc, Apt, Hid};
pub use crate::services::{gfx::Gfx, hid::KeyPad, soc::Soc, Apt, Hid};

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

@ -29,12 +29,12 @@ impl<'a> Title<'a> { @@ -29,12 +29,12 @@ impl<'a> Title<'a> {
self.id
}
pub fn get_product_code(&self) -> crate::Result<String> {
pub fn product_code(&self) -> crate::Result<String> {
let mut buf: [u8; 16] = [0; 16];
unsafe {
ResultCode(ctru_sys::AM_GetTitleProductCode(
self.mediatype as u32,
self.mediatype.into(),
self.id,
buf.as_mut_ptr(),
))?;
@ -42,12 +42,12 @@ impl<'a> Title<'a> { @@ -42,12 +42,12 @@ impl<'a> Title<'a> {
Ok(String::from_utf8_lossy(&buf).to_string())
}
pub fn get_title_info(&self) -> crate::Result<TitleInfo> {
pub fn title_info(&self) -> crate::Result<TitleInfo> {
let mut info = MaybeUninit::zeroed();
unsafe {
ResultCode(ctru_sys::AM_GetTitleInfo(
self.mediatype as u32,
self.mediatype.into(),
1,
&mut self.id.clone(),
info.as_mut_ptr() as _,
@ -68,22 +68,22 @@ impl Am { @@ -68,22 +68,22 @@ impl Am {
}
}
pub fn get_title_count(&self, mediatype: FsMediaType) -> crate::Result<u32> {
pub fn title_count(&self, mediatype: FsMediaType) -> crate::Result<u32> {
unsafe {
let mut count = 0;
ResultCode(ctru_sys::AM_GetTitleCount(mediatype as u32, &mut count))?;
ResultCode(ctru_sys::AM_GetTitleCount(mediatype.into(), &mut count))?;
Ok(count)
}
}
pub fn get_title_list(&self, mediatype: FsMediaType) -> crate::Result<Vec<Title>> {
let count = self.get_title_count(mediatype)?;
pub fn title_list(&self, mediatype: FsMediaType) -> crate::Result<Vec<Title>> {
let count = self.title_count(mediatype)?;
let mut buf = vec![0; count as usize];
let mut read_amount = 0;
unsafe {
ResultCode(ctru_sys::AM_GetTitleList(
&mut read_amount,
mediatype as u32,
mediatype.into(),
count,
buf.as_mut_ptr(),
))?;

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

@ -1,11 +1,10 @@ @@ -1,11 +1,10 @@
//! CAM service
//! Camera service
//!
//! The CAM service provides access to the cameras. Cameras can return 2D images
//! in the form of byte vectors which can be used for display or other usages.
//! The CAM service provides access to the cameras. Cameras can return images
//! in the form of byte vectors which can be displayed or used in other ways.
use crate::error::{Error, ResultCode};
use crate::services::gspgpu::FramebufferFormat;
use bitflags::bitflags;
use ctru_sys::Handle;
use std::time::Duration;
@ -21,191 +20,168 @@ pub struct Cam { @@ -21,191 +20,168 @@ pub struct Cam {
pub both_outer_cams: BothOutwardCam,
}
bitflags! {
/// A set of flags to be passed to [Camera::flip_image]
#[derive(Default)]
pub struct CamFlip: u32 {
const NONE = ctru_sys::FLIP_NONE;
const HORIZONTAL = ctru_sys::FLIP_HORIZONTAL;
const VERTICAL = ctru_sys::FLIP_VERTICAL;
const REVERSE = ctru_sys::FLIP_REVERSE;
}
}
bitflags! {
/// A set of flags to be passed to [Camera::set_view_size]
#[derive(Default)]
pub struct CamSize: u32 {
const VGA = ctru_sys::SIZE_VGA;
const QVGA = ctru_sys::SIZE_QVGA;
const QQVGA = ctru_sys::SIZE_QQVGA;
const CIF = ctru_sys::SIZE_CIF;
const QCIF = ctru_sys::SIZE_QCIF;
const DS_LCD = ctru_sys::SIZE_DS_LCD;
const DS_LCD_X4 = ctru_sys::SIZE_DS_LCDx4;
const CTR_TOP_LCD = ctru_sys::SIZE_CTR_TOP_LCD;
const CTR_BOTTOM_LCD = ctru_sys::SIZE_CTR_BOTTOM_LCD;
}
}
bitflags! {
/// A set of flags to be passed to [Camera::set_frame_rate]
#[derive(Default)]
pub struct CamFrameRate: u32 {
const RATE_15 = ctru_sys::FRAME_RATE_15;
const RATE_15_TO_5 = ctru_sys::FRAME_RATE_15_TO_5;
const RATE_15_TO_2 = ctru_sys::FRAME_RATE_15_TO_2;
const RATE_10 = ctru_sys::FRAME_RATE_10;
const RATE_8_5 = ctru_sys::FRAME_RATE_8_5;
const RATE_5 = ctru_sys::FRAME_RATE_5;
const RATE_20 = ctru_sys::FRAME_RATE_20;
const RATE_20_TO_5 = ctru_sys::FRAME_RATE_20_TO_5;
const RATE_30 = ctru_sys::FRAME_RATE_30;
const RATE_30_TO_5 = ctru_sys::FRAME_RATE_30_TO_5;
const RATE_15_TO_10 = ctru_sys::FRAME_RATE_15_TO_10;
const RATE_20_TO_10 = ctru_sys::FRAME_RATE_20_TO_10;
const RATE_30_TO_10 = ctru_sys::FRAME_RATE_30_TO_10;
}
}
bitflags! {
/// A set of flags to be passed to [Camera::set_white_balance] or
/// Flag to pass to [Camera::flip_image]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum FlipMode {
None = ctru_sys::FLIP_NONE,
Horizontal = ctru_sys::FLIP_HORIZONTAL,
Vertical = ctru_sys::FLIP_VERTICAL,
Reverse = ctru_sys::FLIP_REVERSE,
}
/// Flag to pass to [Camera::set_view_size]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum ViewSize {
TopLCD = ctru_sys::SIZE_CTR_TOP_LCD,
/// Equivalent to QVga
BottomLCD = ctru_sys::SIZE_CTR_BOTTOM_LCD,
Vga = ctru_sys::SIZE_VGA,
QQVga = ctru_sys::SIZE_QQVGA,
Cif = ctru_sys::SIZE_CIF,
QCif = ctru_sys::SIZE_QCIF,
/// Nintendo DS Screen
DS = ctru_sys::SIZE_DS_LCD,
/// Nintendo DS Screen x4
DSX4 = ctru_sys::SIZE_DS_LCDx4,
}
/// Flag to pass to [Camera::set_frame_rate]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum FrameRate {
Fps15 = ctru_sys::FRAME_RATE_15,
Fps15To5 = ctru_sys::FRAME_RATE_15_TO_5,
Fps15To2 = ctru_sys::FRAME_RATE_15_TO_2,
Fps10 = ctru_sys::FRAME_RATE_10,
Fps8_5 = ctru_sys::FRAME_RATE_8_5,
Fps5 = ctru_sys::FRAME_RATE_5,
Fps20 = ctru_sys::FRAME_RATE_20,
Fps20To5 = ctru_sys::FRAME_RATE_20_TO_5,
Fps30 = ctru_sys::FRAME_RATE_30,
Fps30To5 = ctru_sys::FRAME_RATE_30_TO_5,
Fps15To10 = ctru_sys::FRAME_RATE_15_TO_10,
Fps20To10 = ctru_sys::FRAME_RATE_20_TO_10,
Fps30To10 = ctru_sys::FRAME_RATE_30_TO_10,
}
/// Flag to pass to [Camera::set_white_balance] or
/// [Camera::set_white_balance_without_base_up]
#[derive(Default)]
pub struct CamWhiteBalance: u32 {
const AUTO = ctru_sys::WHITE_BALANCE_AUTO;
const BALANCE_3200K = ctru_sys::WHITE_BALANCE_3200K;
const BALANCE_4150K = ctru_sys::WHITE_BALANCE_4150K;
const BALANCE_5200K = ctru_sys::WHITE_BALANCE_5200K;
const BALANCE_6000K = ctru_sys::WHITE_BALANCE_6000K;
const BALANCE_7000K = ctru_sys::WHITE_BALANCE_7000K;
const NORMAL = ctru_sys::WHITE_BALANCE_NORMAL;
const TUNGSTEN = ctru_sys::WHITE_BALANCE_TUNGSTEN;
const WHITE_FLUORESCENT_LIGHT = ctru_sys::WHITE_BALANCE_WHITE_FLUORESCENT_LIGHT;
const DAYLIGHT = ctru_sys::WHITE_BALANCE_DAYLIGHT;
const CLOUDY = ctru_sys::WHITE_BALANCE_CLOUDY;
const HORIZON = ctru_sys::WHITE_BALANCE_HORIZON;
const SHADE = ctru_sys::WHITE_BALANCE_SHADE;
}
}
bitflags! {
/// A set of flags to be passed to [Camera::set_photo_mode]
#[derive(Default)]
pub struct CamPhotoMode: u32 {
const NORMAL = ctru_sys::PHOTO_MODE_NORMAL;
const PORTRAIT = ctru_sys::PHOTO_MODE_PORTRAIT;
const LANDSCAPE = ctru_sys::PHOTO_MODE_LANDSCAPE;
const NIGHTVIEW = ctru_sys::PHOTO_MODE_NIGHTVIEW;
const LETTER = ctru_sys::PHOTO_MODE_LETTER;
}
}
bitflags! {
/// A set of flags to be passed to [Camera::set_effect]
#[derive(Default)]
pub struct CamEffect: u32 {
const NONE = ctru_sys::EFFECT_NONE;
const MONO = ctru_sys::EFFECT_MONO;
const SEPIA = ctru_sys::EFFECT_SEPIA;
const NEGATIVE = ctru_sys::EFFECT_NEGATIVE;
const NEGAFILM = ctru_sys::EFFECT_NEGAFILM;
const SEPIA01 = ctru_sys::EFFECT_SEPIA01;
}
}
bitflags! {
/// A set of flags to be passed to [Camera::set_contrast]
#[derive(Default)]
pub struct CamContrast: u32 {
const PATTERN_01 = ctru_sys::CONTRAST_PATTERN_01;
const PATTERN_02 = ctru_sys::CONTRAST_PATTERN_02;
const PATTERN_03 = ctru_sys::CONTRAST_PATTERN_03;
const PATTERN_04 = ctru_sys::CONTRAST_PATTERN_04;
const PATTERN_05 = ctru_sys::CONTRAST_PATTERN_05;
const PATTERN_06 = ctru_sys::CONTRAST_PATTERN_06;
const PATTERN_07 = ctru_sys::CONTRAST_PATTERN_07;
const PATTERN_08 = ctru_sys::CONTRAST_PATTERN_08;
const PATTERN_09 = ctru_sys::CONTRAST_PATTERN_09;
const PATTERN_10 = ctru_sys::CONTRAST_PATTERN_10;
const PATTERN_11 = ctru_sys::CONTRAST_PATTERN_11;
const LOW = ctru_sys::CONTRAST_LOW;
const NORMAL = ctru_sys::CONTRAST_NORMAL;
const HIGH = ctru_sys::CONTRAST_HIGH;
}
}
bitflags! {
/// A set of flags to be passed to [Camera::set_lens_correction]
#[derive(Default)]
pub struct CamLensCorrection: u32 {
const OFF = ctru_sys::LENS_CORRECTION_OFF;
const ON_70 = ctru_sys::LENS_CORRECTION_ON_70;
const ON_90 = ctru_sys::LENS_CORRECTION_ON_90;
const DARK = ctru_sys::LENS_CORRECTION_DARK;
const NORMAL = ctru_sys::LENS_CORRECTION_NORMAL;
const BRIGHT = ctru_sys::LENS_CORRECTION_BRIGHT;
}
}
bitflags! {
/// A set of flags to be passed to [Camera::set_output_format]
#[derive(Default)]
pub struct CamOutputFormat: u32 {
const YUV_422 = ctru_sys::OUTPUT_YUV_422;
const RGB_565 = ctru_sys::OUTPUT_RGB_565;
}
}
impl TryFrom<FramebufferFormat> for CamOutputFormat {
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum WhiteBalance {
/// Normal
Auto = ctru_sys::WHITE_BALANCE_AUTO,
/// Tungsten
Temp3200K = ctru_sys::WHITE_BALANCE_3200K,
/// Fluorescent Light
Temp4150K = ctru_sys::WHITE_BALANCE_4150K,
/// Daylight
Temp5200K = ctru_sys::WHITE_BALANCE_5200K,
/// Cloudy/Horizon
Temp6000K = ctru_sys::WHITE_BALANCE_6000K,
///Shade
Temp7000K = ctru_sys::WHITE_BALANCE_7000K,
}
/// Flag to pass to [Camera::set_photo_mode]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum PhotoMode {
Normal = ctru_sys::PHOTO_MODE_NORMAL,
Portrait = ctru_sys::PHOTO_MODE_PORTRAIT,
Landscape = ctru_sys::PHOTO_MODE_LANDSCAPE,
NightView = ctru_sys::PHOTO_MODE_NIGHTVIEW,
Letter = ctru_sys::PHOTO_MODE_LETTER,
}
/// Flag to pass to [Camera::set_effect]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum Effect {
None = ctru_sys::EFFECT_NONE,
Mono = ctru_sys::EFFECT_MONO,
Sepia = ctru_sys::EFFECT_SEPIA,
Negative = ctru_sys::EFFECT_NEGATIVE,
Negafilm = ctru_sys::EFFECT_NEGAFILM,
Sepia01 = ctru_sys::EFFECT_SEPIA01,
}
/// Flag to pass to [Camera::set_contrast]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum Contrast {
/// OFF
Low = ctru_sys::CONTRAST_LOW,
/// Brightness ratio: 70
Normal = ctru_sys::CONTRAST_NORMAL,
/// Brightness ratio: 90
High = ctru_sys::CONTRAST_HIGH,
}
/// Flag to pass to [Camera::set_lens_correction]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum LensCorrection {
Off = ctru_sys::LENS_CORRECTION_DARK,
Normal = ctru_sys::LENS_CORRECTION_NORMAL,
Bright = ctru_sys::LENS_CORRECTION_BRIGHT,
}
/// Flag to pass to [Camera::set_output_format]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum OutputFormat {
Yuv422 = ctru_sys::OUTPUT_YUV_422,
Rgb565 = ctru_sys::OUTPUT_RGB_565,
}
/// Flag to pass to [Cam::play_shutter_sound]
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum ShutterSound {
Normal = ctru_sys::SHUTTER_SOUND_TYPE_NORMAL,
Movie = ctru_sys::SHUTTER_SOUND_TYPE_MOVIE,
MovieEnd = ctru_sys::SHUTTER_SOUND_TYPE_MOVIE_END,
}
impl TryFrom<FramebufferFormat> for OutputFormat {
type Error = ();
fn try_from(value: FramebufferFormat) -> Result<Self, Self::Error> {
match value {
FramebufferFormat::Rgb565 => Ok(CamOutputFormat::RGB_565),
FramebufferFormat::Rgb565 => Ok(OutputFormat::Rgb565),
_ => Err(()),
}
}
}
impl TryFrom<CamOutputFormat> for FramebufferFormat {
impl TryFrom<OutputFormat> for FramebufferFormat {
type Error = ();
fn try_from(value: CamOutputFormat) -> Result<Self, Self::Error> {
fn try_from(value: OutputFormat) -> Result<Self, Self::Error> {
match value {
CamOutputFormat::RGB_565 => Ok(FramebufferFormat::Rgb565),
OutputFormat::Rgb565 => Ok(FramebufferFormat::Rgb565),
_ => Err(()),
}
}
}
bitflags! {
/// A set of flags to be passed to [Cam::play_shutter_sound]
#[derive(Default)]
pub struct CamShutterSoundType: u32 {
const NORMAL = ctru_sys::SHUTTER_SOUND_TYPE_NORMAL;
const MOVIE = ctru_sys::SHUTTER_SOUND_TYPE_MOVIE;
const MOVIE_END = ctru_sys::SHUTTER_SOUND_TYPE_MOVIE_END;
}
}
/// Struct containing coordinates passed to [Camera::set_trimming_params].
pub struct CamTrimmingParams {
pub struct TrimmingParams {
x_start: i16,
y_start: i16,
x_end: i16,
y_end: i16,
}
impl CamTrimmingParams {
impl TrimmingParams {
/// Creates a new [CamTrimmingParams] and guarantees the start coordinates are less than or
/// equal to the end coordinates.
///
/// `x_start <= x_end && y_start <= y_end`
pub fn new(x_start: i16, y_start: i16, x_end: i16, y_end: i16) -> CamTrimmingParams {
pub fn new(x_start: i16, y_start: i16, x_end: i16, y_end: i16) -> TrimmingParams {
assert!(x_start <= x_end && y_start <= y_end);
Self {
x_start,
@ -307,7 +283,7 @@ pub trait Camera { @@ -307,7 +283,7 @@ pub trait Camera {
/// Returns the maximum amount of transfer bytes based on the view size, trimming, and other
/// modifications set to the camera
fn get_transfer_bytes(&self) -> crate::Result<u32> {
fn transfer_byte_count(&self) -> crate::Result<u32> {
unsafe {
let mut transfer_bytes = 0;
ResultCode(ctru_sys::CAMU_GetTransferBytes(
@ -336,8 +312,8 @@ pub trait Camera { @@ -336,8 +312,8 @@ pub trait Camera {
}
}
/// Sets trimming parameters based on coordinates specified inside a [CamTrimmingParams]
fn set_trimming_params(&mut self, params: CamTrimmingParams) -> crate::Result<()> {
/// Sets trimming parameters based on coordinates specified inside a [TrimmingParams]
fn set_trimming_params(&mut self, params: TrimmingParams) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetTrimmingParams(
self.port_as_raw(),
@ -350,8 +326,8 @@ pub trait Camera { @@ -350,8 +326,8 @@ pub trait Camera {
}
}
/// Returns the set [CamTrimmingParams] from the camera
fn get_trimming_params(&self) -> crate::Result<CamTrimmingParams> {
/// Returns the [TrimmingParams] set
fn trimming_params(&self) -> crate::Result<TrimmingParams> {
unsafe {
let mut x_start = 0;
let mut y_start = 0;
@ -365,7 +341,7 @@ pub trait Camera { @@ -365,7 +341,7 @@ pub trait Camera {
self.port_as_raw(),
))?;
Ok(CamTrimmingParams {
Ok(TrimmingParams {
x_start,
y_start,
x_end,
@ -404,27 +380,27 @@ pub trait Camera { @@ -404,27 +380,27 @@ pub trait Camera {
}
}
/// Sets the white balance mod of the camera based on the passed [CamWhiteBalance] argument
fn set_white_balance(&mut self, white_balance: CamWhiteBalance) -> crate::Result<()> {
/// Sets the white balance mod of the camera based on the passed [WhiteBalance] argument
fn set_white_balance(&mut self, white_balance: WhiteBalance) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetWhiteBalance(
self.camera_as_raw(),
white_balance.bits(),
white_balance.into(),
))?;
Ok(())
}
}
/// Sets the white balance mode of the camera based on the passed [CamWhiteBalance] argument
/// Sets the white balance mode of the camera based on the passed [WhiteBalance] argument
// TODO: Explain base up
fn set_white_balance_without_base_up(
&mut self,
white_balance: CamWhiteBalance,
white_balance: WhiteBalance,
) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetWhiteBalanceWithoutBaseUp(
self.camera_as_raw(),
white_balance.bits(),
white_balance.into(),
))?;
Ok(())
}
@ -484,12 +460,12 @@ pub trait Camera { @@ -484,12 +460,12 @@ pub trait Camera {
}
}
/// Sets the flip direction of the camera's image based on the passed [CamFlip] argument
fn flip_image(&mut self, flip: CamFlip) -> crate::Result<()> {
/// Sets the flip direction of the camera's image based on the passed [FlipMode] argument
fn flip_image(&mut self, flip: FlipMode) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_FlipImage(
self.camera_as_raw(),
flip.bits(),
flip.into(),
ctru_sys::CONTEXT_A,
))?;
Ok(())
@ -530,82 +506,82 @@ pub trait Camera { @@ -530,82 +506,82 @@ pub trait Camera {
}
}
/// Sets the view size of the camera based on the passed [CamSize] argument.
fn set_view_size(&mut self, size: CamSize) -> crate::Result<()> {
/// Sets the view size of the camera based on the passed [ViewSize] argument.
fn set_view_size(&mut self, size: ViewSize) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetSize(
self.camera_as_raw(),
size.bits(),
size.into(),
ctru_sys::CONTEXT_A,
))?;
Ok(())
}
}
/// Sets the frame rate of the camera based on the passed [CamFrameRate] argument.
fn set_frame_rate(&mut self, frame_rate: CamFrameRate) -> crate::Result<()> {
/// Sets the frame rate of the camera based on the passed [FrameRate] argument.
fn set_frame_rate(&mut self, frame_rate: FrameRate) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetFrameRate(
self.camera_as_raw(),
frame_rate.bits(),
frame_rate.into(),
))?;
Ok(())
}
}
/// Sets the photo mode of the camera based on the passed [CamPhotoMode] argument.
fn set_photo_mode(&mut self, photo_mode: CamPhotoMode) -> crate::Result<()> {
/// Sets the photo mode of the camera based on the passed [PhotoMode] argument.
fn set_photo_mode(&mut self, photo_mode: PhotoMode) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetPhotoMode(
self.camera_as_raw(),
photo_mode.bits(),
photo_mode.into(),
))?;
Ok(())
}
}
/// Sets the effect of the camera based on the passed [CamEffect] argument.
/// Sets the effect of the camera based on the passed [Effect] argument.
///
/// Multiple effects can be set at once by combining the bitflags of [CamEffect]
fn set_effect(&mut self, effect: CamEffect) -> crate::Result<()> {
fn set_effect(&mut self, effect: Effect) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetEffect(
self.camera_as_raw(),
effect.bits(),
effect.into(),
ctru_sys::CONTEXT_A,
))?;
Ok(())
}
}
/// Sets the contrast of the camera based on the passed [CamContrast] argument.
fn set_contrast(&mut self, contrast: CamContrast) -> crate::Result<()> {
/// Sets the contrast of the camera based on the passed [Contrast] argument.
fn set_contrast(&mut self, contrast: Contrast) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetContrast(
self.camera_as_raw(),
contrast.bits(),
contrast.into(),
))?;
Ok(())
}
}
/// Sets the lens correction of the camera based on the passed [CamLensCorrection] argument.
fn set_lens_correction(&mut self, lens_correction: CamLensCorrection) -> crate::Result<()> {
/// Sets the lens correction of the camera based on the passed [LensCorrection] argument.
fn set_lens_correction(&mut self, lens_correction: LensCorrection) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetLensCorrection(
self.camera_as_raw(),
lens_correction.bits(),
lens_correction.into(),
))?;
Ok(())
}
}
/// Sets the output format of the camera based on the passed [CamOutputFormat] argument.
fn set_output_format(&mut self, format: CamOutputFormat) -> crate::Result<()> {
/// Sets the output format of the camera based on the passed [OutputFormat] argument.
fn set_output_format(&mut self, format: OutputFormat) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_SetOutputFormat(
self.camera_as_raw(),
format.bits(),
format.into(),
ctru_sys::CONTEXT_A,
))?;
Ok(())
@ -687,7 +663,7 @@ pub trait Camera { @@ -687,7 +663,7 @@ pub trait Camera {
}
/// Returns the current [ImageQualityCalibrationData] for the camera
fn get_image_quality_calibration_data(&self) -> crate::Result<ImageQualityCalibrationData> {
fn image_quality_calibration_data(&self) -> crate::Result<ImageQualityCalibrationData> {
unsafe {
let mut data = ImageQualityCalibrationData::default();
ResultCode(ctru_sys::CAMU_GetImageQualityCalibrationData(&mut data.0))?;
@ -806,10 +782,10 @@ impl Cam { @@ -806,10 +782,10 @@ impl Cam {
}
}
/// Plays the specified sound based on the [CamShutterSoundType] argument
pub fn play_shutter_sound(&self, sound: CamShutterSoundType) -> crate::Result<()> {
/// Plays the specified sound based on the [ShutterSound] argument
pub fn play_shutter_sound(&self, sound: ShutterSound) -> crate::Result<()> {
unsafe {
ResultCode(ctru_sys::CAMU_PlayShutterSound(sound.bits()))?;
ResultCode(ctru_sys::CAMU_PlayShutterSound(sound.into()))?;
Ok(())
}
}
@ -820,3 +796,14 @@ impl Drop for Cam { @@ -820,3 +796,14 @@ impl Drop for Cam {
unsafe { ctru_sys::camExit() };
}
}
from_impl!(FlipMode, ctru_sys::CAMU_Flip);
from_impl!(ViewSize, ctru_sys::CAMU_Size);
from_impl!(FrameRate, ctru_sys::CAMU_FrameRate);
from_impl!(WhiteBalance, ctru_sys::CAMU_WhiteBalance);
from_impl!(PhotoMode, ctru_sys::CAMU_PhotoMode);
from_impl!(Effect, ctru_sys::CAMU_Effect);
from_impl!(Contrast, ctru_sys::CAMU_Contrast);
from_impl!(LensCorrection, ctru_sys::CAMU_LensCorrection);
from_impl!(OutputFormat, ctru_sys::CAMU_OutputFormat);
from_impl!(ShutterSound, ctru_sys::CAMU_ShutterSoundType);

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

@ -67,7 +67,7 @@ impl Cfgu { @@ -67,7 +67,7 @@ impl Cfgu {
}
/// Gets system region from secure info
pub fn get_region(&self) -> crate::Result<Region> {
pub fn region(&self) -> crate::Result<Region> {
let mut region: u8 = 0;
ResultCode(unsafe { ctru_sys::CFGU_SecureInfoGetRegion(&mut region) })?;
@ -75,7 +75,7 @@ impl Cfgu { @@ -75,7 +75,7 @@ impl Cfgu {
}
/// Gets system's model
pub fn get_model(&self) -> crate::Result<SystemModel> {
pub fn model(&self) -> crate::Result<SystemModel> {
let mut model: u8 = 0;
ResultCode(unsafe { ctru_sys::CFGU_GetSystemModel(&mut model) })?;
@ -83,7 +83,7 @@ impl Cfgu { @@ -83,7 +83,7 @@ impl Cfgu {
}
/// Gets system's language
pub fn get_language(&self) -> crate::Result<Language> {
pub fn language(&self) -> crate::Result<Language> {
let mut language: u8 = 0;
ResultCode(unsafe { ctru_sys::CFGU_GetSystemLanguage(&mut language) })?;
@ -115,19 +115,9 @@ impl Drop for Cfgu { @@ -115,19 +115,9 @@ impl Drop for Cfgu {
}
}
macro_rules! from_type_to_u8 {
($from_type:ty) => {
impl From<$from_type> for u8 {
fn from(v: $from_type) -> Self {
v as u8
}
}
};
}
from_type_to_u8!(Region);
from_type_to_u8!(Language);
from_type_to_u8!(SystemModel);
from_impl!(Region, u8);
from_impl!(Language, u8);
from_impl!(SystemModel, u8);
impl TryFrom<u8> for Region {
type Error = ();

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

@ -1,7 +1,7 @@ @@ -1,7 +1,7 @@
//! Filesystem service
//!
//! This module contains basic methods to manipulate the contents of the 3DS's filesystem.
//! Only the SD card is currently supported.
//! Only the SD card is currently supported. You should prefer using `std::fs`.
use bitflags::bitflags;
use std::ffi::OsString;
@ -52,38 +52,40 @@ pub enum FsMediaType { @@ -52,38 +52,40 @@ pub enum FsMediaType {
}
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum PathType {
Invalid,
Empty,
Binary,
ASCII,
UTF16,
Invalid = ctru_sys::PATH_INVALID,
Empty = ctru_sys::PATH_EMPTY,
Binary = ctru_sys::PATH_BINARY,
ASCII = ctru_sys::PATH_ASCII,
UTF16 = ctru_sys::PATH_UTF16,
}
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum ArchiveID {
RomFS,
Savedata,
Extdata,
SharedExtdata,
SystemSavedata,
Sdmc,
SdmcWriteOnly,
BossExtdata,
CardSpiFS,
ExtDataAndBossExtdata,
SystemSaveData2,
NandRW,
NandRO,
NandROWriteAccess,
SaveDataAndContent,
SaveDataAndContent2,
NandCtrFS,
TwlPhoto,
NandTwlFS,
GameCardSavedata,
UserSavedata,
DemoSavedata,
RomFS = ctru_sys::ARCHIVE_ROMFS,
Savedata = ctru_sys::ARCHIVE_SAVEDATA,
Extdata = ctru_sys::ARCHIVE_EXTDATA,
SharedExtdata = ctru_sys::ARCHIVE_SHARED_EXTDATA,
SystemSavedata = ctru_sys::ARCHIVE_SYSTEM_SAVEDATA,
Sdmc = ctru_sys::ARCHIVE_SDMC,
SdmcWriteOnly = ctru_sys::ARCHIVE_SDMC_WRITE_ONLY,
BossExtdata = ctru_sys::ARCHIVE_BOSS_EXTDATA,
CardSpiFS = ctru_sys::ARCHIVE_CARD_SPIFS,
ExtDataAndBossExtdata = ctru_sys::ARCHIVE_EXTDATA_AND_BOSS_EXTDATA,
SystemSaveData2 = ctru_sys::ARCHIVE_SYSTEM_SAVEDATA2,
NandRW = ctru_sys::ARCHIVE_NAND_RW,
NandRO = ctru_sys::ARCHIVE_NAND_RO,
NandROWriteAccess = ctru_sys::ARCHIVE_NAND_RO_WRITE_ACCESS,
SaveDataAndContent = ctru_sys::ARCHIVE_SAVEDATA_AND_CONTENT,
SaveDataAndContent2 = ctru_sys::ARCHIVE_SAVEDATA_AND_CONTENT2,
NandCtrFS = ctru_sys::ARCHIVE_NAND_CTR_FS,
TwlPhoto = ctru_sys::ARCHIVE_TWL_PHOTO,
NandTwlFS = ctru_sys::ARCHIVE_NAND_TWL_FS,
GameCardSavedata = ctru_sys::ARCHIVE_GAMECARD_SAVEDATA,
UserSavedata = ctru_sys::ARCHIVE_USER_SAVEDATA,
DemoSavedata = ctru_sys::ARCHIVE_DEMO_SAVEDATA,
}
/// Represents the filesystem service. No file IO can be performed
@ -327,7 +329,7 @@ impl Archive { @@ -327,7 +329,7 @@ impl Archive {
/// Retrieves an Archive's [`ArchiveID`]
///
/// [`ArchiveID`]: enum.ArchiveID.html
pub fn get_id(&self) -> ArchiveID {
pub fn id(&self) -> ArchiveID {
self.id
}
}
@ -587,7 +589,7 @@ impl OpenOptions { @@ -587,7 +589,7 @@ impl OpenOptions {
///
/// [`Archive`]: struct.Archive.html
pub fn open<P: AsRef<Path>>(&self, path: P) -> IoResult<File> {
self._open(path.as_ref(), self.get_open_flags())
self._open(path.as_ref(), self.open_flags())
}
fn _open(&self, path: &Path, flags: FsOpen) -> IoResult<File> {
@ -626,7 +628,7 @@ impl OpenOptions { @@ -626,7 +628,7 @@ impl OpenOptions {
}
}
fn get_open_flags(&self) -> FsOpen {
fn open_flags(&self) -> FsOpen {
match (self.read, self.write || self.append, self.create) {
(true, false, false) => FsOpen::FS_OPEN_READ,
(false, true, false) => FsOpen::FS_OPEN_WRITE,
@ -1016,45 +1018,6 @@ impl Drop for Dir { @@ -1016,45 +1018,6 @@ impl Drop for Dir {
}
}
impl From<PathType> for ctru_sys::FS_PathType {
fn from(p: PathType) -> Self {
use self::PathType::*;
match p {
Invalid => ctru_sys::PATH_INVALID,
Empty => ctru_sys::PATH_EMPTY,
Binary => ctru_sys::PATH_BINARY,
ASCII => ctru_sys::PATH_ASCII,
UTF16 => ctru_sys::PATH_UTF16,
}
}
}
impl From<ArchiveID> for ctru_sys::FS_ArchiveID {
fn from(a: ArchiveID) -> Self {
use self::ArchiveID::*;
match a {
RomFS => ctru_sys::ARCHIVE_ROMFS,
Savedata => ctru_sys::ARCHIVE_SAVEDATA,
Extdata => ctru_sys::ARCHIVE_EXTDATA,
SharedExtdata => ctru_sys::ARCHIVE_SHARED_EXTDATA,
SystemSavedata => ctru_sys::ARCHIVE_SYSTEM_SAVEDATA,
Sdmc => ctru_sys::ARCHIVE_SDMC,
SdmcWriteOnly => ctru_sys::ARCHIVE_SDMC_WRITE_ONLY,
BossExtdata => ctru_sys::ARCHIVE_BOSS_EXTDATA,
CardSpiFS => ctru_sys::ARCHIVE_CARD_SPIFS,
ExtDataAndBossExtdata => ctru_sys::ARCHIVE_EXTDATA_AND_BOSS_EXTDATA,
SystemSaveData2 => ctru_sys::ARCHIVE_SYSTEM_SAVEDATA2,
NandRW => ctru_sys::ARCHIVE_NAND_RW,
NandRO => ctru_sys::ARCHIVE_NAND_RO,
NandROWriteAccess => ctru_sys::ARCHIVE_NAND_RO_WRITE_ACCESS,
SaveDataAndContent => ctru_sys::ARCHIVE_SAVEDATA_AND_CONTENT,
SaveDataAndContent2 => ctru_sys::ARCHIVE_SAVEDATA_AND_CONTENT2,
NandCtrFS => ctru_sys::ARCHIVE_NAND_CTR_FS,
TwlPhoto => ctru_sys::ARCHIVE_TWL_PHOTO,
NandTwlFS => ctru_sys::ARCHIVE_NAND_TWL_FS,
GameCardSavedata => ctru_sys::ARCHIVE_GAMECARD_SAVEDATA,
UserSavedata => ctru_sys::ARCHIVE_USER_SAVEDATA,
DemoSavedata => ctru_sys::ARCHIVE_DEMO_SAVEDATA,
}
}
}
from_impl!(FsMediaType, ctru_sys::FS_MediaType);
from_impl!(PathType, ctru_sys::FS_PathType);
from_impl!(ArchiveID, ctru_sys::FS_ArchiveID);

22
ctru-rs/src/gfx.rs → ctru-rs/src/services/gfx.rs

@ -33,7 +33,7 @@ pub trait Screen: private::Sealed { @@ -33,7 +33,7 @@ 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 get_raw_framebuffer(&mut self) -> RawFrameBuffer {
fn raw_framebuffer(&mut self) -> RawFrameBuffer {
let mut width = 0;
let mut height = 0;
let ptr = unsafe {
@ -56,8 +56,8 @@ pub trait Screen: private::Sealed { @@ -56,8 +56,8 @@ pub trait Screen: private::Sealed {
}
/// Gets the framebuffer format
fn get_framebuffer_format(&self) -> FramebufferFormat {
unsafe { ctru_sys::gfxGetScreenFormat(self.as_raw()).into() }
fn framebuffer_format(&self) -> FramebufferFormat {
unsafe { ctru_sys::gfxGetScreenFormat(self.as_raw()) }.into()
}
/// Change the framebuffer format
@ -104,14 +104,15 @@ pub struct RawFrameBuffer<'screen> { @@ -104,14 +104,15 @@ pub struct RawFrameBuffer<'screen> {
}
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
/// Side of top screen framebuffer
///
/// The top screen of the 3DS can have two separate sets of framebuffers to support its 3D functionality
pub enum Side {
/// The left framebuffer. This framebuffer is also the one used when 3D is disabled
Left,
Left = ctru_sys::GFX_LEFT,
/// The right framebuffer
Right,
Right = ctru_sys::GFX_RIGHT,
}
/// A handle to libctru's gfx module. This module is a wrapper around the GSPGPU service that
@ -238,7 +239,7 @@ impl TopScreen { @@ -238,7 +239,7 @@ impl TopScreen {
}
/// Returns whether or not wide mode is enabled on the top screen.
pub fn get_wide_mode(&self) -> bool {
pub fn is_wide(&self) -> bool {
unsafe { ctru_sys::gfxIsWide() }
}
}
@ -283,14 +284,7 @@ impl Screen for BottomScreen { @@ -283,14 +284,7 @@ impl Screen for BottomScreen {
}
}
impl From<Side> for ctru_sys::gfx3dSide_t {
fn from(s: Side) -> ctru_sys::gfx3dSide_t {
match s {
Side::Left => ctru_sys::GFX_LEFT,
Side::Right => ctru_sys::GFX_RIGHT,
}
}
}
from_impl!(Side, ctru_sys::gfx3dSide_t);
#[cfg(test)]
mod tests {

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

@ -1,31 +1,31 @@ @@ -1,31 +1,31 @@
//! GSPGPU service
use std::convert::From;
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum Event {
Psc0,
Psc1,
VBlank0,
VBlank1,
PPF,
P3D,
DMA,
Psc0 = ctru_sys::GSPGPU_EVENT_PSC0,
Psc1 = ctru_sys::GSPGPU_EVENT_PSC1,
VBlank0 = ctru_sys::GSPGPU_EVENT_VBlank0,
VBlank1 = ctru_sys::GSPGPU_EVENT_VBlank1,
PPF = ctru_sys::GSPGPU_EVENT_PPF,
P3D = ctru_sys::GSPGPU_EVENT_P3D,
DMA = ctru_sys::GSPGPU_EVENT_DMA,
}
/// The different framebuffer formats supported by the 3DS
/// Framebuffer formats supported by the 3DS
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum FramebufferFormat {
/// RGBA8. 4 bytes per pixel
Rgba8,
Rgba8 = ctru_sys::GSP_RGBA8_OES,
/// BGR8. 3 bytes per pixel
Bgr8,
Bgr8 = ctru_sys::GSP_BGR8_OES,
/// RGB565. 2 bytes per pixel
Rgb565,
Rgb565 = ctru_sys::GSP_RGB565_OES,
/// RGB5A1. 2 bytes per pixel
Rgb5A1,
Rgb5A1 = ctru_sys::GSP_RGB5_A1_OES,
/// RGBA4. 2 bytes per pixel
Rgba4,
Rgba4 = ctru_sys::GSP_RGBA4_OES,
}
impl FramebufferFormat {
@ -65,30 +65,5 @@ impl From<ctru_sys::GSPGPU_FramebufferFormat> for FramebufferFormat { @@ -65,30 +65,5 @@ impl From<ctru_sys::GSPGPU_FramebufferFormat> for FramebufferFormat {
}
}
impl From<FramebufferFormat> for ctru_sys::GSPGPU_FramebufferFormat {
fn from(g: FramebufferFormat) -> Self {
use self::FramebufferFormat::*;
match g {
Rgba8 => ctru_sys::GSP_RGBA8_OES,
Bgr8 => ctru_sys::GSP_BGR8_OES,
Rgb565 => ctru_sys::GSP_RGB565_OES,
Rgb5A1 => ctru_sys::GSP_RGB5_A1_OES,
Rgba4 => ctru_sys::GSP_RGBA4_OES,
}
}
}
impl From<Event> for ctru_sys::GSPGPU_Event {
fn from(ev: Event) -> Self {
use self::Event::*;
match ev {
Psc0 => ctru_sys::GSPGPU_EVENT_PSC0,
Psc1 => ctru_sys::GSPGPU_EVENT_PSC1,
VBlank0 => ctru_sys::GSPGPU_EVENT_VBlank0,
VBlank1 => ctru_sys::GSPGPU_EVENT_VBlank1,
PPF => ctru_sys::GSPGPU_EVENT_PPF,
P3D => ctru_sys::GSPGPU_EVENT_P3D,
DMA => ctru_sys::GSPGPU_EVENT_DMA,
}
}
}
from_impl!(FramebufferFormat, ctru_sys::GSPGPU_FramebufferFormat);
from_impl!(Event, ctru_sys::GSPGPU_Event);

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

@ -10,34 +10,34 @@ bitflags::bitflags! { @@ -10,34 +10,34 @@ bitflags::bitflags! {
/// inputs on the 3DS
#[derive(Default)]
pub struct KeyPad: u32 {
const KEY_A = 1u32 << 0;
const KEY_B = 1u32 << 1;
const KEY_SELECT = 1u32 << 2;
const KEY_START = 1u32 << 3;
const KEY_DRIGHT = 1u32 << 4;
const KEY_DLEFT = 1u32 << 5;
const KEY_DUP = 1u32 << 6;
const KEY_DDOWN = 1u32 << 7;
const KEY_R = 1u32 << 8;
const KEY_L = 1u32 << 9;
const KEY_X = 1u32 << 10;
const KEY_Y = 1u32 << 11;
const KEY_ZL = 1u32 << 14;
const KEY_ZR = 1u32 << 15;
const KEY_TOUCH = 1u32 << 20;
const KEY_CSTICK_RIGHT = 1u32 << 24;
const KEY_CSTICK_LEFT = 1u32 << 25;
const KEY_CSTICK_UP = 1u32 << 26;
const KEY_CSTICK_DOWN = 1u32 << 27;
const KEY_CPAD_RIGHT = 1u32 << 28;
const KEY_CPAD_LEFT = 1u32 << 29;
const KEY_CPAD_UP = 1u32 << 30;
const KEY_CPAD_DOWN = 1u32 << 31;
// convenience catch-all for the dpad and cpad
const KEY_UP = KeyPad::KEY_DUP.bits | KeyPad::KEY_CPAD_UP.bits;
const KEY_DOWN = KeyPad::KEY_DDOWN.bits | KeyPad::KEY_CPAD_DOWN.bits;
const KEY_LEFT = KeyPad::KEY_DLEFT.bits | KeyPad::KEY_CPAD_LEFT.bits;
const KEY_RIGHT = KeyPad::KEY_DRIGHT.bits | KeyPad::KEY_CPAD_RIGHT.bits;
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 R = ctru_sys::KEY_R;
const L = ctru_sys::KEY_L;
const X = ctru_sys::KEY_X;
const Y = ctru_sys::KEY_Y;
const ZL = ctru_sys::KEY_ZL;
const ZR = ctru_sys::KEY_ZR;
const TOUCH = ctru_sys::KEY_TOUCH;
const CSTICK_RIGHT = ctru_sys::KEY_CSTICK_RIGHT;
const CSTICK_LEFT = ctru_sys::KEY_CSTICK_LEFT;
const CSTICK_UP = ctru_sys::KEY_CSTICK_UP;
const CSTICK_DOWN = ctru_sys::KEY_CSTICK_DOWN;
const CPAD_RIGHT = ctru_sys::KEY_CPAD_RIGHT;
const CPAD_LEFT = ctru_sys::KEY_CPAD_LEFT;
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();
}
}

20
ctru-rs/src/services/mod.rs

@ -10,6 +10,7 @@ pub mod apt; @@ -10,6 +10,7 @@ pub mod apt;
pub mod cam;
pub mod cfgu;
pub mod fs;
pub mod gfx;
pub mod gspgpu;
pub mod hid;
pub mod ndsp;
@ -18,6 +19,25 @@ mod reference; @@ -18,6 +19,25 @@ mod reference;
pub mod soc;
pub mod sslc;
cfg_if::cfg_if! {
if #[cfg(all(feature = "romfs", romfs_exists))] {
pub mod romfs;
} else {
pub mod romfs {
//! The RomFS folder has not been detected and/or the `romfs` feature has not been enabled.
//!
//! Configure the path in Cargo.toml (the default path is "romfs"). Paths are relative to the
//! `CARGO_MANIFEST_DIR` environment variable, which is the directory containing the manifest of
//! your package.
//!
//! ```toml
//! [package.metadata.cargo-3ds]
//! romfs_dir = "romfs"
//! ```
}
}
}
pub use self::apt::Apt;
pub use self::hid::Hid;

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

@ -122,7 +122,7 @@ impl Ndsp { @@ -122,7 +122,7 @@ impl Ndsp {
/// Set the audio output mode. Defaults to `OutputMode::Stereo`.
pub fn set_output_mode(&mut self, mode: OutputMode) {
unsafe { ctru_sys::ndspSetOutputMode(mode as u32) };
unsafe { ctru_sys::ndspSetOutputMode(mode.into()) };
}
}
@ -172,12 +172,12 @@ impl Channel<'_> { @@ -172,12 +172,12 @@ impl Channel<'_> {
/// Set the channel's output format.
/// Change this setting based on the used sample's format.
pub fn set_format(&self, format: AudioFormat) {
unsafe { ctru_sys::ndspChnSetFormat(self.id.into(), format as u16) };
unsafe { ctru_sys::ndspChnSetFormat(self.id.into(), format.into()) };
}
/// Set the channel's interpolation mode.
pub fn set_interpolation(&self, interp_type: InterpolationType) {
unsafe { ctru_sys::ndspChnSetInterp(self.id.into(), interp_type as u32) };
unsafe { ctru_sys::ndspChnSetInterp(self.id.into(), interp_type.into()) };
}
/// Set the channel's volume mix.
@ -454,3 +454,7 @@ impl Drop for Ndsp { @@ -454,3 +454,7 @@ impl Drop for Ndsp {
}
}
}
from_impl!(InterpolationType, ctru_sys::ndspInterpType);
from_impl!(OutputMode, ctru_sys::ndspOutputMode);
from_impl!(AudioFormat, u16);

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

@ -8,26 +8,26 @@ use crate::Result; @@ -8,26 +8,26 @@ use crate::Result;
#[repr(u32)]
pub enum AESAlgorithm {
CbcEnc,
CbcDec,
CtrEnc,
CtrDec,
CcmEnc,
CcmDec,
CbcEnc = ctru_sys::PS_ALGORITHM_CBC_ENC,
CbcDec = ctru_sys::PS_ALGORITHM_CBC_DEC,
CtrEnc = ctru_sys::PS_ALGORITHM_CTR_ENC,
CtrDec = ctru_sys::PS_ALGORITHM_CTR_DEC,
CcmEnc = ctru_sys::PS_ALGORITHM_CCM_ENC,
CcmDec = ctru_sys::PS_ALGORITHM_CCM_DEC,
}
#[repr(u32)]
pub enum AESKeyType {
Keyslot0D,
Keyslot2D,
Keyslot31,
Keyslot38,
Keyslot32,
Keyslot39Dlp,
Keyslot2E,
KeyslotInvalid,
Keyslot36,
Keyslot39Nfc,
Keyslot0D = ctru_sys::PS_KEYSLOT_0D,
Keyslot2D = ctru_sys::PS_KEYSLOT_2D,
Keyslot2E = ctru_sys::PS_KEYSLOT_2E,
Keyslot31 = ctru_sys::PS_KEYSLOT_31,
Keyslot32 = ctru_sys::PS_KEYSLOT_32,
Keyslot36 = ctru_sys::PS_KEYSLOT_36,
Keyslot38 = ctru_sys::PS_KEYSLOT_38,
Keyslot39Dlp = ctru_sys::PS_KEYSLOT_39_DLP,
Keyslot39Nfc = ctru_sys::PS_KEYSLOT_39_NFC,
KeyslotInvalid = ctru_sys::PS_KEYSLOT_INVALID,
}
pub struct Ps(());
@ -70,6 +70,9 @@ impl Drop for Ps { @@ -70,6 +70,9 @@ impl Drop for Ps {
}
}
from_impl!(AESAlgorithm, ctru_sys::PS_AESAlgorithm);
from_impl!(AESKeyType, ctru_sys::PS_AESKeyType);
#[cfg(test)]
mod tests {
use std::collections::HashMap;

2
ctru-rs/src/romfs.rs → ctru-rs/src/services/romfs.rs

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
//! Read-Only Memory FileSystem
//!
//! This module only gets compiled if the configured RomFS directory is found and the `romfs`
//! feature is enabled.
//!

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

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
//! Network Socket
use libc::memalign;
use std::net::Ipv4Addr;
use std::sync::Mutex;
@ -6,8 +8,10 @@ use crate::error::ResultCode; @@ -6,8 +8,10 @@ use crate::error::ResultCode;
use crate::services::ServiceReference;
use crate::Error;
/// Soc service. Initializing this service will enable the use of network sockets and utilities
/// such as those found in `std::net`. The service will be closed when this struct is is dropped.
/// Network socket service
///
/// Initializing this service will enable the use of network sockets and utilities
/// such as those found in `std::net`. The service will close once this struct gets dropped.
pub struct Soc {
_service_handler: ServiceReference,
sock_3dslink: libc::c_int,

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

@ -1,3 +1,5 @@ @@ -1,3 +1,5 @@
//! SSLC (TLS) service
// TODO: Implement remaining functions
use crate::error::ResultCode;
@ -5,7 +7,7 @@ use crate::error::ResultCode; @@ -5,7 +7,7 @@ use crate::error::ResultCode;
pub struct SslC(());
impl SslC {
/// Initialize sslc
/// Initialize the service
pub fn init() -> crate::Result<Self> {
unsafe {
ResultCode(ctru_sys::sslcInit(0))?;

7
ctru-rs/src/test_runner.rs

@ -6,10 +6,7 @@ use std::io; @@ -6,10 +6,7 @@ use std::io;
use test::{ColorConfig, OutputFormat, TestDescAndFn, TestFn, TestOpts};
use crate::console::Console;
use crate::gfx::Gfx;
use crate::services::hid::{Hid, KeyPad};
use crate::services::Apt;
use crate::prelude::*;
/// A custom runner to be used with `#[test_runner]`. This simple implementation
/// runs all tests in series, "failing" on the first one to panic (really, the
@ -47,7 +44,7 @@ pub(crate) fn run(tests: &[&TestDescAndFn]) { @@ -47,7 +44,7 @@ pub(crate) fn run(tests: &[&TestDescAndFn]) {
gfx.wait_for_vblank();
hid.scan_input();
if hid.keys_down().contains(KeyPad::KEY_START) {
if hid.keys_down().contains(KeyPad::START) {
break;
}
}

Loading…
Cancel
Save