@ -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,27 +268,18 @@ impl BothOutwardCam {
@@ -267,27 +268,18 @@ impl BothOutwardCam {
brightness_synchronization : bool ,
) -> crate ::Result < ( ) > {
unsafe {
let r = ctru_sys ::CAMU_SetBrightnessSynchronization ( brightness_synchronization ) ;
if r < 0 {
Err ( r . into ( ) )
} else {
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 {
LibCtruError ( ctru_sys ::CAMU_SynchronizeVsyncTiming ( ctru_sys ::SELECT_OUT1 , ctru_sys ::SELECT_OUT2 ) ) ? ;
Ok ( ( ) )
}
}
}
}
impl Camera for BothOutwardCam {
fn camera_as_raw ( & self ) -> ctru_sys ::u32_ {
@ -313,72 +305,52 @@ pub trait Camera {
@@ -313,72 +305,52 @@ 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 {
LibCtruError ( ctru_sys ::CAMU_IsBusy ( & mut is_busy , self . port_as_raw ( ) ) ) ? ;
Ok ( is_busy )
}
}
}
/// 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 > {
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 {
LibCtruError ( ctru_sys ::CAMU_GetTransferBytes ( & mut transfer_bytes , self . port_as_raw ( ) ) ) ? ;
Ok ( transfer_bytes )
}
}
}
/// Sets whether or not the camera should trim the image based on parameters set by
/// [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 {
LibCtruError ( ctru_sys ::CAMU_SetTrimming ( self . port_as_raw ( ) , enabled ) ) ? ;
Ok ( ( ) )
}
}
}
/// Returns whether or not trimming is currently enabled for the 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 {
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 ( ( ) )
}
}
}
/// Returns the set [CamTrimmingParams] from the camera
fn get_trimming_params ( & self ) -> crate ::Result < CamTrimmingParams > {
@ -387,16 +359,14 @@ pub trait Camera {
@@ -387,16 +359,14 @@ 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 ,
@ -405,7 +375,6 @@ pub trait Camera {
@@ -405,7 +375,6 @@ pub trait Camera {
} )
}
}
}
/// Sets the trimming parameters revolving around the center of the image.
/// The new width will be `trim_width / 2` to the left and right of the center.
@ -418,44 +387,32 @@ pub trait Camera {
@@ -418,44 +387,32 @@ 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 ( ( ) )
}
}
}
/// 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 {
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 {
LibCtruError ( ctru_sys ::CAMU_SetWhiteBalance ( self . camera_as_raw ( ) , white_balance . bits ( ) ) ) ? ;
Ok ( ( ) )
}
}
}
/// Sets the white balance mode of the camera based on the passed [CamWhiteBalance] argument
// TODO: Explain base up
@ -464,92 +421,63 @@ pub trait Camera {
@@ -464,92 +421,63 @@ 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 ( ( ) )
}
}
}
/// 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 {
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 {
LibCtruError ( ctru_sys ::CAMU_SetAutoExposure ( self . camera_as_raw ( ) , enabled ) ) ? ;
Ok ( ( ) )
}
}
}
/// Returns true if auto exposure is enabled for the 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 {
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 {
LibCtruError ( ctru_sys ::CAMU_SetAutoWhiteBalance ( self . camera_as_raw ( ) , enabled ) ) ? ;
Ok ( ( ) )
}
}
}
/// Returns true if auto white balance is enabled for the 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 {
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 {
LibCtruError ( ctru_sys ::CAMU_FlipImage ( self . camera_as_raw ( ) , flip . bits ( ) , ctru_sys ::CONTEXT_A ) ) ? ;
Ok ( ( ) )
}
}
}
/// Sets the image resolution of the camera in detail
///
@ -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,105 +508,72 @@ pub trait Camera {
@@ -580,105 +508,72 @@ pub trait Camera {
crop_1 . 0 ,
crop_1 . 1 ,
ctru_sys ::CONTEXT_A ,
) ;
if r < 0 {
Err ( r . into ( ) )
} else {
) ) ? ;
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 {
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 {
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 {
LibCtruError ( ctru_sys ::CAMU_SetPhotoMode ( self . camera_as_raw ( ) , photo_mode . bits ( ) ) ) ? ;
Ok ( ( ) )
}
}
}
/// Sets the effect of the camera based on the passed [CamEffect] argument.
///
/// 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 {
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 {
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 {
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 ( ( ) )
}
}
}
/// Sets the region in which auto exposure should be based on.
///
@ -696,14 +591,10 @@ pub trait Camera {
@@ -696,14 +591,10 @@ 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 {
LibCtruError ( ctru_sys ::CAMU_SetAutoExposureWindow ( self . camera_as_raw ( ) , x , y , width , height ) ) ? ;
Ok ( ( ) )
}
}
}
/// Sets the region in which auto white balance should be based on.
///
@ -721,27 +612,18 @@ pub trait Camera {
@@ -721,27 +612,18 @@ 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 {
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 {
LibCtruError ( ctru_sys ::CAMU_SetNoiseFilter ( self . camera_as_raw ( ) , enabled ) ) ? ;
Ok ( ( ) )
}
}
}
/// Sets the image quality calibration data for the camera based on the passed in
/// [ImageQualityCalibrationData] argument
@ -750,40 +632,28 @@ pub trait Camera {
@@ -750,40 +632,28 @@ pub trait Camera {
data : ImageQualityCalibrationData ,
) -> crate ::Result < ( ) > {
unsafe {
let r = ctru_sys ::CAMU_SetImageQualityCalibrationData ( data . 0 ) ;
if r < 0 {
Err ( r . into ( ) )
} else {
LibCtruError ( ctru_sys ::CAMU_SetImageQualityCalibrationData ( data . 0 ) ) ? ;
Ok ( ( ) )
}
}
}
/// Returns the current [ImageQualityCalibrationData] for the 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 {
LibCtruError ( ctru_sys ::CAMU_GetImageQualityCalibrationData ( & mut data . 0 ) ) ? ;
Ok ( data )
}
}
}
/// Sets the camera as the current sleep 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 {
LibCtruError ( ctru_sys ::CAMU_SetSleepCamera ( self . camera_as_raw ( ) ) ) ? ;
Ok ( ( ) )
}
}
}
/// Requests the camera to take a picture and returns a vector containing the image bytes.
///
@ -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! [ 0 u8 ; 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,10 +733,7 @@ impl Cam {
@@ -910,10 +733,7 @@ impl Cam {
/// rare in practice.
pub fn init ( ) -> crate ::Result < Cam > {
unsafe {
let r = ctru_sys ::camInit ( ) ;
if r < 0 {
Err ( r . into ( ) )
} else {
LibCtruError ( ctru_sys ::camInit ( ) ) ? ;
Ok ( Cam {
inner_cam : InwardCam ,
outer_right_cam : OutwardRightCam ,
@ -922,20 +742,15 @@ impl Cam {
@@ -922,20 +742,15 @@ impl Cam {
} )
}
}
}
/// 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 {
LibCtruError ( ctru_sys ::CAMU_PlayShutterSound ( sound . bits ( ) ) ) ? ;
Ok ( ( ) )
}
}
}
}
impl Drop for Cam {
fn drop ( & mut self ) {