implement Clear, HardReset, Cp437Data

This commit is contained in:
Vinzenz Schroeter 2024-05-08 13:21:31 +02:00
parent c1b1f0364e
commit ab7bebfc6e

View file

@ -1,11 +1,9 @@
use std::mem::size_of; use std::mem::size_of;
use std::net::UdpSocket; use std::net::{UdpSocket};
use clap::Parser; use clap::Parser;
use num_derive::FromPrimitive; use num_derive::FromPrimitive;
use crate::DisplayCommand::CmdBitmapLinearWin;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
struct Cli { struct Cli {
#[arg(long = "bind", default_value = "0.0.0.0:2342")] #[arg(long = "bind", default_value = "0.0.0.0:2342")]
@ -60,9 +58,18 @@ fn main() -> std::io::Result<()> {
assert_eq!(size_of::<HdrWindow>(), 10, "invalid struct size"); assert_eq!(size_of::<HdrWindow>(), 10, "invalid struct size");
let cli = Cli::parse(); let cli = Cli::parse();
println!("running with args: {:?}", cli); println!("running with args: {:?}", &cli);
let socket = UdpSocket::bind(cli.bind)?; loop {
// to emulate a hard reset, the actual main method gets called until it crashes
main2(&cli).unwrap();
}
}
fn main2(cli: &Cli) -> std::io::Result<()> {
println!("display booting up");
let socket = UdpSocket::bind(&cli.bind)?;
let mut buf = [0; 8985]; let mut buf = [0; 8985];
loop { loop {
@ -74,11 +81,19 @@ fn main() -> std::io::Result<()> {
continue; continue;
} }
let command_u16 =
u16::from_be(unsafe { std::ptr::read(received[0..=1].as_ptr() as *const u16) });
let maybe_command = num::FromPrimitive::from_u16(command_u16);
if maybe_command.is_none() {
println!(
"command {} received from {:?} is invalid",
command_u16, source
);
continue;
}
let header: HdrWindow = HdrWindow { let header: HdrWindow = HdrWindow {
command: num::FromPrimitive::from_u16(u16::from_be(unsafe { command: maybe_command.unwrap(),
std::ptr::read(received[0..=1].as_ptr() as *const u16)
}))
.unwrap(),
x: u16::from_be(unsafe { std::ptr::read(received[2..=3].as_ptr() as *const u16) }), x: u16::from_be(unsafe { std::ptr::read(received[2..=3].as_ptr() as *const u16) }),
y: u16::from_be(unsafe { std::ptr::read(received[4..=5].as_ptr() as *const u16) }), y: u16::from_be(unsafe { std::ptr::read(received[4..=5].as_ptr() as *const u16) }),
w: u16::from_be(unsafe { std::ptr::read(received[6..=7].as_ptr() as *const u16) }), w: u16::from_be(unsafe { std::ptr::read(received[6..=7].as_ptr() as *const u16) }),
@ -93,37 +108,80 @@ fn main() -> std::io::Result<()> {
payload.len() payload.len()
); );
if !matches!(header.command, CmdBitmapLinearWin) { match header.command {
DisplayCommand::CmdClear => {
println!("(imagine an empty screen now)")
}
DisplayCommand::CmdHardReset => {
println!("display shutting down");
return Ok(());
}
DisplayCommand::CmdBitmapLinearWin => {
print_bitmap_linear_win(&header, payload);
}
DisplayCommand::CmdCp437data => {
print_cp437_data(&header, payload);
}
_ => {
println!( println!(
"command {:?} sent by {:?} not implemented yet", "command {:?} sent by {:?} not implemented yet",
header.command, source header.command, source
); );
continue; }
}
}
}
fn check_payload_size(buf: &[u8], expected: usize) -> bool {
let actual = buf.len();
if actual == expected {
return true;
} }
let expected_size = (header.w * header.h) as usize;
if expected_size != payload.len() {
println!( println!(
"expected a payload length of {} but got {} from {:?}", "expected a payload length of {} but got {}",
expected_size, expected, actual
payload.len(),
source
); );
continue; return false;
}
fn print_bitmap_linear_win(header: &HdrWindow, payload: &[u8]) {
if !check_payload_size(payload, (header.w * header.h) as usize) {
return;
} }
println!("top left is offset by ({} | {})", header.x, header.y);
for y in 0..header.h { for y in 0..header.h {
for byte_x in 0..header.w { for byte_x in 0..header.w {
let byte_index = (y * header.w + byte_x) as usize; let byte_index = (y * header.w + byte_x) as usize;
let byte = payload[byte_index]; let byte = payload[byte_index];
for bitmask in [1, 2, 4, 8, 16, 32, 64, 128] { for bitmask in [1, 2, 4, 8, 16, 32, 64, 128] {
let char = if byte & bitmask == bitmask {'█'} else {' '}; let char = if byte & bitmask == bitmask {
'█'
} else {
' '
};
print!("{}", char); print!("{}", char);
} }
} }
println!(); println!();
} }
}
fn print_cp437_data(header: &HdrWindow, payload: &[u8]) {
if !check_payload_size(payload, (header.w * header.h) as usize) {
return;
}
println!("top left is offset by ({} | {})", header.x, header.y);
for y in 0..header.h {
for byte_x in 0..header.w {
let byte_index = (y * header.w + byte_x) as usize;
print!("{}", payload[byte_index] as char)
}
println!();
} }
} }