diff --git a/ctru-rs/Cargo.toml b/ctru-rs/Cargo.toml index f33e177..29323b4 100644 --- a/ctru-rs/Cargo.toml +++ b/ctru-rs/Cargo.toml @@ -18,3 +18,6 @@ pthread-3ds = { git = "https://github.com/Meziu/pthread-3ds.git" } libc = { git = "https://github.com/Meziu/libc.git" } bitflags = "1.0.0" widestring = "0.2.2" + +[dev-dependencies] +ferris-says = "0.2.1" diff --git a/ctru-rs/examples/buttons.rs b/ctru-rs/examples/buttons.rs index 36127cd..152ede6 100644 --- a/ctru-rs/examples/buttons.rs +++ b/ctru-rs/examples/buttons.rs @@ -1,5 +1,5 @@ use ctru::console::Console; -use ctru::gfx::{Gfx, Screen}; +use ctru::gfx::Gfx; use ctru::services::apt::Apt; use ctru::services::hid::{Hid, KeyPad}; @@ -9,7 +9,7 @@ fn main() { let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::default(); - let console = Console::init(&gfx, Screen::Top); + let console = Console::init(gfx.top_screen.borrow_mut()); println!("Hi there! Try pressing a button"); println!("\x1b[29;16HPress Start to exit"); diff --git a/ctru-rs/examples/file-explorer.rs b/ctru-rs/examples/file-explorer.rs index 690c6a8..988283b 100644 --- a/ctru-rs/examples/file-explorer.rs +++ b/ctru-rs/examples/file-explorer.rs @@ -3,7 +3,6 @@ use ctru::applets::swkbd::{Button, Swkbd}; use ctru::console::Console; -use ctru::gfx::Screen; use ctru::services::hid::KeyPad; use ctru::services::{Apt, Hid}; use ctru::Gfx; @@ -31,8 +30,8 @@ struct FileExplorer<'a> { impl<'a> FileExplorer<'a> { fn init(apt: &'a Apt, hid: &'a Hid, gfx: &'a Gfx) -> Self { - gfx.set_wide_mode(true); - let console = Console::init(gfx, Screen::Top); + gfx.top_screen.borrow_mut().set_wide_mode(true); + let console = Console::init(gfx.top_screen.borrow_mut()); FileExplorer { apt, diff --git a/ctru-rs/examples/gfx_wide_mode.rs b/ctru-rs/examples/gfx-wide-mode.rs similarity index 62% rename from ctru-rs/examples/gfx_wide_mode.rs rename to ctru-rs/examples/gfx-wide-mode.rs index f4ba365..fcf3fa9 100644 --- a/ctru-rs/examples/gfx_wide_mode.rs +++ b/ctru-rs/examples/gfx-wide-mode.rs @@ -1,7 +1,4 @@ -extern crate ctru; - use ctru::console::Console; -use ctru::gfx::Screen; use ctru::services::hid::KeyPad; use ctru::services::{Apt, Hid}; use ctru::Gfx; @@ -11,7 +8,7 @@ fn main() { let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::default(); - let _console = Console::init(&gfx, Screen::Top); + let mut console = Console::init(gfx.top_screen.borrow_mut()); println!("Press A to enable/disable wide screen mode."); @@ -23,7 +20,13 @@ fn main() { } if hid.keys_down().contains(KeyPad::KEY_A) { - gfx.set_wide_mode(!gfx.get_wide_mode()); + drop(console); + + let wide_mode = gfx.top_screen.borrow().get_wide_mode(); + gfx.top_screen.borrow_mut().set_wide_mode(!wide_mode); + + console = Console::init(gfx.top_screen.borrow_mut()); + println!("Press A to enable/disable wide screen mode."); } gfx.flush_buffers(); diff --git a/ctru-rs/examples/hello-both-screens.rs b/ctru-rs/examples/hello-both-screens.rs index 180b1b2..67113a3 100644 --- a/ctru-rs/examples/hello-both-screens.rs +++ b/ctru-rs/examples/hello-both-screens.rs @@ -1,5 +1,5 @@ use ctru::console::Console; -use ctru::gfx::{Gfx, Screen}; +use ctru::gfx::Gfx; use ctru::services::apt::Apt; use ctru::services::hid::{Hid, KeyPad}; @@ -11,11 +11,11 @@ fn main() { let gfx = Gfx::default(); // Start a console on the top screen - let top_screen = Console::init(&gfx, Screen::Top); + let top_screen = Console::init(gfx.top_screen.borrow_mut()); // Start a console on the bottom screen. // The most recently initialized console will be active by default - let bottom_screen = Console::init(&gfx, Screen::Bottom); + let bottom_screen = Console::init(gfx.bottom_screen.borrow_mut()); // Let's print on the top screen first top_screen.select(); diff --git a/ctru-rs/examples/hello-world.rs b/ctru-rs/examples/hello-world.rs index ccebef7..930549f 100644 --- a/ctru-rs/examples/hello-world.rs +++ b/ctru-rs/examples/hello-world.rs @@ -1,56 +1,41 @@ use ctru::console::Console; -use ctru::gfx::{Gfx, Screen}; +use ctru::gfx::Gfx; use ctru::services::apt::Apt; use ctru::services::hid::{Hid, KeyPad}; +use std::io::BufWriter; + fn main() { - // Initialize ctrulib service handles. - // Service handles are internally reference-counted. When all instances of a - // service handle go out of scope, the service will be closed. ctru::init(); - - // The APT service handles application management functions, such as enabling sleep - // mode and jumping to the home menu or to other applications - let apt = Apt::init().unwrap(); - - // The HID service handles button and touch screen inputs. - let hid = Hid::init().unwrap(); - - // The GFX service manages the framebuffers for the top and bottom screens. let gfx = Gfx::default(); + let hid = Hid::init().expect("Couldn't obtain HID controller"); + let apt = Apt::init().expect("Couldn't obtain APT controller"); + let _console = Console::init(gfx.top_screen.borrow_mut()); - // Initialize a ctrulib console and direct standard output to it. - // Consoles can be initialized on both the top and bottom screens. - let _console = Console::init(&gfx, Screen::Top); + let out = b"Hello fellow Rustaceans, I'm on the Nintendo 3DS!"; + let width = 24; - // Now we can print to stdout! - println!("Hello, world!"); + let mut writer = BufWriter::new(Vec::new()); + ferris_says::say(out, width, &mut writer).unwrap(); - // We can use escape sequences to move the cursor around the terminal. - // The following text will be moved down 29 rows and right 16 characters - // before printing begins. - println!("\x1b[29;16HPress Start to exit"); + println!( + "\x1b[0;0H{}", + String::from_utf8_lossy(&writer.into_inner().unwrap()) + ); - // Main application loop. + // Main loop while apt.main_loop() { - // Flushes and swaps the framebuffers when double-buffering - // is enabled - gfx.flush_buffers(); - gfx.swap_buffers(); - - // Wait for the next frame to begin - gfx.wait_for_vblank(); - - // Scan for user input. + //Scan all the inputs. This should be done once for each frame hid.scan_input(); - // Check if the user has pressed the given button on this frame. - // If so, break out of the loop. if hid.keys_down().contains(KeyPad::KEY_START) { break; } - } + // Flush and swap framebuffers + gfx.flush_buffers(); + gfx.swap_buffers(); - // All of our service handles will drop out of scope at this point, - // triggering the end of our application. + //Wait for VBlank + gfx.wait_for_vblank(); + } } diff --git a/ctru-rs/examples/network-sockets.rs b/ctru-rs/examples/network-sockets.rs new file mode 100644 index 0000000..84978e9 --- /dev/null +++ b/ctru-rs/examples/network-sockets.rs @@ -0,0 +1,65 @@ +use ctru::console::Console; +use ctru::gfx::Gfx; +use ctru::services::apt::Apt; +use ctru::services::hid::{Hid, KeyPad}; +use ctru::services::soc::Soc; + +use std::io::{Read, Write}; +use std::net::{Shutdown, TcpListener}; +use std::time::Duration; + +fn main() { + ctru::init(); + let gfx = Gfx::default(); + let _console = Console::init(gfx.top_screen.borrow_mut()); + let hid = Hid::init().unwrap(); + let apt = Apt::init().unwrap(); + + println!("\nlibctru sockets demo\n"); + + let soc = Soc::init().unwrap(); + + let server = TcpListener::bind("0.0.0.0:80").unwrap(); + server.set_nonblocking(true).unwrap(); + + println!("Point your browser to http://{}/\n", soc.host_address()); + + while apt.main_loop() { + gfx.wait_for_vblank(); + + match server.accept() { + Ok((mut stream, socket_addr)) => { + println!("Got connection from {}", socket_addr); + + let mut buf = [0u8; 4096]; + match stream.read(&mut buf) { + Ok(_) => { + let req_str = String::from_utf8_lossy(&buf); + println!("{}", req_str); + } + Err(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
Hello world\r\n"; + + if let Err(e) = stream.write(response) { + println!("Error writing http response: {}", e); + } + + stream.shutdown(Shutdown::Both).unwrap(); + } + Err(e) => match e.kind() { + std::io::ErrorKind::WouldBlock => {} + _ => { + println!("Error accepting connection: {}", e); + std::thread::sleep(Duration::from_secs(2)); + } + }, + } + + hid.scan_input(); + if hid.keys_down().contains(KeyPad::KEY_START) { + break; + }; + } +} diff --git a/ctru-rs/examples/software-keyboard.rs b/ctru-rs/examples/software-keyboard.rs index b3b9347..6be9e81 100644 --- a/ctru-rs/examples/software-keyboard.rs +++ b/ctru-rs/examples/software-keyboard.rs @@ -1,6 +1,6 @@ use ctru::applets::swkbd::{Button, Swkbd}; use ctru::console::Console; -use ctru::gfx::{Gfx, Screen}; +use ctru::gfx::Gfx; use ctru::services::apt::Apt; use ctru::services::hid::{Hid, KeyPad}; @@ -9,7 +9,7 @@ fn main() { let apt = Apt::init().unwrap(); let hid = Hid::init().unwrap(); let gfx = Gfx::default(); - let _console = Console::init(&gfx, Screen::Top); + let _console = Console::init(gfx.top_screen.borrow_mut()); println!("Press A to enter some text or press Start to quit"); diff --git a/ctru-rs/src/console.rs b/ctru-rs/src/console.rs index 0c86129..2df1495 100644 --- a/ctru-rs/src/console.rs +++ b/ctru-rs/src/console.rs @@ -1,28 +1,25 @@ +use std::cell::RefMut; use std::default::Default; -use std::marker::PhantomData; use ctru_sys::{consoleClear, consoleInit, consoleSelect, consoleSetWindow, PrintConsole}; -use crate::gfx::{Gfx, Screen}; +use crate::gfx::Screen; -pub struct Console<'gfx> { +pub struct Console<'screen> { context: Box