From 89c5c44e286300256d6f72febe5a66146ecd9909 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Sat, 11 May 2024 14:43:56 +0200 Subject: [PATCH] add luma, currently broken --- Cargo.lock | 11 ++++--- src/gui.rs | 34 +++++++++++++-------- src/main.rs | 88 +++++++++++++++++++++++++++++++---------------------- 3 files changed, 78 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0d4d237..2ec18c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2151,8 +2151,9 @@ dependencies = [ [[package]] name = "servicepoint2" version = "0.1.0" -source = "git+https://github.com/kaesaecracker/servicepoint.git#8ceaef72faaa5d36000089c415a5b28f7e244513" +source = "git+https://github.com/kaesaecracker/servicepoint.git#27f891cd921821400b4ae69e02986bf5ed2687b8" dependencies = [ + "log", "num", "num-derive", "num-traits", @@ -2270,9 +2271,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.61" +version = "2.0.62" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c993ed8ccba56ae856363b1845da7266a7cb78e1d146c8a32d54b45a8b831fc9" +checksum = "9f660c3bfcefb88c538776b6685a0c472e3128b51e74d48793dc2a488196e8eb" dependencies = [ "proc-macro2", "quote", @@ -2426,9 +2427,9 @@ checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" [[package]] name = "ttf-parser" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71ffab0ca84cecd986dd52e873c8d0b013f3d5d9ce25a6f7d0513ed933d562" +checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" [[package]] name = "ultraviolet" diff --git a/src/gui.rs b/src/gui.rs index 511d450..859419c 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -1,7 +1,7 @@ -use log::{trace, warn}; +use log::warn; use pixels::wgpu::TextureFormat; use pixels::{Pixels, PixelsBuilder, SurfaceTexture}; -use servicepoint2::{PixelGrid, PIXEL_HEIGHT, PIXEL_WIDTH}; +use servicepoint2::{ByteGrid, PixelGrid, PIXEL_HEIGHT, PIXEL_WIDTH, TILE_SIZE}; use std::sync::mpsc::Receiver; use std::sync::RwLock; use winit::application::ApplicationHandler; @@ -12,15 +12,21 @@ use winit::window::{Window, WindowId}; pub struct App<'t> { display: &'t RwLock, + luma: &'t RwLock, window: Option, pixels: Option, stop_ui_rx: Receiver<()>, } impl<'t> App<'t> { - pub fn new(display: &RwLock, stop_ui_rx: Receiver<()>) -> App { + pub fn new( + display: &'t RwLock, + luma: &'t RwLock, + stop_ui_rx: Receiver<()>, + ) -> Self { App { display, + luma, stop_ui_rx, pixels: None, window: None, @@ -53,30 +59,32 @@ impl ApplicationHandler for App<'_> { } fn window_event(&mut self, event_loop: &ActiveEventLoop, _: WindowId, event: WindowEvent) { - trace!("event {:?}", event); + if self.stop_ui_rx.try_recv().is_ok() { + warn!("ui thread stop requested"); + event_loop.exit(); + } + match event { WindowEvent::CloseRequested => { warn!("The close button was pressed; stopping"); event_loop.exit(); } WindowEvent::RedrawRequested => { - if self.stop_ui_rx.try_recv().is_ok() { - warn!("ui thread stopping"); - event_loop.exit(); - } - let window = self.window.as_ref().unwrap(); let pixels = self.pixels.as_mut().unwrap(); let mut frame = pixels.frame_mut().chunks_exact_mut(4); let display = self.display.read().unwrap(); + let luma = self.luma.read().unwrap(); + + for y in 0..PIXEL_HEIGHT as usize { + for x in 0..PIXEL_WIDTH as usize { + let is_set = display.get(x , y ); + let brightness = luma.get(x / TILE_SIZE as usize, y / TILE_SIZE as usize); - for y in 0..PIXEL_HEIGHT { - for x in 0..PIXEL_WIDTH { - let is_set = display.get(x as usize, y as usize); let color = if is_set { - [255u8, 255, 255, 255] + [0u8, brightness, 0, 255] } else { [0u8, 0, 0, 255] }; diff --git a/src/main.rs b/src/main.rs index 4526e8e..d50ec02 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,8 +8,8 @@ use crate::gui::App; use clap::Parser; use log::{debug, error, info, warn}; use servicepoint2::{ - Command, Origin, Packet, PixelGrid, Size, Window, PIXEL_HEIGHT, PIXEL_WIDTH, TILE_SIZE, - TILE_WIDTH, + ByteGrid, Command, Origin, Packet, PixelGrid, PIXEL_HEIGHT, PIXEL_WIDTH, TILE_HEIGHT, + TILE_SIZE, TILE_WIDTH, }; use std::io::ErrorKind; use std::net::UdpSocket; @@ -36,9 +36,13 @@ fn main() { let font = BitmapFont::load_file("Web437_IBM_BIOS.woff"); - let display = PixelGrid::new(PIXEL_WIDTH as usize, PIXEL_HEIGHT as usize); - let display_locked = RwLock::new(display); - let display_locked_ref = &display_locked; + let display = RwLock::new(PixelGrid::new(PIXEL_WIDTH as usize, PIXEL_HEIGHT as usize)); + let display_ref = &display; + + let mut luma = ByteGrid::new(TILE_WIDTH as usize, TILE_HEIGHT as usize); + luma.fill(u8::MAX); + let luma = RwLock::new(luma); + let luma_ref = &luma; std::thread::scope(move |scope| { let (stop_udp_tx, stop_udp_rx) = mpsc::channel(); @@ -67,14 +71,13 @@ fn main() { let vec = buf[..amount].to_vec(); let package = servicepoint2::Packet::from(vec); - let mut display = display_locked_ref.write().unwrap(); - handle_package(package, &font, &mut display); + handle_package(package, &font, display_ref, luma_ref); } stop_ui_tx.send(()).expect("could not stop ui thread"); }); - let mut app = App::new(display_locked_ref, stop_ui_rx); + let mut app = App::new(display_ref, luma_ref, stop_ui_rx); let event_loop = EventLoop::new().expect("could not create event loop"); event_loop.set_control_flow(ControlFlow::Poll); @@ -89,7 +92,12 @@ fn main() { }); } -fn handle_package(received: Packet, font: &BitmapFont, display: &mut RwLockWriteGuard) { +fn handle_package( + received: Packet, + font: &BitmapFont, + display_ref: &RwLock, + luma_ref: &RwLock, +) { let command = match Command::try_from(received) { Err(err) => { warn!("could not read command for packet: {:?}", err); @@ -101,23 +109,27 @@ fn handle_package(received: Packet, font: &BitmapFont, display: &mut RwLockWrite match command { Command::Clear => { info!("clearing display"); - display.fill(false); + display_ref.write().unwrap().fill(false); } Command::HardReset => { warn!("display shutting down"); return; } Command::BitmapLinearWin(Origin(x, y), pixels) => { - print_pixel_grid(x as usize, y as usize, &pixels, display); + let mut display = display_ref.write().unwrap(); + print_pixel_grid(x as usize, y as usize, &pixels, &mut display); } - Command::Cp437Data(window, payload) => { - print_cp437_data(window, &payload, font, display); + Command::Cp437Data(origin, grid) => { + let mut display = display_ref.write().unwrap(); + print_cp437_data(origin, &grid, font, &mut display); } #[allow(deprecated)] Command::BitmapLegacy => { warn!("ignoring deprecated command {:?}", command); } + // TODO: how to deduplicate this code in a rusty way? Command::BitmapLinear(offset, vec) => { + let mut display = display_ref.write().unwrap(); for bitmap_index in 0..vec.len() { let pixel_index = offset as usize + bitmap_index; let y = pixel_index / TILE_WIDTH as usize; @@ -126,6 +138,7 @@ fn handle_package(received: Packet, font: &BitmapFont, display: &mut RwLockWrite } } Command::BitmapLinearAnd(offset, vec) => { + let mut display = display_ref.write().unwrap(); for bitmap_index in 0..vec.len() { let pixel_index = offset as usize + bitmap_index; let y = pixel_index / TILE_WIDTH as usize; @@ -135,6 +148,7 @@ fn handle_package(received: Packet, font: &BitmapFont, display: &mut RwLockWrite } } Command::BitmapLinearOr(offset, vec) => { + let mut display = display_ref.write().unwrap(); for bitmap_index in 0..vec.len() { let pixel_index = offset as usize + bitmap_index; let y = pixel_index / TILE_WIDTH as usize; @@ -144,6 +158,7 @@ fn handle_package(received: Packet, font: &BitmapFont, display: &mut RwLockWrite } } Command::BitmapLinearXor(offset, vec) => { + let mut display = display_ref.write().unwrap(); for bitmap_index in 0..vec.len() { let pixel_index = offset as usize + bitmap_index; let y = pixel_index / TILE_WIDTH as usize; @@ -152,39 +167,38 @@ fn handle_package(received: Packet, font: &BitmapFont, display: &mut RwLockWrite display.set(x, y, old_value ^ vec.get(bitmap_index)); } } - _ => { + Command::CharBrightness(origin, grid) => { + let Origin(offset_x, offset_y) = origin; + let offset_x = offset_x as usize; + let offset_y = offset_y as usize; + + let mut luma = luma_ref.write().unwrap(); + for inner_y in 0..grid.height { + for inner_x in 0..grid.width { + let brightness = grid.get(inner_x, inner_y); + luma.set(offset_x + inner_x, offset_y + inner_y, brightness); + } + } + } + Command::Brightness(brightness) => { + luma_ref.write().unwrap().fill(brightness); + } + Command::FadeOut => { error!("command not implemented: {command:?}") } }; } -fn check_payload_size(buf: &[u8], expected: usize) -> bool { - let actual = buf.len(); - if actual == expected { - return true; - } - - error!( - "expected a payload length of {} but got {}", - expected, actual - ); - return false; -} - fn print_cp437_data( - window: Window, - payload: &[u8], + origin: Origin, + grid: &ByteGrid, font: &BitmapFont, display: &mut RwLockWriteGuard, ) { - let Window(Origin(x, y), Size(w, h)) = window; - if !check_payload_size(payload, (w * h) as usize) { - return; - } - - for char_y in 0usize..h as usize { - for char_x in 0usize..w as usize { - let char_code = payload[char_y * w as usize + char_x]; + let Origin(x, y) = origin; + for char_y in 0usize..grid.height { + for char_x in 0usize..grid.width { + let char_code = grid.get(char_x, char_y); let tile_x = char_x + x as usize; let tile_y = char_y + y as usize;