Skip to content

Commit

Permalink
Merge pull request #137 from rust3ds/camera-and-more
Browse files Browse the repository at this point in the history
Camera rework and small fixes
  • Loading branch information
Meziu authored Nov 22, 2023
2 parents 4d718c4 + 1f72bfd commit 9406f5d
Show file tree
Hide file tree
Showing 39 changed files with 1,242 additions and 591 deletions.
2 changes: 0 additions & 2 deletions ctru-rs/examples/audio-filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ fn fill_buffer(audio_data: &mut [u8], frequency: f32) {
}

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand Down
10 changes: 7 additions & 3 deletions ctru-rs/examples/buttons.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
use ctru::prelude::*;

fn main() {
ctru::use_panic_handler();

let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
Expand All @@ -25,6 +23,12 @@ fn main() {
// Get information about which keys were held down on this frame.
let keys = hid.keys_held();

// Print the status of the volume slider.
println!(
"\x1b[20;0HVolume slider: {} ",
hid.volume_slider()
);

// We only want to print when the keys we're holding now are different
// from what they were on the previous frame.
if keys != old_keys {
Expand All @@ -44,7 +48,7 @@ fn main() {
// and the `.intersects()` method checks for any of the provided keys.
//
// You can also use the `.bits()` method to do direct comparisons on
// the underlying bits
// the underlying bits.

if keys.contains(KeyPad::A) {
println!("You held A!");
Expand Down
77 changes: 45 additions & 32 deletions ctru-rs/examples/camera-image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,27 @@
//! This example demonstrates how to use the built-in cameras to take a picture and display it to the screen.
use ctru::prelude::*;
use ctru::services::cam::{Cam, Camera, OutputFormat, ShutterSound, ViewSize};
use ctru::services::gfx::{Flush, Screen, Swap};
use ctru::services::cam::{
Cam, Camera, OutputFormat, ShutterSound, Trimming, ViewSize, WhiteBalance,
};
use ctru::services::gfx::{Flush, Screen, Swap, TopScreen3D};
use ctru::services::gspgpu::FramebufferFormat;

use std::time::Duration;

const WIDTH: usize = 400;
const HEIGHT: usize = 240;

// The screen size is the width and height multiplied by 2 (RGB565 store pixels in 2 bytes).
const BUF_SIZE: usize = WIDTH * HEIGHT * 2;

const WAIT_TIMEOUT: Duration = Duration::from_millis(300);

fn main() {
ctru::use_panic_handler();

let apt = Apt::new().expect("Failed to initialize Apt service.");
let mut hid = Hid::new().expect("Failed to initialize Hid service.");
let gfx = Gfx::new().expect("Failed to initialize GFX service.");

let mut top_screen = gfx.top_screen.borrow_mut();
top_screen.set_double_buffering(true);
top_screen.set_framebuffer_format(FramebufferFormat::Rgb565);
gfx.top_screen.borrow_mut().set_double_buffering(true);
gfx.top_screen
.borrow_mut()
.set_framebuffer_format(FramebufferFormat::Rgb565);

let mut top_screen_3d = TopScreen3D::from(&gfx.top_screen);

let _console = Console::new(gfx.bottom_screen.borrow_mut());

Expand All @@ -35,9 +32,8 @@ fn main() {
let mut cam = Cam::new().expect("Failed to initialize CAM service.");

// Camera setup.
let camera = &mut cam.both_outer_cams;
{
let camera = &mut cam.outer_right_cam;

camera
.set_view_size(ViewSize::TopLCD)
.expect("Failed to set camera size");
Expand All @@ -51,14 +47,17 @@ fn main() {
.set_auto_exposure(true)
.expect("Failed to enable auto exposure");
camera
.set_auto_white_balance(true)
.set_white_balance(WhiteBalance::Auto)
.expect("Failed to enable auto white balance");
// This line has no effect on the camera since the photos are already shot with `TopLCD` size.
camera
.set_trimming(false)
.expect("Failed to disable trimming");
.set_trimming(Trimming::new_centered_with_view(ViewSize::TopLCD))
.expect("Failed to enable trimming");
}

let mut buf = vec![0u8; BUF_SIZE];
// We don't intend on making any other modifications to the camera, so this size should be enough.
let len = camera.final_byte_length();
let mut buf = vec![0u8; len];

println!("\nPress R to take a new picture");
println!("Press Start to exit");
Expand All @@ -75,28 +74,42 @@ fn main() {
if keys_down.contains(KeyPad::R) {
println!("Capturing new image");

let camera = &mut cam.outer_right_cam;
let camera = &mut cam.both_outer_cams;

// Take a picture and write it to the buffer.
camera
.take_picture(
&mut buf,
WIDTH.try_into().unwrap(),
HEIGHT.try_into().unwrap(),
WAIT_TIMEOUT,
)
.take_picture(&mut buf, WAIT_TIMEOUT)
.expect("Failed to take picture");

let (width, height) = camera.final_view_size();

// Play the normal shutter sound.
cam.play_shutter_sound(ShutterSound::Normal)
.expect("Failed to play shutter sound");

// Rotate the image and correctly display it on the screen.
rotate_image_to_screen(&buf, top_screen.raw_framebuffer().ptr, WIDTH, HEIGHT);
{
let (mut left_side, mut right_side) = top_screen_3d.split_mut();

// Rotate the left image and correctly display it on the screen.
rotate_image_to_screen(
&buf,
left_side.raw_framebuffer().ptr,
width as usize,
height as usize,
);

// Rotate the right image and correctly display it on the screen.
rotate_image_to_screen(
&buf[len / 2..],
right_side.raw_framebuffer().ptr,
width as usize,
height as usize,
);
}

// We will only flush and swap the "camera" screen, since the other screen is handled by the `Console`.
top_screen.flush_buffers();
top_screen.swap_buffers();
top_screen_3d.flush_buffers();
top_screen_3d.swap_buffers();

gfx.wait_for_vblank();
}
Expand Down Expand Up @@ -125,8 +138,8 @@ fn rotate_image_to_screen(src: &[u8], framebuf: *mut u8, width: usize, height: u
unsafe {
// We'll work with pointers since the framebuffer is a raw pointer regardless.
// The offsets are completely safe as long as the width and height are correct.
let pixel_pointer = framebuf.offset(draw_index as isize);
pixel_pointer.copy_from(src.as_ptr().offset(read_index as isize), 2);
let pixel_pointer = framebuf.add(draw_index);
pixel_pointer.copy_from(src.as_ptr().add(read_index), 2);
}
}
}
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/file-explorer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ use std::os::horizon::fs::MetadataExt;
use std::path::{Path, PathBuf};

fn main() {
ctru::use_panic_handler();

let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/futures-basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ use futures::StreamExt;
use std::os::horizon::thread::BuilderExt;

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/futures-tokio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use std::os::horizon::thread::BuilderExt;
use std::time::Duration;

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/gfx-3d-mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ const IMAGE: &[u8] = include_bytes!("assets/ferris.rgb");
static ZERO: &[u8] = &[0; IMAGE.len()];

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/gfx-bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ use ctru::services::gfx::{Flush, Screen, Swap};
static IMAGE: &[u8] = include_bytes!("assets/ferris.rgb");

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/gfx-wide-mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
use ctru::prelude::*;

fn main() {
ctru::use_panic_handler();

let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/hashmaps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
use ctru::prelude::*;

fn main() {
ctru::use_panic_handler();

// HashMaps generate hashes thanks to the 3DS' cryptografically secure generator.
// This generator is only active when activating the `PS` service.
// This service is automatically initialized.
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/hello-both-screens.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
use ctru::prelude::*;

fn main() {
ctru::use_panic_handler();

let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
Expand Down
4 changes: 0 additions & 4 deletions ctru-rs/examples/hello-world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ use ctru::prelude::*;
use std::io::BufWriter;

fn main() {
// Setup the custom panic handler in case any errors arise.
// Thanks to it the user will get promptly notified of any panics.
ctru::use_panic_handler();

// Setup Graphics, Controller Inputs, Application runtime.
// These is standard setup any app would need.
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/linear-memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ use ctru::linear::LinearAllocator;
use ctru::prelude::*;

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand Down
4 changes: 1 addition & 3 deletions ctru-rs/examples/mii-selector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use ctru::applets::mii_selector::{Error, MiiSelector, Options};
use ctru::prelude::*;

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand All @@ -19,7 +17,7 @@ fn main() {
mii_selector.set_options(Options::ENABLE_CANCEL);
mii_selector.set_initial_index(3);
// The first user-made Mii cannot be used.
mii_selector.blacklist_user_mii(0.into());
mii_selector.blocklist_user_mii(0.into());
mii_selector.set_title("Great Mii Selector!");

// Launch the Mii Selector and use its result to print the selected Mii's information.
Expand Down
52 changes: 52 additions & 0 deletions ctru-rs/examples/movement.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//! Movement example.
//!
//! Simple application to showcase the use of the accelerometer and gyroscope.
use ctru::prelude::*;

fn main() {
let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");

let _console = Console::new(gfx.top_screen.borrow_mut());

println!("Move the console around!");
println!("\x1b[29;16HPress Start to exit");

// 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.
// However, they can simply be turned on and off whenever necessary.
hid.set_accelerometer(true)
.expect("Couldn't activate accelerometer");
hid.set_gyroscope(true)
.expect("Couldn't activate gyroscope");

while apt.main_loop() {
// Scan all the controller inputs.
// Accelerometer and gyroscope require this step to update the readings.
hid.scan_input();

if hid.keys_down().contains(KeyPad::START) {
break;
}

// Be careful: reading without activating the sensors (as done before this loop) will result in a panic.
println!(
"\x1b[3;0HAcceleration: {:?} ",
<(i16, i16, i16)>::from(
hid.accelerometer_vector()
.expect("could not retrieve acceleration vector")
)
);
println!(
"\x1b[4;0HGyroscope angular rate: {:?} ",
Into::<(i16, i16, i16)>::into(
hid.gyroscope_rate()
.expect("could not retrieve angular rate")
)
);

gfx.wait_for_vblank();
}
}
2 changes: 0 additions & 2 deletions ctru-rs/examples/network-sockets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ use std::net::{Shutdown, TcpListener};
use std::time::Duration;

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().unwrap();
let mut hid = Hid::new().unwrap();
let apt = Apt::new().unwrap();
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/output-3dslink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
use ctru::prelude::*;

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/romfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
use ctru::prelude::*;

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/software-keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use ctru::applets::swkbd::{Button, SoftwareKeyboard};
use ctru::prelude::*;

fn main() {
ctru::use_panic_handler();

let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/system-configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ use ctru::prelude::*;
use ctru::services::cfgu::Cfgu;

fn main() {
ctru::use_panic_handler();

let gfx = Gfx::new().expect("Couldn't obtain GFX controller");
let mut hid = Hid::new().expect("Couldn't obtain HID controller");
let apt = Apt::new().expect("Couldn't obtain APT controller");
Expand Down
2 changes: 0 additions & 2 deletions ctru-rs/examples/thread-basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ use std::os::horizon::thread::BuilderExt;
use std::time::Duration;

fn main() {
ctru::use_panic_handler();

let apt = Apt::new().unwrap();
let mut hid = Hid::new().unwrap();
let gfx = Gfx::new().unwrap();
Expand Down
Loading

0 comments on commit 9406f5d

Please sign in to comment.