Browse Source

All non-struct functions

pull/65/head
Steve Cook 2 years ago
parent
commit
c7b6470382
  1. 3
      .gitignore
  2. 12
      ctru-rs/examples/camera-image.rs
  3. 2
      ctru-rs/examples/network-sockets.rs
  4. 746
      ctru-rs/src/services/cam.rs
  5. 9
      ctru-rs/src/services/reference.rs
  6. 184
      example.rsf

3
.gitignore vendored

@ -4,3 +4,6 @@ Cargo.lock
# IDE files # IDE files
.idea .idea
# 3ds files
*.cia

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

@ -87,14 +87,14 @@ fn main() {
gfx.swap_buffers(); gfx.swap_buffers();
gfx.wait_for_vblank(); gfx.wait_for_vblank();
held_r = true; held_r = true;
take_picture(&mut cam, buf.as_mut_ptr()); take_picture(&mut cam, &mut buf);
} else if !key_held.contains(KeyPad::KEY_R) { } else if !key_held.contains(KeyPad::KEY_R) {
held_r = false; held_r = false;
} }
write_picture_to_frame_buffer_rgb_565( write_picture_to_frame_buffer_rgb_565(
gfx.top_screen.borrow_mut().get_raw_framebuffer(Side::Left), gfx.top_screen.borrow_mut().get_raw_framebuffer(Side::Left),
buf.as_mut_ptr(), &mut buf,
0, 0,
0, 0,
WIDTH as u16, WIDTH as u16,
@ -107,7 +107,7 @@ fn main() {
} }
} }
fn take_picture(cam: &mut Cam, buf: *mut u8) { fn take_picture(cam: &mut Cam, buf: &mut [u8]) {
let mut buf_size = 0; let mut buf_size = 0;
cam.get_max_bytes(&mut buf_size, WIDTH as i16, HEIGHT as i16) cam.get_max_bytes(&mut buf_size, WIDTH as i16, HEIGHT as i16)
.expect("Failed to get max bytes"); .expect("Failed to get max bytes");
@ -138,7 +138,7 @@ fn take_picture(cam: &mut Cam, buf: *mut u8) {
.expect("Failed to set receiving"); .expect("Failed to set receiving");
cam.set_receiving( cam.set_receiving(
&mut receive_event2, &mut receive_event2,
unsafe { buf.add(SCREEN_SIZE) }, &mut buf[SCREEN_SIZE..],
CamPort::PORT_CAM2, CamPort::PORT_CAM2,
SCREEN_SIZE as u32, SCREEN_SIZE as u32,
buf_size as i16, buf_size as i16,
@ -175,14 +175,14 @@ fn take_picture(cam: &mut Cam, buf: *mut u8) {
fn write_picture_to_frame_buffer_rgb_565( fn write_picture_to_frame_buffer_rgb_565(
fb: RawFrameBuffer, fb: RawFrameBuffer,
img: *mut u8, img: &mut [u8],
x: u16, x: u16,
y: u16, y: u16,
width: u16, width: u16,
height: u16, height: u16,
) { ) {
let fb_8 = fb.ptr; let fb_8 = fb.ptr;
let img_16 = img as *mut u16; let img_16 = img.as_mut_ptr() as *mut u16;
let mut draw_x; let mut draw_x;
let mut draw_y; let mut draw_y;
for j in 0..height { for j in 0..height {

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

@ -43,7 +43,7 @@ fn main() {
} else { } else {
println!("Unable to read stream: {}", e) println!("Unable to read stream: {}", e)
} }
}, }
} }
let response = b"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n<html><body>Hello world</body></html>\r\n"; let response = b"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n<html><body>Hello world</body></html>\r\n";

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

@ -26,6 +26,26 @@ bitflags! {
} }
} }
bitflags! {
#[derive(Default)]
pub struct CamContext: u32 {
const CONTEXT_NONE = 0;
const CONTEXT_A = 1;
const CONTEXT_B = 2;
const CONTEXT_BOTH = Self::CONTEXT_A.bits | Self::CONTEXT_B.bits;
}
}
bitflags! {
#[derive(Default)]
pub struct CamFlip: u32 {
const FLIP_NONE = 0;
const FLIP_HORIZONTAL = 1;
const FLIP_VERTICAL = 2;
const FLIP_REVERSE = 3;
}
}
bitflags! { bitflags! {
#[derive(Default)] #[derive(Default)]
pub struct CamSize: u32 { pub struct CamSize: u32 {
@ -43,11 +63,97 @@ bitflags! {
bitflags! { bitflags! {
#[derive(Default)] #[derive(Default)]
pub struct CamContext: u32 { pub struct CamFrameRate: u32 {
const CONTEXT_NONE = 0; const FRAME_RATE_15 = 0;
const CONTEXT_A = 1; const FRAME_RATE_15_TO_5 = 1;
const CONTEXT_B = 2; const FRAME_RATE_15_TO_2 = 2;
const CONTEXT_BOTH = Self::CONTEXT_A.bits | Self::CONTEXT_B.bits; const FRAME_RATE_10 = 3;
const FRAME_RATE_8_5 = 4;
const FRAME_RATE_5 = 5;
const FRAME_RATE_20 = 6;
const FRAME_RATE_20_TO_5 = 7;
const FRAME_RATE_30 = 8;
const FRAME_RATE_30_TO_5 = 9;
const FRAME_RATE_15_TO_10 = 10;
const FRAME_RATE_20_TO_10 = 11;
const FRAME_RATE_30_TO_10 = 12;
}
}
bitflags! {
#[derive(Default)]
pub struct CamWhiteBalance: u32 {
const WHITE_BALANCE_AUTO = 0;
const WHITE_BALANCE_3200K = 1;
const WHITE_BALANCE_4150K = 2;
const WHITE_BALANCE_5200K = 3;
const WHITE_BALANCE_6000K = 4;
const WHITE_BALANCE_7000K = 5;
const WHITE_BALANCE_NORMAL = Self::WHITE_BALANCE_AUTO.bits;
const WHITE_BALANCE_TUNGSTEN = Self::WHITE_BALANCE_3200K.bits;
const WHITE_BALANCE_WHITE_FLUORESCENT_LIGHT = Self::WHITE_BALANCE_4150K.bits;
const WHITE_BALANCE_DAYLIGHT = Self::WHITE_BALANCE_5200K.bits;
const WHITE_BALANCE_CLOUDY = Self::WHITE_BALANCE_6000K.bits;
const WHITE_BALANCE_HORIZON = Self::WHITE_BALANCE_6000K.bits;
const WHITE_BALANCE_SHADE = Self::WHITE_BALANCE_7000K.bits;
}
}
bitflags! {
#[derive(Default)]
pub struct CamPhotoMode: u32 {
const PHOTO_MODE_NORMAL = 0;
const PHOTO_MODE_PORTRAIT = 1;
const PHOTO_MODE_LANDSCAPE = 2;
const PHOTO_MODE_NIGHTVIEW = 3;
const PHOTO_MODE_LETTER = 4;
}
}
bitflags! {
#[derive(Default)]
pub struct CamEffect: u32 {
const EFFECT_NONE = 0;
const EFFECT_MONO = 1;
const EFFECT_SEPIA = 2;
const EFFECT_NEGATIVE = 3;
const EFFECT_NEGAFILM = 4;
const EFFECT_SEPIA01 = 5;
}
}
bitflags! {
#[derive(Default)]
pub struct CamContrast: u32 {
const CONTRAST_PATTERN_01 = 0;
const CONTRAST_PATTERN_02 = 1;
const CONTRAST_PATTERN_03 = 2;
const CONTRAST_PATTERN_04 = 3;
const CONTRAST_PATTERN_05 = 4;
const CONTRAST_PATTERN_06 = 5;
const CONTRAST_PATTERN_07 = 6;
const CONTRAST_PATTERN_08 = 7;
const CONTRAST_PATTERN_09 = 8;
const CONTRAST_PATTERN_10 = 9;
const CONTRAST_PATTERN_11 = 10;
const CONTRAST_LOW = Self::CONTRAST_PATTERN_05.bits;
const CONTRAST_NORMAL = Self::CONTRAST_PATTERN_06.bits;
const CONTRAST_HIGH = Self::CONTRAST_PATTERN_07.bits;
}
}
bitflags! {
#[derive(Default)]
pub struct CamLensCorrection: u32 {
const LENS_CORRECTION_OFF = 0;
const LENS_CORRECTION_ON_70 = 1;
const LENS_CORRECTION_ON_90 = 2;
const LENS_CORRECTION_DARK = Self::LENS_CORRECTION_OFF.bits;
const LENS_CORRECTION_NORMAL = Self::LENS_CORRECTION_ON_70.bits;
const LENS_CORRECTION_BRIGHT = Self::LENS_CORRECTION_ON_90.bits;
} }
} }
@ -80,14 +186,304 @@ impl Cam {
} }
} }
pub fn set_size( pub fn start_capture(&self, port: CamPort) -> crate::Result<()> {
&mut self, unsafe {
let r = ctru_sys::CAMU_StartCapture(port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn stop_capture(&self, port: CamPort) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_StopCapture(port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn is_busy(&self, bool: &mut bool, port: CamPort) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_IsBusy(bool, port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn clear_buffer(&self, port: CamPort) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_ClearBuffer(port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn get_vsync_interrupt_event(&self, event: &mut u32, port: CamPort) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_GetVsyncInterruptEvent(event, port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn get_buffer_error_interrupt_event(
&self,
event: &mut u32,
port: CamPort,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_GetBufferErrorInterruptEvent(event, port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_receiving(
&self,
handle: &mut u32,
buf: &mut [u8],
port: CamPort,
size: u32,
buf_size: i16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetReceiving(
handle,
buf.as_mut_ptr() as *mut ::libc::c_void,
port.bits(),
size,
buf_size,
);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn is_finished_receiving(
&self,
finished_receiving: &mut bool,
port: CamPort,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_IsFinishedReceiving(finished_receiving, port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_transfer_lines(
&self,
port: CamPort,
lines: i16,
width: i16,
height: i16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetTransferLines(port.bits(), lines, width, height);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn get_max_lines(&self, max_lines: &mut i16, width: i16, height: i16) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_GetMaxLines(max_lines, width, height);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_transfer_bytes(
&self,
port: CamPort,
buf_size: u32,
width: i16,
height: i16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetTransferBytes(port.bits(), buf_size, width, height);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn get_transfer_bytes(&self, transfer_bytes: &mut u32, port: CamPort) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_GetTransferBytes(transfer_bytes, port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn get_max_bytes(&self, buf_size: &mut u32, width: i16, height: i16) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_GetMaxBytes(buf_size, width, height);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_trimming(&self, port: CamPort, enabled: bool) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetTrimming(port.bits(), enabled);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn is_trimming(&self, trimming: &mut bool, port: CamPort) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_IsTrimming(trimming, port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_trimming_params(
&self,
port: CamPort,
x_start: i16,
y_start: i16,
x_end: i16,
y_end: i16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetTrimmingParams(port.bits(), x_start, y_start, x_end, y_end);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn get_trimming_params(
&self,
x_start: &mut i16,
y_start: &mut i16,
x_end: &mut i16,
y_end: &mut i16,
port: CamPort,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_GetTrimmingParams(x_start, y_start, x_end, y_end, port.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_trimming_params_center(
&self,
port: CamPort,
trim_width: i16,
trim_height: i16,
cam_width: i16,
cam_height: i16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetTrimmingParamsCenter(
port.bits(),
trim_width,
trim_height,
cam_width,
cam_height,
);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn activate(&self, camera: CamSelect) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_Activate(camera.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn switch_context(&self, camera: CamSelect, context: CamContext) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SwitchContext(camera.bits(), context.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_exposure(&self, camera: CamSelect, exposure: i8) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetExposure(camera.bits(), exposure);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_white_balance(
&self,
camera: CamSelect, camera: CamSelect,
size: CamSize, white_balance: CamWhiteBalance,
context: CamContext,
) -> crate::Result<()> { ) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_SetSize(camera.bits(), size.bits(), context.bits()); let r = ctru_sys::CAMU_SetWhiteBalance(camera.bits(), white_balance.bits());
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -96,14 +492,14 @@ impl Cam {
} }
} }
pub fn set_output_format( pub fn set_white_balance_without_base_up(
&mut self, &self,
camera: CamSelect, camera: CamSelect,
format: CamOutputFormat, white_balance: CamWhiteBalance,
context: CamContext,
) -> crate::Result<()> { ) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_SetOutputFormat(camera.bits(), format.bits(), context.bits()); let r =
ctru_sys::CAMU_SetWhiteBalanceWithoutBaseUp(camera.bits(), white_balance.bits());
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -112,9 +508,9 @@ impl Cam {
} }
} }
pub fn set_noise_filter(&mut self, camera: CamSelect, enabled: bool) -> crate::Result<()> { pub fn set_sharpness(&self, camera: CamSelect, sharpness: i8) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_SetNoiseFilter(camera.bits(), enabled); let r = ctru_sys::CAMU_SetSharpness(camera.bits(), sharpness);
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -123,7 +519,7 @@ impl Cam {
} }
} }
pub fn set_auto_exposure(&mut self, camera: CamSelect, enabled: bool) -> crate::Result<()> { pub fn set_auto_exposure(&self, camera: CamSelect, enabled: bool) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_SetAutoExposure(camera.bits(), enabled); let r = ctru_sys::CAMU_SetAutoExposure(camera.bits(), enabled);
if r < 0 { if r < 0 {
@ -134,11 +530,22 @@ impl Cam {
} }
} }
pub fn set_auto_white_balance( pub fn is_auto_exposure(
&mut self, &self,
is_auto_exposure: &mut bool,
camera: CamSelect, camera: CamSelect,
enabled: bool,
) -> crate::Result<()> { ) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_IsAutoExposure(is_auto_exposure, camera.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_auto_white_balance(&self, camera: CamSelect, enabled: bool) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_SetAutoWhiteBalance(camera.bits(), enabled); let r = ctru_sys::CAMU_SetAutoWhiteBalance(camera.bits(), enabled);
if r < 0 { if r < 0 {
@ -149,9 +556,13 @@ impl Cam {
} }
} }
pub fn set_trimming(&mut self, port: CamPort, enabled: bool) -> crate::Result<()> { pub fn is_auto_white_balance(
&self,
is_auto_white_balance: &mut bool,
camera: CamSelect,
) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_SetTrimming(port.bits(), enabled); let r = ctru_sys::CAMU_IsAutoWhiteBalance(is_auto_white_balance, camera.bits());
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -160,9 +571,14 @@ impl Cam {
} }
} }
pub fn get_max_bytes(&self, buf_size: &mut u32, width: i16, height: i16) -> crate::Result<()> { pub fn flip_image(
&self,
camera: CamSelect,
flip: CamFlip,
context: CamContext,
) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_GetMaxBytes(buf_size, width, height); let r = ctru_sys::CAMU_FlipImage(camera.bits(), flip.bits(), context.bits());
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -171,15 +587,28 @@ impl Cam {
} }
} }
pub fn set_transfer_bytes( pub fn set_detail_size(
&mut self, &self,
port: CamPort, camera: CamSelect,
buf_size: u32,
width: i16, width: i16,
height: i16, height: i16,
crop_x0: i16,
crop_y0: i16,
crop_x1: i16,
crop_y1: i16,
context: CamContext,
) -> crate::Result<()> { ) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_SetTransferBytes(port.bits(), buf_size, width, height); let r = ctru_sys::CAMU_SetDetailSize(
camera.bits(),
width,
height,
crop_x0,
crop_y0,
crop_x1,
crop_y1,
context.bits(),
);
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -188,9 +617,141 @@ impl Cam {
} }
} }
pub fn clear_buffer(&mut self, port: CamPort) -> crate::Result<()> { pub fn set_size(
&self,
camera: CamSelect,
size: CamSize,
context: CamContext,
) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_ClearBuffer(port.bits()); let r = ctru_sys::CAMU_SetSize(camera.bits(), size.bits(), context.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_frame_rate(&self, camera: CamSelect, frame_rate: CamFrameRate) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetFrameRate(camera.bits(), frame_rate.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_photo_mode(&self, camera: CamSelect, photo_mode: CamPhotoMode) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetPhotoMode(camera.bits(), photo_mode.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_effect(
&self,
camera: CamSelect,
effect: CamEffect,
context: CamContext,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetEffect(camera.bits(), effect.bits(), context.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_contrast(&self, camera: CamSelect, contrast: CamContrast) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetContrast(camera.bits(), contrast.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_lens_correction(
&self,
camera: CamSelect,
lens_correction: CamLensCorrection,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetLensCorrection(camera.bits(), lens_correction.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_output_format(
&self,
camera: CamSelect,
format: CamOutputFormat,
context: CamContext,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetOutputFormat(camera.bits(), format.bits(), context.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_auto_exposure_window(
&self,
camera: CamSelect,
x: i16,
y: i16,
width: i16,
height: i16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetAutoExposureWindow(camera.bits(), x, y, width, height);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_auto_white_balance_window(
&self,
camera: CamSelect,
x: i16,
y: i16,
width: i16,
height: i16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetAutoWhiteBalanceWindow(camera.bits(), x, y, width, height);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_noise_filter(&self, camera: CamSelect, enabled: bool) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetNoiseFilter(camera.bits(), enabled);
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -200,7 +761,7 @@ impl Cam {
} }
pub fn synchronize_vsync_timing( pub fn synchronize_vsync_timing(
&mut self, &self,
camera1: CamSelect, camera1: CamSelect,
camera2: CamSelect, camera2: CamSelect,
) -> crate::Result<()> { ) -> crate::Result<()> {
@ -214,16 +775,73 @@ impl Cam {
} }
} }
pub fn set_receiving( pub fn get_latest_vsync_timing(
&mut self, &self,
handle: &mut u32, timing: &mut i64,
buf: *mut u8,
port: CamPort, port: CamPort,
size: u32, past: u32,
buf_size: i16,
) -> crate::Result<()> { ) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_SetReceiving(handle, buf as *mut ::libc::c_void, port.bits(), size, buf_size); let r = ctru_sys::CAMU_GetLatestVsyncTiming(timing, port.bits(), past);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn write_register_i2c(&self, camera: CamSelect, addr: u16, data: u16) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_WriteRegisterI2c(camera.bits(), addr, data);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn write_mcu_variable_i2c(
&self,
camera: CamSelect,
addr: u16,
data: u16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_WriteMcuVariableI2c(camera.bits(), addr, data);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn read_register_i2c_exclusive(
&self,
data: &mut u16,
camera: CamSelect,
addr: u16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_ReadRegisterI2cExclusive(data, camera.bits(), addr);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn read_mcu_variable_i2c_exclusive(
&self,
data: &mut u16,
camera: CamSelect,
addr: u16,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_ReadMcuVariableI2cExclusive(data, camera.bits(), addr);
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -243,9 +861,9 @@ impl Cam {
} }
} }
pub fn start_capture(&self, port: CamPort) -> crate::Result<()> { pub fn driver_initialize(&self) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_StartCapture(port.bits()); let r = ctru_sys::CAMU_DriverInitialize();
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -254,9 +872,9 @@ impl Cam {
} }
} }
pub fn stop_capture(&self, port: CamPort) -> crate::Result<()> { pub fn driver_finalize(&self) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_StopCapture(port.bits()); let r = ctru_sys::CAMU_DriverFinalize();
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {
@ -265,9 +883,45 @@ impl Cam {
} }
} }
pub fn activate(&mut self, camera: CamSelect) -> crate::Result<()> { pub fn get_activated_camera(&self, camera: &mut u32) -> crate::Result<()> {
unsafe { unsafe {
let r = ctru_sys::CAMU_Activate(camera.bits()); let r = ctru_sys::CAMU_GetActivatedCamera(camera);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn get_sleep_camera(&self, camera: &mut u32) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_GetSleepCamera(camera);
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_sleep_camera(&self, camera: CamSelect) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetSleepCamera(camera.bits());
if r < 0 {
Err(r.into())
} else {
Ok(())
}
}
}
pub fn set_brightness_synchronization(
&self,
brightness_synchronization: bool,
) -> crate::Result<()> {
unsafe {
let r = ctru_sys::CAMU_SetBrightnessSynchronization(brightness_synchronization);
if r < 0 { if r < 0 {
Err(r.into()) Err(r.into())
} else { } else {

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

@ -16,7 +16,9 @@ impl ServiceReference {
S: FnOnce() -> crate::Result<()>, S: FnOnce() -> crate::Result<()>,
E: Fn() + Send + Sync + 'static, E: Fn() + Send + Sync + 'static,
{ {
let mut value = counter.lock().expect("Mutex Counter for ServiceReference is poisoned"); // todo: handle poisoning let mut value = counter
.lock()
.expect("Mutex Counter for ServiceReference is poisoned"); // todo: handle poisoning
if *value == 0 { if *value == 0 {
start()?; start()?;
@ -35,7 +37,10 @@ impl ServiceReference {
impl Drop for ServiceReference { impl Drop for ServiceReference {
fn drop(&mut self) { fn drop(&mut self) {
let mut value = self.counter.lock().expect("Mutex Counter for ServiceReference is poisoned"); // todo: handle poisoning let mut value = self
.counter
.lock()
.expect("Mutex Counter for ServiceReference is poisoned"); // todo: handle poisoning
*value -= 1; *value -= 1;
if *value == 0 { if *value == 0 {
(self.close)(); (self.close)();

184
example.rsf

@ -0,0 +1,184 @@
BasicInfo:
Title : ctru-rs-test
ProductCode : CTRU-TEST
Logo : Homebrew # Nintendo / Licensed / Distributed / iQue / iQueForSystem
TitleInfo:
Category : Application
UniqueId : 0xCC
Option:
UseOnSD : true # true if App is to be installed to SD
FreeProductCode : true # Removes limitations on ProductCode
MediaFootPadding : false # If true CCI files are created with padding
EnableCrypt : false # Enables encryption for NCCH and CIA
EnableCompress : false # Compresses where applicable (currently only exefs:/.code)
AccessControlInfo:
CoreVersion : 2
# Exheader Format Version
DescVersion : 2
# ExtData
UseExtSaveData : false # enables ExtData
# FS:USER Archive Access Permissions
FileSystemAccess:
- DirectSdmc
# Process Settings
MemoryType : Application # Application/System/Base
SystemMode : 64MB # 64MB(Default)/96MB/80MB/72MB/32MB
IdealProcessor : 0
AffinityMask : 1
Priority : 16
MaxCpu : 0 # Let system decide
HandleTableSize : 0x200
DisableDebug : false
EnableForceDebug : false
CanWriteSharedPage : true
CanUsePrivilegedPriority : false
CanUseNonAlphabetAndNumber : true
PermitMainFunctionArgument : true
CanShareDeviceMemory : true
RunnableOnSleep : false
SpecialMemoryArrange : true
# New3DS Exclusive Process Settings
SystemModeExt : 124MB # Legacy(Default)/124MB/178MB Legacy:Use Old3DS SystemMode
CpuSpeed : 804MHz # 268MHz(Default)/804MHz
EnableL2Cache : true # false(default)/true
CanAccessCore2 : true
# Virtual Address Mappings
IORegisterMapping:
- 1ff00000-1ff7ffff # DSP memory
MemoryMapping:
- 1f000000-1f5fffff:r # VRAM
# Accessible SVCs, <Name>:<ID>
SystemCallAccess:
ArbitrateAddress: 34
Break: 60
CancelTimer: 28
ClearEvent: 25
ClearTimer: 29
CloseHandle: 35
ConnectToPort: 45
ControlMemory: 1
CreateAddressArbiter: 33
CreateEvent: 23
CreateMemoryBlock: 30
CreateMutex: 19
CreateSemaphore: 21
CreateThread: 8
CreateTimer: 26
DuplicateHandle: 39
ExitProcess: 3
ExitThread: 9
GetCurrentProcessorNumber: 17
GetHandleInfo: 41
GetProcessId: 53
GetProcessIdOfThread: 54
GetProcessIdealProcessor: 6
GetProcessInfo: 43
GetResourceLimit: 56
GetResourceLimitCurrentValues: 58
GetResourceLimitLimitValues: 57
GetSystemInfo: 42
GetSystemTick: 40
GetThreadContext: 59
GetThreadId: 55
GetThreadIdealProcessor: 15
GetThreadInfo: 44
GetThreadPriority: 11
MapMemoryBlock: 31
OutputDebugString: 61
QueryMemory: 2
ReleaseMutex: 20
ReleaseSemaphore: 22
SendSyncRequest1: 46
SendSyncRequest2: 47
SendSyncRequest3: 48
SendSyncRequest4: 49
SendSyncRequest: 50
SetThreadPriority: 12
SetTimer: 27
SignalEvent: 24
SleepThread: 10
UnmapMemoryBlock: 32
WaitSynchronization1: 36
WaitSynchronizationN: 37
Backdoor: 123
# Service List
# Maximum 34 services (32 if firmware is prior to 9.3.0)
ServiceAccessControl:
- cfg:u
- fs:USER
- gsp::Gpu
- hid:USER
- ndm:u
- pxi:dev
- APT:U
- ac:u
- act:u
- am:net
- boss:U
- cam:u
- cecd:u
- csnd:SND
- frd:u
- http:C
- ir:USER
- ir:u
- ir:rst
- ldr:ro
- mic:u
- news:u
- nfc:u
- nim:aoc
- nwm::UDS
- ptm:u
- qtm:u
- soc:U
- ssl:C
- y2r:u
SystemControlInfo:
SaveDataSize: 0KB # It doesn't use any save data.
RemasterVersion: 0
StackSize: 0x40000
Dependency:
ac: 0x0004013000002402
am: 0x0004013000001502
boss: 0x0004013000003402
camera: 0x0004013000001602
cecd: 0x0004013000002602
cfg: 0x0004013000001702
codec: 0x0004013000001802
csnd: 0x0004013000002702
dlp: 0x0004013000002802
dsp: 0x0004013000001a02
friends: 0x0004013000003202
gpio: 0x0004013000001b02
gsp: 0x0004013000001c02
hid: 0x0004013000001d02
http: 0x0004013000002902
i2c: 0x0004013000001e02
ir: 0x0004013000003302
mcu: 0x0004013000001f02
mic: 0x0004013000002002
ndm: 0x0004013000002b02
news: 0x0004013000003502
nim: 0x0004013000002c02
nwm: 0x0004013000002d02
pdn: 0x0004013000002102
ps: 0x0004013000003102
ptm: 0x0004013000002202
ro: 0x0004013000003702
socket: 0x0004013000002e02
spi: 0x0004013000002302
ssl: 0x0004013000002f02
Loading…
Cancel
Save