Ian Chamberlain
3 years ago
9 changed files with 199 additions and 126 deletions
@ -1,56 +1,41 @@ |
|||||||
use ctru::console::Console; |
use ctru::console::Console; |
||||||
use ctru::gfx::{Gfx, Screen}; |
use ctru::gfx::Gfx; |
||||||
use ctru::services::apt::Apt; |
use ctru::services::apt::Apt; |
||||||
use ctru::services::hid::{Hid, KeyPad}; |
use ctru::services::hid::{Hid, KeyPad}; |
||||||
|
|
||||||
|
use std::io::BufWriter; |
||||||
|
|
||||||
fn main() { |
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(); |
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 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.
|
let out = b"Hello fellow Rustaceans, I'm on the Nintendo 3DS!"; |
||||||
// Consoles can be initialized on both the top and bottom screens.
|
let width = 24; |
||||||
let _console = Console::init(&gfx, Screen::Top); |
|
||||||
|
|
||||||
// Now we can print to stdout!
|
let mut writer = BufWriter::new(Vec::new()); |
||||||
println!("Hello, world!"); |
ferris_says::say(out, width, &mut writer).unwrap(); |
||||||
|
|
||||||
// We can use escape sequences to move the cursor around the terminal.
|
println!( |
||||||
// The following text will be moved down 29 rows and right 16 characters
|
"\x1b[0;0H{}", |
||||||
// before printing begins.
|
String::from_utf8_lossy(&writer.into_inner().unwrap()) |
||||||
println!("\x1b[29;16HPress Start to exit"); |
); |
||||||
|
|
||||||
// Main application loop.
|
// Main loop
|
||||||
while apt.main_loop() { |
while apt.main_loop() { |
||||||
// Flushes and swaps the framebuffers when double-buffering
|
//Scan all the inputs. This should be done once for each frame
|
||||||
// is enabled
|
|
||||||
gfx.flush_buffers(); |
|
||||||
gfx.swap_buffers(); |
|
||||||
|
|
||||||
// Wait for the next frame to begin
|
|
||||||
gfx.wait_for_vblank(); |
|
||||||
|
|
||||||
// Scan for user input.
|
|
||||||
hid.scan_input(); |
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) { |
if hid.keys_down().contains(KeyPad::KEY_START) { |
||||||
break; |
break; |
||||||
} |
} |
||||||
} |
// Flush and swap framebuffers
|
||||||
|
gfx.flush_buffers(); |
||||||
|
gfx.swap_buffers(); |
||||||
|
|
||||||
// All of our service handles will drop out of scope at this point,
|
//Wait for VBlank
|
||||||
// triggering the end of our application.
|
gfx.wait_for_vblank(); |
||||||
|
} |
||||||
} |
} |
||||||
|
@ -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<html><body>Hello world</body></html>\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; |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue