Browse Source

Improve calling ``ctru_sys `` functions ergonomics

Now instead of handling the error number manually, you can use ``LibCtruError(ctru_sys::xxx())?`` for the cases where ``if r < 0`` executes ``Err(r.into())``

Most changes are migrations to the new system, relevant code changes are in ``src/error.rs``
pull/74/head
TechiePi 2 years ago
parent
commit
22183d8765
  1. 33
      ctru-rs/src/error.rs
  2. 1
      ctru-rs/src/lib.rs
  3. 7
      ctru-rs/src/romfs.rs
  4. 18
      ctru-rs/src/services/apt.rs
  5. 387
      ctru-rs/src/services/cam.rs
  6. 55
      ctru-rs/src/services/cfgu.rs
  7. 9
      ctru-rs/src/services/hid.rs
  8. 26
      ctru-rs/src/services/ps.rs
  9. 6
      ctru-rs/src/services/soc.rs
  10. 18
      ctru-rs/src/services/sslc.rs

33
ctru-rs/src/error.rs

@ -1,11 +1,38 @@ @@ -1,11 +1,38 @@
use std::error;
use std::ffi::CStr;
use std::fmt;
use std::ops::{ControlFlow, FromResidual, Try};
use ctru_sys::result::{R_DESCRIPTION, R_LEVEL, R_MODULE, R_SUMMARY};
pub type Result<T> = ::std::result::Result<T, Error>;
#[derive(Debug, Clone, PartialEq, PartialOrd)]
#[repr(transparent)]
pub(crate) struct LibCtruError(pub i32);
impl Try for LibCtruError {
type Output = ();
type Residual = crate::Result<core::convert::Infallible>;
fn from_output(_: Self::Output) -> Self {
Self(0)
}
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
match self.0 {
0 => ControlFlow::Continue(()),
_ => ControlFlow::Break(Err(self.into()))
}
}
}
impl FromResidual for LibCtruError {
fn from_residual(_: <Self as Try>::Residual) -> Self {
Self(1)
}
}
/// The error type returned by all libctru functions.
#[non_exhaustive]
pub enum Error {
@ -39,6 +66,12 @@ impl From<ctru_sys::Result> for Error { @@ -39,6 +66,12 @@ impl From<ctru_sys::Result> for Error {
}
}
impl From<LibCtruError> for Error {
fn from(err: LibCtruError) -> Self {
Self::Os(err.0)
}
}
impl fmt::Debug for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {

1
ctru-rs/src/lib.rs

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
#![crate_name = "ctru"]
#![feature(test)]
#![feature(custom_test_frameworks)]
#![feature(try_trait_v2)]
#![test_runner(test_runner::run)]
extern "C" fn services_deinit() {

7
ctru-rs/src/romfs.rs

@ -13,6 +13,7 @@ @@ -13,6 +13,7 @@
use once_cell::sync::Lazy;
use std::ffi::CStr;
use std::sync::Mutex;
use crate::error::LibCtruError;
use crate::services::ServiceReference;
@ -30,11 +31,7 @@ impl RomFS { @@ -30,11 +31,7 @@ impl RomFS {
true,
|| {
let mount_name = CStr::from_bytes_with_nul(b"romfs\0").unwrap();
let r = unsafe { ctru_sys::romfsMountSelf(mount_name.as_ptr()) };
if r < 0 {
return Err(r.into());
}
LibCtruError(unsafe { ctru_sys::romfsMountSelf(mount_name.as_ptr()) })?;
Ok(())
},
|| {

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

@ -1,14 +1,12 @@ @@ -1,14 +1,12 @@
use crate::error::LibCtruError;
pub struct Apt(());
impl Apt {
pub fn init() -> crate::Result<Apt> {
unsafe {
let r = ctru_sys::aptInit();
if r < 0 {
Err(r.into())
} else {
Ok(Apt(()))
}
LibCtruError(ctru_sys::aptInit())?;
Ok(Apt(()))
}
}
@ -18,12 +16,8 @@ impl Apt { @@ -18,12 +16,8 @@ impl Apt {
pub fn set_app_cpu_time_limit(&self, percent: u32) -> crate::Result<()> {
unsafe {
let r = ctru_sys::APT_SetAppCpuTimeLimit(percent);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::APT_SetAppCpuTimeLimit(percent))?;
Ok(())
}
}
}

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

@ -7,6 +7,7 @@ use crate::services::gspgpu::FramebufferFormat; @@ -7,6 +7,7 @@ use crate::services::gspgpu::FramebufferFormat;
use bitflags::bitflags;
use ctru_sys::Handle;
use std::time::Duration;
use crate::error::LibCtruError;
/// A reference-counted handle to the CAM service and the usable cameras.
/// The service is closed when all instances of this struct fall out of scope.
@ -267,24 +268,15 @@ impl BothOutwardCam { @@ -267,24 +268,15 @@ impl BothOutwardCam {
brightness_synchronization: bool,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetBrightnessSynchronization(brightness_synchronization);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetBrightnessSynchronization(brightness_synchronization))?;
Ok(())
}
}
fn synchronize_vsync_timing(&self) -> crate::Result<()> {
unsafe {
let r =
ctru_sys::CAMU_SynchronizeVsyncTiming(ctru_sys::SELECT_OUT1, ctru_sys::SELECT_OUT2);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SynchronizeVsyncTiming(ctru_sys::SELECT_OUT1, ctru_sys::SELECT_OUT2))?;
Ok(())
}
}
}
@ -313,12 +305,8 @@ pub trait Camera { @@ -313,12 +305,8 @@ pub trait Camera {
fn is_busy(&self) -> crate::Result<bool> {
unsafe {
let mut is_busy = false;
let r = ctru_sys::CAMU_IsBusy(&mut is_busy, self.port_as_raw());
if r < 0 {
Err(r.into())
} else {
Ok(is_busy)
}
LibCtruError(ctru_sys::CAMU_IsBusy(&mut is_busy, self.port_as_raw()))?;
Ok(is_busy)
}
}
@ -327,12 +315,8 @@ pub trait Camera { @@ -327,12 +315,8 @@ pub trait Camera {
fn get_transfer_bytes(&self) -> crate::Result<u32> {
unsafe {
let mut transfer_bytes = 0;
let r = ctru_sys::CAMU_GetTransferBytes(&mut transfer_bytes, self.port_as_raw());
if r < 0 {
Err(r.into())
} else {
Ok(transfer_bytes)
}
LibCtruError(ctru_sys::CAMU_GetTransferBytes(&mut transfer_bytes, self.port_as_raw()))?;
Ok(transfer_bytes)
}
}
@ -340,12 +324,8 @@ pub trait Camera { @@ -340,12 +324,8 @@ pub trait Camera {
/// [Camera::set_trimming_params]
fn set_trimming(&mut self, enabled: bool) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetTrimming(self.port_as_raw(), enabled);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetTrimming(self.port_as_raw(), enabled))?;
Ok(())
}
}
@ -353,30 +333,22 @@ pub trait Camera { @@ -353,30 +333,22 @@ pub trait Camera {
fn is_trimming_enabled(&self) -> crate::Result<bool> {
unsafe {
let mut trimming = false;
let r = ctru_sys::CAMU_IsTrimming(&mut trimming, self.port_as_raw());
if r < 0 {
Err(r.into())
} else {
Ok(trimming)
}
LibCtruError(ctru_sys::CAMU_IsTrimming(&mut trimming, self.port_as_raw()))?;
Ok(trimming)
}
}
/// Sets trimming parameters based on coordinates specified inside a [CamTrimmingParams]
fn set_trimming_params(&mut self, params: CamTrimmingParams) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetTrimmingParams(
LibCtruError(ctru_sys::CAMU_SetTrimmingParams(
self.port_as_raw(),
params.x_start,
params.y_start,
params.x_end,
params.y_end,
);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
))?;
Ok(())
}
}
@ -387,23 +359,20 @@ pub trait Camera { @@ -387,23 +359,20 @@ pub trait Camera {
let mut y_start = 0;
let mut x_end = 0;
let mut y_end = 0;
let r = ctru_sys::CAMU_GetTrimmingParams(
LibCtruError(ctru_sys::CAMU_GetTrimmingParams(
&mut x_start,
&mut y_start,
&mut x_end,
&mut y_end,
self.port_as_raw(),
);
if r < 0 {
Err(r.into())
} else {
Ok(CamTrimmingParams {
x_start,
y_start,
x_end,
y_end,
})
}
))?;
Ok(CamTrimmingParams {
x_start,
y_start,
x_end,
y_end,
})
}
}
@ -418,42 +387,30 @@ pub trait Camera { @@ -418,42 +387,30 @@ pub trait Camera {
cam_height: i16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetTrimmingParamsCenter(
LibCtruError(ctru_sys::CAMU_SetTrimmingParamsCenter(
self.port_as_raw(),
trim_width,
trim_height,
cam_width,
cam_height,
);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
))?;
Ok(())
}
}
/// Sets the exposure level of the camera
fn set_exposure(&mut self, exposure: i8) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetExposure(self.camera_as_raw(), exposure);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetExposure(self.camera_as_raw(), exposure))?;
Ok(())
}
}
/// 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<()> {
unsafe {
let r = ctru_sys::CAMU_SetWhiteBalance(self.camera_as_raw(), white_balance.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetWhiteBalance(self.camera_as_raw(), white_balance.bits()))?;
Ok(())
}
}
@ -464,39 +421,27 @@ pub trait Camera { @@ -464,39 +421,27 @@ pub trait Camera {
white_balance: CamWhiteBalance,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetWhiteBalanceWithoutBaseUp(
LibCtruError(ctru_sys::CAMU_SetWhiteBalanceWithoutBaseUp(
self.camera_as_raw(),
white_balance.bits(),
);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
))?;
Ok(())
}
}
/// Sets the sharpness of the camera
fn set_sharpness(&mut self, sharpness: i8) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetSharpness(self.camera_as_raw(), sharpness);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetSharpness(self.camera_as_raw(), sharpness))?;
Ok(())
}
}
/// Sets whether auto exposure is enabled or disabled for the camera
fn set_auto_exposure(&mut self, enabled: bool) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetAutoExposure(self.camera_as_raw(), enabled);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetAutoExposure(self.camera_as_raw(), enabled))?;
Ok(())
}
}
@ -504,24 +449,16 @@ pub trait Camera { @@ -504,24 +449,16 @@ pub trait Camera {
fn is_auto_exposure_enabled(&self) -> crate::Result<bool> {
unsafe {
let mut enabled = false;
let r = ctru_sys::CAMU_IsAutoExposure(&mut enabled, self.camera_as_raw());
if r < 0 {
Err(r.into())
} else {
Ok(enabled)
}
LibCtruError(ctru_sys::CAMU_IsAutoExposure(&mut enabled, self.camera_as_raw()))?;
Ok(enabled)
}
}
/// Sets whether auto white balance is enabled or disabled for the camera
fn set_auto_white_balance(&mut self, enabled: bool) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetAutoWhiteBalance(self.camera_as_raw(), enabled);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetAutoWhiteBalance(self.camera_as_raw(), enabled))?;
Ok(())
}
}
@ -529,25 +466,16 @@ pub trait Camera { @@ -529,25 +466,16 @@ pub trait Camera {
fn is_auto_white_balance_enabled(&self) -> crate::Result<bool> {
unsafe {
let mut enabled = false;
let r = ctru_sys::CAMU_IsAutoWhiteBalance(&mut enabled, self.camera_as_raw());
if r < 0 {
Err(r.into())
} else {
Ok(enabled)
}
LibCtruError(ctru_sys::CAMU_IsAutoWhiteBalance(&mut enabled, self.camera_as_raw()))?;
Ok(enabled)
}
}
/// Sets the flip direction of the camera's image based on the passed [CamFlip] argument
fn flip_image(&mut self, flip: CamFlip) -> crate::Result<()> {
unsafe {
let r =
ctru_sys::CAMU_FlipImage(self.camera_as_raw(), flip.bits(), ctru_sys::CONTEXT_A);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_FlipImage(self.camera_as_raw(), flip.bits(), ctru_sys::CONTEXT_A))?;
Ok(())
}
}
@ -571,7 +499,7 @@ pub trait Camera { @@ -571,7 +499,7 @@ pub trait Camera {
crop_1: (i16, i16),
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetDetailSize(
LibCtruError(ctru_sys::CAMU_SetDetailSize(
self.camera_as_raw(),
width,
height,
@ -580,48 +508,32 @@ pub trait Camera { @@ -580,48 +508,32 @@ pub trait Camera {
crop_1.0,
crop_1.1,
ctru_sys::CONTEXT_A,
);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
))?;
Ok(())
}
}
/// Sets the view size of the camera based on the passed [CamSize] argument.
fn set_view_size(&mut self, size: CamSize) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetSize(self.camera_as_raw(), size.bits(), ctru_sys::CONTEXT_A);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetSize(self.camera_as_raw(), size.bits(), 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<()> {
unsafe {
let r = ctru_sys::CAMU_SetFrameRate(self.camera_as_raw(), frame_rate.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetFrameRate(self.camera_as_raw(), frame_rate.bits()))?;
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<()> {
unsafe {
let r = ctru_sys::CAMU_SetPhotoMode(self.camera_as_raw(), photo_mode.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetPhotoMode(self.camera_as_raw(), photo_mode.bits()))?;
Ok(())
}
}
@ -630,53 +542,36 @@ pub trait Camera { @@ -630,53 +542,36 @@ pub trait Camera {
/// Multiple effects can be set at once by combining the bitflags of [CamEffect]
fn set_effect(&mut self, effect: CamEffect) -> crate::Result<()> {
unsafe {
let r =
ctru_sys::CAMU_SetEffect(self.camera_as_raw(), effect.bits(), ctru_sys::CONTEXT_A);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetEffect(self.camera_as_raw(), effect.bits(), 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<()> {
unsafe {
let r = ctru_sys::CAMU_SetContrast(self.camera_as_raw(), contrast.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetContrast(self.camera_as_raw(), contrast.bits()))?;
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<()> {
unsafe {
let r = ctru_sys::CAMU_SetLensCorrection(self.camera_as_raw(), lens_correction.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetLensCorrection(self.camera_as_raw(), lens_correction.bits()))?;
Ok(())
}
}
/// Sets the output format of the camera based on the passed [CamOutputFormat] argument.
fn set_output_format(&mut self, format: CamOutputFormat) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetOutputFormat(
LibCtruError(ctru_sys::CAMU_SetOutputFormat(
self.camera_as_raw(),
format.bits(),
ctru_sys::CONTEXT_A,
);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
))?;
Ok(())
}
}
@ -696,12 +591,8 @@ pub trait Camera { @@ -696,12 +591,8 @@ pub trait Camera {
height: i16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetAutoExposureWindow(self.camera_as_raw(), x, y, width, height);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetAutoExposureWindow(self.camera_as_raw(), x, y, width, height))?;
Ok(())
}
}
@ -721,25 +612,16 @@ pub trait Camera { @@ -721,25 +612,16 @@ pub trait Camera {
height: i16,
) -> crate::Result<()> {
unsafe {
let r =
ctru_sys::CAMU_SetAutoWhiteBalanceWindow(self.camera_as_raw(), x, y, width, height);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetAutoWhiteBalanceWindow(self.camera_as_raw(), x, y, width, height))?;
Ok(())
}
}
/// Sets whether the noise filter should be enabled or disabled for the camera
fn set_noise_filter(&mut self, enabled: bool) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetNoiseFilter(self.camera_as_raw(), enabled);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetNoiseFilter(self.camera_as_raw(), enabled))?;
Ok(())
}
}
@ -750,12 +632,8 @@ pub trait Camera { @@ -750,12 +632,8 @@ pub trait Camera {
data: ImageQualityCalibrationData,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetImageQualityCalibrationData(data.0);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetImageQualityCalibrationData(data.0))?;
Ok(())
}
}
@ -763,12 +641,8 @@ pub trait Camera { @@ -763,12 +641,8 @@ pub trait Camera {
fn get_image_quality_calibration_data(&self) -> crate::Result<ImageQualityCalibrationData> {
unsafe {
let mut data = ImageQualityCalibrationData::default();
let r = ctru_sys::CAMU_GetImageQualityCalibrationData(&mut data.0);
if r < 0 {
Err(r.into())
} else {
Ok(data)
}
LibCtruError(ctru_sys::CAMU_GetImageQualityCalibrationData(&mut data.0))?;
Ok(data)
}
}
@ -776,12 +650,8 @@ pub trait Camera { @@ -776,12 +650,8 @@ pub trait Camera {
// TODO: Explain sleep camera
fn set_sleep_camera(&mut self) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetSleepCamera(self.camera_as_raw());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_SetSleepCamera(self.camera_as_raw()))?;
Ok(())
}
}
@ -804,12 +674,8 @@ pub trait Camera { @@ -804,12 +674,8 @@ pub trait Camera {
) -> crate::Result<Vec<u8>> {
let transfer_unit = unsafe {
let mut buf_size = 0;
let r = ctru_sys::CAMU_GetMaxBytes(&mut buf_size, width as i16, height as i16);
if r < 0 {
Err(crate::Error::from(r))
} else {
Ok(buf_size)
}
LibCtruError(ctru_sys::CAMU_GetMaxBytes(&mut buf_size, width as i16, height as i16))?;
Ok::<u32, i32>(buf_size)
}?;
let screen_size = u32::from(width) * u32::from(width) * 2;
@ -817,83 +683,40 @@ pub trait Camera { @@ -817,83 +683,40 @@ pub trait Camera {
let mut buf = vec![0u8; usize::try_from(screen_size).unwrap()];
unsafe {
let r = ctru_sys::CAMU_SetTransferBytes(
LibCtruError(ctru_sys::CAMU_SetTransferBytes(
self.port_as_raw(),
transfer_unit,
width as i16,
height as i16,
);
if r < 0 {
return Err(r.into());
}
};
unsafe {
let r = ctru_sys::CAMU_Activate(self.camera_as_raw());
if r < 0 {
return Err(r.into());
}
))?;
};
unsafe {
let r = ctru_sys::CAMU_ClearBuffer(self.port_as_raw());
if r < 0 {
return Err(r.into());
}
};
unsafe {
let r = ctru_sys::CAMU_StartCapture(self.port_as_raw());
if r < 0 {
return Err(r.into());
}
LibCtruError(ctru_sys::CAMU_Activate(self.camera_as_raw()))?;
LibCtruError(ctru_sys::CAMU_ClearBuffer(self.port_as_raw()))?;
LibCtruError(ctru_sys::CAMU_StartCapture(self.port_as_raw()))?;
};
let receive_event = unsafe {
let mut completion_handle: Handle = 0;
let r = ctru_sys::CAMU_SetReceiving(
LibCtruError(ctru_sys::CAMU_SetReceiving(
&mut completion_handle,
buf.as_mut_ptr() as *mut ::libc::c_void,
self.port_as_raw(),
screen_size,
transfer_unit.try_into().unwrap(),
);
if r < 0 {
Err(crate::Error::from(r))
} else {
Ok(completion_handle)
}
))?;
Ok::<Handle, i32>(completion_handle)
}?;
unsafe {
let r = ctru_sys::svcWaitSynchronization(
LibCtruError(ctru_sys::svcWaitSynchronization(
receive_event,
timeout.as_nanos().try_into().unwrap(),
);
if r < 0 {
return Err(r.into());
}
};
unsafe {
let r = ctru_sys::CAMU_StopCapture(self.port_as_raw());
if r < 0 {
return Err(r.into());
}
};
unsafe {
let r = ctru_sys::svcCloseHandle(receive_event);
if r < 0 {
return Err(r.into());
}
};
unsafe {
let r = ctru_sys::CAMU_Activate(ctru_sys::SELECT_NONE);
if r < 0 {
return Err(r.into());
}
))?;
LibCtruError(ctru_sys::CAMU_StopCapture(self.port_as_raw()))?;
LibCtruError(ctru_sys::svcCloseHandle(receive_event))?;
LibCtruError(ctru_sys::CAMU_Activate(ctru_sys::SELECT_NONE))?;
};
Ok(buf)
@ -910,29 +733,21 @@ impl Cam { @@ -910,29 +733,21 @@ impl Cam {
/// rare in practice.
pub fn init() -> crate::Result<Cam> {
unsafe {
let r = ctru_sys::camInit();
if r < 0 {
Err(r.into())
} else {
Ok(Cam {
inner_cam: InwardCam,
outer_right_cam: OutwardRightCam,
outer_left_cam: OutwardLeftCam,
both_outer_cams: BothOutwardCam,
})
}
LibCtruError(ctru_sys::camInit())?;
Ok(Cam {
inner_cam: InwardCam,
outer_right_cam: OutwardRightCam,
outer_left_cam: OutwardLeftCam,
both_outer_cams: BothOutwardCam,
})
}
}
/// Plays the specified sound based on the [CamShutterSoundType] argument
pub fn play_shutter_sound(&self, sound: CamShutterSoundType) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_PlayShutterSound(sound.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::CAMU_PlayShutterSound(sound.bits()))?;
Ok(())
}
}
}

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

@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
//!
//! This module contains basic methods to retrieve and change configuration from the console.
use crate::error::LibCtruError;
#[derive(Copy, Clone, Debug)]
#[repr(u32)]
pub enum Region {
@ -60,77 +62,48 @@ impl Cfgu { @@ -60,77 +62,48 @@ impl Cfgu {
/// 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> {
unsafe {
let r = ctru_sys::cfguInit();
if r < 0 {
Err(r.into())
} else {
Ok(Cfgu(()))
}
}
LibCtruError(unsafe { ctru_sys::cfguInit() })?;
Ok(Cfgu(()))
}
/// Gets system region from secure info
pub fn get_region(&self) -> crate::Result<Region> {
let mut region: u8 = 0;
let r = unsafe { ctru_sys::CFGU_SecureInfoGetRegion(&mut region) };
if r < 0 {
Err(r.into())
} else {
// The system shouldn't give an invalid value
Ok(Region::try_from(region).unwrap())
}
LibCtruError(unsafe { ctru_sys::CFGU_SecureInfoGetRegion(&mut region) })?;
Ok(Region::try_from(region).unwrap())
}
/// Gets system's model
pub fn get_model(&self) -> crate::Result<SystemModel> {
let mut model: u8 = 0;
let r = unsafe { ctru_sys::CFGU_GetSystemModel(&mut model) };
if r < 0 {
Err(r.into())
} else {
// The system shouldn't give an invalid value
Ok(SystemModel::try_from(model).unwrap())
}
LibCtruError(unsafe { ctru_sys::CFGU_GetSystemModel(&mut model) })?;
Ok(SystemModel::try_from(model).unwrap())
}
/// Gets system's language
pub fn get_language(&self) -> crate::Result<Language> {
let mut language: u8 = 0;
let r = unsafe { ctru_sys::CFGU_GetSystemLanguage(&mut language) };
if r < 0 {
Err(r.into())
} else {
// The system shouldn't give an invalid value
Ok(Language::try_from(language).unwrap())
}
LibCtruError(unsafe { ctru_sys::CFGU_GetSystemLanguage(&mut language) })?;
Ok(Language::try_from(language).unwrap())
}
/// Checks if NFC is supported by the console
pub fn is_nfc_supported(&self) -> crate::Result<bool> {
let mut supported: bool = false;
let r = unsafe { ctru_sys::CFGU_IsNFCSupported(&mut supported) };
if r < 0 {
Err(r.into())
} else {
Ok(supported)
}
LibCtruError(unsafe { ctru_sys::CFGU_IsNFCSupported(&mut supported) })?;
Ok(supported)
}
/// Check if the console is from the 2DS family (2DS, New2DS, New2DSXL)
pub fn is_2ds_family(&self) -> crate::Result<bool> {
let mut is_2ds_family: u8 = 0;
let r = unsafe { ctru_sys::CFGU_GetModelNintendo2DS(&mut is_2ds_family) };
if r < 0 {
Err(r.into())
} else {
Ok(is_2ds_family == 0)
}
LibCtruError(unsafe { ctru_sys::CFGU_GetModelNintendo2DS(&mut is_2ds_family) })?;
Ok(is_2ds_family == 0)
}
}

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

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
//! and circle pad information. It also provides information from the sound volume slider,
//! the accelerometer, and the gyroscope.
use crate::error::LibCtruError;
bitflags::bitflags! {
/// A set of flags corresponding to the button and directional pad
/// inputs on the 3DS
@ -62,12 +63,8 @@ pub struct CirclePosition(ctru_sys::circlePosition); @@ -62,12 +63,8 @@ pub struct CirclePosition(ctru_sys::circlePosition);
impl Hid {
pub fn init() -> crate::Result<Hid> {
unsafe {
let r = ctru_sys::hidInit();
if r < 0 {
Err(r.into())
} else {
Ok(Hid(()))
}
LibCtruError(ctru_sys::hidInit())?;
Ok(Hid(()))
}
}

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

@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
//! As such, it is initialized by default in `ctru::init` instead of having a safety handler
//! See also <https://www.3dbrew.org/wiki/Process_Services>
use crate::error::LibCtruError;
#[repr(u32)]
pub enum AESAlgorithm {
CbcEnc,
@ -31,32 +33,20 @@ pub enum AESKeyType { @@ -31,32 +33,20 @@ pub enum AESKeyType {
pub fn local_friend_code_seed() -> crate::Result<u64> {
let mut seed: u64 = 0;
let r = unsafe { ctru_sys::PS_GetLocalFriendCodeSeed(&mut seed) };
if r < 0 {
Err(r.into())
} else {
Ok(seed)
}
LibCtruError(unsafe { ctru_sys::PS_GetLocalFriendCodeSeed(&mut seed) })?;
Ok(seed)
}
pub fn device_id() -> crate::Result<u32> {
let mut id: u32 = 0;
let r = unsafe { ctru_sys::PS_GetDeviceId(&mut id) };
if r < 0 {
Err(r.into())
} else {
Ok(id)
}
LibCtruError(unsafe { ctru_sys::PS_GetDeviceId(&mut id) })?;
Ok(id)
}
pub fn generate_random_bytes(out: &mut [u8]) -> crate::Result<()> {
let r = unsafe { ctru_sys::PS_GenerateRandomBytes(out as *mut _ as *mut _, out.len() as u32) };
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(unsafe { ctru_sys::PS_GenerateRandomBytes(out as *mut _ as *mut _, out.len() as u32) })?;
Ok(())
}
#[cfg(test)]

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

@ -5,6 +5,7 @@ use std::sync::Mutex; @@ -5,6 +5,7 @@ use std::sync::Mutex;
use crate::services::ServiceReference;
use crate::Error;
use crate::error::LibCtruError;
/// 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.
@ -38,10 +39,7 @@ impl Soc { @@ -38,10 +39,7 @@ impl Soc {
false,
|| {
let soc_mem = unsafe { memalign(0x1000, num_bytes) } as *mut u32;
let r = unsafe { ctru_sys::socInit(soc_mem, num_bytes as u32) };
if r < 0 {
return Err(r.into());
}
LibCtruError(unsafe { ctru_sys::socInit(soc_mem, num_bytes as u32) })?;
Ok(())
},

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

@ -1,29 +1,23 @@ @@ -1,29 +1,23 @@
// TODO: Implement remaining functions
use crate::error::LibCtruError;
pub struct SslC(());
impl SslC {
/// Initialize sslc
pub fn init() -> crate::Result<Self> {
unsafe {
let r = ctru_sys::sslcInit(0);
if r < 0 {
Err(r.into())
} else {
Ok(SslC(()))
}
LibCtruError(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 {
let r = ctru_sys::sslcGenerateRandomData(buf.as_ptr() as _, buf.len() as u32);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
LibCtruError(ctru_sys::sslcGenerateRandomData(buf.as_ptr() as _, buf.len() as u32))?;
Ok(())
}
}
}

Loading…
Cancel
Save