Browse Source

Fixed nits and suggestions

pull/137/head
Andrea Ciliberti 1 year ago
parent
commit
079f3bdc3c
  1. 10
      ctru-rs/examples/camera-image.rs
  2. 18
      ctru-rs/examples/movement.rs
  3. 8
      ctru-rs/src/console.rs
  4. 23
      ctru-rs/src/lib.rs
  5. 2
      ctru-rs/src/services/cam.rs
  6. 4
      ctru-rs/src/services/gfx.rs
  7. 89
      ctru-rs/src/services/hid.rs
  8. 1
      ctru-rs/src/services/ndsp/mod.rs

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

@ -83,7 +83,7 @@ fn main() {
.take_picture(&mut buf, WAIT_TIMEOUT) .take_picture(&mut buf, WAIT_TIMEOUT)
.expect("Failed to take picture"); .expect("Failed to take picture");
let image_size = camera.final_view_size(); let (width, height) = camera.final_view_size();
// Play the normal shutter sound. // Play the normal shutter sound.
cam.play_shutter_sound(ShutterSound::Normal) cam.play_shutter_sound(ShutterSound::Normal)
@ -96,16 +96,16 @@ fn main() {
rotate_image_to_screen( rotate_image_to_screen(
&buf, &buf,
left_side.raw_framebuffer().ptr, left_side.raw_framebuffer().ptr,
image_size.0 as usize, width as usize,
image_size.1 as usize, height as usize,
); );
// Rotate the right image and correctly display it on the screen. // Rotate the right image and correctly display it on the screen.
rotate_image_to_screen( rotate_image_to_screen(
&buf[len / 2..], &buf[len / 2..],
right_side.raw_framebuffer().ptr, right_side.raw_framebuffer().ptr,
image_size.0 as usize, width as usize,
image_size.1 as usize, height as usize,
); );
} }

18
ctru-rs/examples/movement.rs

@ -19,8 +19,10 @@ fn main() {
// Activate the accelerometer and the gyroscope. // Activate the accelerometer and the gyroscope.
// Because of the complex nature of the movement sensors, they aren't activated by default with the `Hid` service. // Because of the complex nature of the movement sensors, they aren't activated by default with the `Hid` service.
// However, they can simply be turned on and off whenever necessary. // However, they can simply be turned on and off whenever necessary.
hid.set_accelerometer(true); hid.set_accelerometer(true)
hid.set_gyroscope(true); .expect("Couldn't activate accelerometer");
hid.set_gyroscope(true)
.expect("Couldn't activate gyroscope");
while apt.main_loop() { while apt.main_loop() {
// Scan all the controller inputs. // Scan all the controller inputs.
@ -34,13 +36,17 @@ fn main() {
// Be careful: reading without activating the sensors (as done before this loop) will result in a panic. // Be careful: reading without activating the sensors (as done before this loop) will result in a panic.
println!( println!(
"\x1b[3;0HAcceleration: {:?} ", "\x1b[3;0HAcceleration: {:?} ",
hid.accelerometer_vector() Into::<(i16, i16, i16)>::into(
.expect("could not retrieve acceleration vector") hid.accelerometer_vector()
.expect("could not retrieve acceleration vector")
)
); );
println!( println!(
"\x1b[4;0HGyroscope angular rate: {:?} ", "\x1b[4;0HGyroscope angular rate: {:?} ",
hid.gyroscope_rate() Into::<(i16, i16, i16)>::into(
.expect("could not retrieve angular rate") hid.gyroscope_rate()
.expect("could not retrieve angular rate")
)
); );
gfx.wait_for_vblank(); gfx.wait_for_vblank();

8
ctru-rs/src/console.rs

@ -209,7 +209,7 @@ impl<'screen> Console<'screen> {
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #
@ -264,7 +264,7 @@ impl<'screen> Console<'screen> {
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #
@ -288,14 +288,14 @@ impl<'screen> Console<'screen> {
pub fn reset_window(&mut self) { pub fn reset_window(&mut self) {
let width = self.max_width(); let width = self.max_width();
unsafe { consoleSetWindow(self.context.as_mut(), 0, 0, width.into(), 30) }; self.set_window(0, 0, width, 30).unwrap();
} }
/// Returns this [`Console`]'s maximum character width depending on the screen used. /// Returns this [`Console`]'s maximum character width depending on the screen used.
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #

23
ctru-rs/src/lib.rs

@ -76,7 +76,6 @@ pub fn use_panic_handler() {
/// When `test` is enabled, this function will be ignored. /// When `test` is enabled, this function will be ignored.
#[cfg(not(test))] #[cfg(not(test))]
fn panic_hook_setup() { fn panic_hook_setup() {
use crate::services::hid::KeyPad;
use std::panic::PanicInfo; use std::panic::PanicInfo;
let main_thread = std::thread::current().id(); let main_thread = std::thread::current().id();
@ -88,27 +87,9 @@ fn panic_hook_setup() {
// Only for panics in the main thread // Only for panics in the main thread
if main_thread == std::thread::current().id() && console::Console::exists() { if main_thread == std::thread::current().id() && console::Console::exists() {
println!("\nPress SELECT to exit the software"); println!("\nThe software will exit in 5 seconds");
// Due to how the Hid service operates, we can't safely use 2 handles to it at the same time. std::thread::sleep(std::time::Duration::from_secs(5));
// Furthermore, the panic hook runs before the panic cleanup is done, which means that any other handles
// to the service will still be alive during this process.
// Regardless, we can "unsafely" spin up a new instance, since the module won't be used any further from the main process,
// which is going to get cleaned up right after this loop.
unsafe {
let _ = ctru_sys::hidInit();
loop {
ctru_sys::hidScanInput();
let keys = ctru_sys::hidKeysDown();
if KeyPad::from_bits_truncate(keys).contains(KeyPad::SELECT) {
break;
}
}
ctru_sys::hidExit();
}
} }
}); });
std::panic::set_hook(new_hook); std::panic::set_hook(new_hook);

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

@ -633,7 +633,7 @@ pub trait Camera: private::ConfigurableCamera {
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #

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

@ -350,11 +350,11 @@ impl Gfx {
/// By initializing the [`Gfx`] service as such, all functionality that relies on CPU manipulation of the framebuffers will /// By initializing the [`Gfx`] service as such, all functionality that relies on CPU manipulation of the framebuffers will
/// be completely unavailable (usually resulting in an ARM panic if wrongly used). /// be completely unavailable (usually resulting in an ARM panic if wrongly used).
/// ///
/// Things such as [`Console`](crate::console::Console) and [`Screen::raw_framebuffer()`] will result in ARM exceptions. /// Usage of functionality such as [`Console`](crate::console::Console) and [`Screen::raw_framebuffer()`] will result in ARM exceptions.
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #

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

@ -81,6 +81,7 @@ bitflags! {
} }
/// Error enum for generic errors within the [`Hid`] service. /// Error enum for generic errors within the [`Hid`] service.
#[non_exhaustive]
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Error { pub enum Error {
/// An attempt was made to access the accelerometer while disabled. /// An attempt was made to access the accelerometer while disabled.
@ -89,6 +90,28 @@ pub enum Error {
UnavailableGyroscope, UnavailableGyroscope,
} }
/// Representation of the acceleration vector read by the accelerometer.
///
/// Have a look at [`Hid::enable_accelerometer()`] for more information.
#[allow(missing_docs)]
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
pub struct Acceleration {
x: i16,
y: i16,
z: i16,
}
/// Representation of the angular rate read by the gyroscope.
///
/// Have a look at [`Hid::enable_gyroscope())`] for more information.
#[allow(missing_docs)]
#[derive(Default, Copy, Clone, Debug, PartialEq, Eq)]
pub struct AngularRate {
roll: i16,
pitch: i16,
yaw: i16,
}
/// Handle to the HID service. /// Handle to the HID service.
pub struct Hid { pub struct Hid {
active_accelerometer: bool, active_accelerometer: bool,
@ -336,7 +359,7 @@ impl Hid {
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #
@ -365,7 +388,7 @@ impl Hid {
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #
@ -373,28 +396,30 @@ impl Hid {
/// let mut hid = Hid::new()?; /// let mut hid = Hid::new()?;
/// ///
/// // The accelerometer will start to register movements. /// // The accelerometer will start to register movements.
/// hid.set_accelerometer(true); /// hid.set_accelerometer(true).unwrap();
/// # /// #
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[doc(alias = "HIDUSER_EnableAccelerometer")] #[doc(alias = "HIDUSER_EnableAccelerometer")]
#[doc(alias = "HIDUSER_DisableAccelerometer")] #[doc(alias = "HIDUSER_DisableAccelerometer")]
pub fn set_accelerometer(&mut self, enabled: bool) { pub fn set_accelerometer(&mut self, enabled: bool) -> crate::Result<()> {
if enabled { if enabled {
let _ = unsafe { ctru_sys::HIDUSER_EnableAccelerometer() }; ResultCode(unsafe { ctru_sys::HIDUSER_EnableAccelerometer() })?;
} else { } else {
let _ = unsafe { ctru_sys::HIDUSER_DisableAccelerometer() }; ResultCode(unsafe { ctru_sys::HIDUSER_DisableAccelerometer() })?;
} }
self.active_accelerometer = enabled; self.active_accelerometer = enabled;
Ok(())
} }
/// Activate/deactivate the console's gyroscopic sensor. /// Activate/deactivate the console's gyroscopic sensor.
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #
@ -402,24 +427,26 @@ impl Hid {
/// let mut hid = Hid::new()?; /// let mut hid = Hid::new()?;
/// ///
/// // The gyroscope will start to register positions. /// // The gyroscope will start to register positions.
/// hid.set_gyroscope(true); /// hid.set_gyroscope(true).unwrap();
/// # /// #
/// # Ok(()) /// # Ok(())
/// # } /// # }
/// ``` /// ```
#[doc(alias = "HIDUSER_EnableGyroscope")] #[doc(alias = "HIDUSER_EnableGyroscope")]
#[doc(alias = "HIDUSER_DisableGyroscope")] #[doc(alias = "HIDUSER_DisableGyroscope")]
pub fn set_gyroscope(&mut self, enabled: bool) { pub fn set_gyroscope(&mut self, enabled: bool) -> crate::Result<()> {
if enabled { if enabled {
let _ = unsafe { ctru_sys::HIDUSER_EnableGyroscope() }; ResultCode(unsafe { ctru_sys::HIDUSER_EnableGyroscope() })?;
} else { } else {
let _ = unsafe { ctru_sys::HIDUSER_DisableGyroscope() }; ResultCode(unsafe { ctru_sys::HIDUSER_DisableGyroscope() })?;
} }
self.active_gyroscope = enabled; self.active_gyroscope = enabled;
Ok(())
} }
/// Returns the acceleration vector (x,y,z) registered by the accelerometer. /// Returns the acceleration vector (x, y, z) registered by the accelerometer.
/// ///
/// # Errors /// # Errors
/// ///
@ -428,7 +455,7 @@ impl Hid {
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #
@ -436,7 +463,7 @@ impl Hid {
/// let mut hid = Hid::new()?; /// let mut hid = Hid::new()?;
/// ///
/// // The accelerometer will start to register movements. /// // The accelerometer will start to register movements.
/// hid.set_accelerometer(true); /// hid.set_accelerometer(true).unwrap();
/// ///
/// // It's necessary to run `scan_input()` to update the accelerometer's readings. /// // It's necessary to run `scan_input()` to update the accelerometer's readings.
/// hid.scan_input(); /// hid.scan_input();
@ -448,7 +475,7 @@ impl Hid {
/// # } /// # }
/// ``` /// ```
#[doc(alias = "hidAccelRead")] #[doc(alias = "hidAccelRead")]
pub fn accelerometer_vector(&self) -> Result<(i16, i16, i16), Error> { pub fn accelerometer_vector(&self) -> Result<Acceleration, Error> {
if !self.active_accelerometer { if !self.active_accelerometer {
return Err(Error::UnavailableAccelerometer); return Err(Error::UnavailableAccelerometer);
} }
@ -459,10 +486,14 @@ impl Hid {
ctru_sys::hidAccelRead(&mut res); ctru_sys::hidAccelRead(&mut res);
} }
Ok((res.x, res.y, res.z)) Ok(Acceleration {
x: res.x,
y: res.y,
z: res.z,
})
} }
/// Returns the angular rate (roll,pitch,yaw) registered by the gyroscope. /// Returns the angular rate registered by the gyroscope.
/// ///
/// # Errors /// # Errors
/// ///
@ -471,7 +502,7 @@ impl Hid {
/// ///
/// # Example /// # Example
/// ///
/// ```no_run /// ```
/// # use std::error::Error; /// # use std::error::Error;
/// # fn main() -> Result<(), Box<dyn Error>> { /// # fn main() -> Result<(), Box<dyn Error>> {
/// # /// #
@ -479,7 +510,7 @@ impl Hid {
/// let mut hid = Hid::new()?; /// let mut hid = Hid::new()?;
/// ///
/// // The gyroscope will start to register positions. /// // The gyroscope will start to register positions.
/// hid.set_gyroscope(true); /// hid.set_gyroscope(true).unwrap();
/// ///
/// // It's necessary to run `scan_input()` to update the gyroscope's readings. /// // It's necessary to run `scan_input()` to update the gyroscope's readings.
/// hid.scan_input(); /// hid.scan_input();
@ -491,7 +522,7 @@ impl Hid {
/// # } /// # }
/// ``` /// ```
#[doc(alias = "hidGyroRead")] #[doc(alias = "hidGyroRead")]
pub fn gyroscope_rate(&self) -> Result<(i16, i16, i16), Error> { pub fn gyroscope_rate(&self) -> Result<AngularRate, Error> {
if !self.active_gyroscope { if !self.active_gyroscope {
return Err(Error::UnavailableGyroscope); return Err(Error::UnavailableGyroscope);
} }
@ -502,7 +533,23 @@ impl Hid {
ctru_sys::hidGyroRead(&mut res); ctru_sys::hidGyroRead(&mut res);
} }
Ok((res.x, res.y, res.z)) Ok(AngularRate {
roll: res.x,
pitch: res.y,
yaw: res.z,
})
}
}
impl From<Acceleration> for (i16, i16, i16) {
fn from(value: Acceleration) -> (i16, i16, i16) {
(value.x, value.y, value.z)
}
}
impl From<AngularRate> for (i16, i16, i16) {
fn from(value: AngularRate) -> (i16, i16, i16) {
(value.roll, value.pitch, value.yaw)
} }
} }

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

@ -85,6 +85,7 @@ pub enum InterpolationType {
} }
/// Errors returned by [`ndsp`](self) functions. /// Errors returned by [`ndsp`](self) functions.
#[non_exhaustive]
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub enum Error { pub enum Error {
/// Channel with the specified ID does not exist. /// Channel with the specified ID does not exist.

Loading…
Cancel
Save