diff --git a/Cargo.lock b/Cargo.lock index abb6812..f3bdf1e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -760,6 +760,17 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inherent" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c38228f24186d9cc68c729accb4d413be9eaed6ad07ff79e0270d9e56f3de13" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -1510,13 +1521,14 @@ dependencies = [ [[package]] name = "servicepoint" -version = "0.16.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b04582e916474f1bc1605cad3773262c425d9062b487e49a0df59662f2cca8d" +checksum = "7d1e88713031e003dc3ee708dbb282e36714eee466a12d311d0e2e24c61c7118" dependencies = [ "bitvec", "bzip2", "flate2", + "inherent", "log", "once_cell", "rust-lzma", @@ -1526,7 +1538,7 @@ dependencies = [ [[package]] name = "servicepoint-simulator" -version = "0.2.4" +version = "0.2.3" dependencies = [ "clap", "env_logger", diff --git a/Cargo.toml b/Cargo.toml index a179ced..9dff976 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "servicepoint-simulator" -version = "0.2.4" +version = "0.2.3" edition = "2021" publish = true license = "GPL-3.0-or-later" @@ -19,6 +19,9 @@ env_logger = "0.11" clap = { version = "4.5", features = ["derive"] } thiserror = "2.0" +# package parsing +servicepoint = { features = ["all_compressions"], version = "0.15.2" } + # font rendering font-kit = "0.14.2" # I should not need this as a direct dependency, but then I cannot spell the types needed to use font-kit... @@ -29,10 +32,6 @@ winit = "0.30" # for drawing pixels onto the surface of the window softbuffer = "0.4.6" -[dependencies.servicepoint] -version = "0.16.0" -features = ["all_compressions"] - [profile.release] lto = true # Enable link-time optimization codegen-units = 1 # Reduce number of codegen units to increase optimizations diff --git a/README.md b/README.md index 2610a25..17d5be5 100644 --- a/README.md +++ b/README.md @@ -42,24 +42,14 @@ Make sure to run a release build, because a debug build _way_ slower. Usage: servicepoint-simulator [OPTIONS] Options: - --bind - address and port to bind to [default: 0.0.0.0:2342] - -f, --font - The name of the font family to use. This defaults to the system monospace font. - -s, --spacers - add spacers between tile rows to simulate gaps in real display - -r, --red - Use the red color channel - -g, --green - Use the green color channel - -b, --blue - Use the blue color channel - -v, --verbose - Set default log level lower. You can also change this via the RUST_LOG environment variable. - --experimental-null-char-handling - When receiving a null byte as a char in the CharGridCommand, do not overwrite any pixels instead of clearing all pixels. - -h, --help - Print help + --bind address and port to bind to [default: 0.0.0.0:2342] + -f, --font The name of the font family to use. This defaults to the system monospace font. + -s, --spacers add spacers between tile rows to simulate gaps in real display + -r, --red Use the red color channel + -g, --green Use the green color channel + -b, --blue Use the blue color channel + -v, --verbose Set default log level lower. You can also change this via the RUST_LOG environment variable. + -h, --help Print help ``` See [env_logger](https://docs.rs/env_logger/latest/env_logger/) to configure logging. diff --git a/flake.nix b/flake.nix index ffe1341..b5f5964 100644 --- a/flake.nix +++ b/flake.nix @@ -75,7 +75,6 @@ NIX_LD_LIBRARY_PATH = LD_LIBRARY_PATH; NIX_LD = pkgs.stdenv.cc.bintools.dynamicLinker; RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; - RUST_BACKTRACE = "1"; }; } ); diff --git a/src/cli.rs b/src/cli.rs index eb0497c..5d7adf0 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -22,11 +22,6 @@ pub struct Cli { help = "Set default log level lower. You can also change this via the RUST_LOG environment variable." )] pub verbose: bool, - #[arg( - long, - help = "When receiving a null byte as a char in the CharGridCommand, do not overwrite any pixels instead of clearing all pixels." - )] - pub experimental_null_char_handling: bool, } #[derive(Parser, Debug)] diff --git a/src/command_executor.rs b/src/command_executor.rs index 0fe276f..f24a5fe 100644 --- a/src/command_executor.rs +++ b/src/command_executor.rs @@ -5,11 +5,10 @@ use crate::{ }; use log::{debug, error, info, trace, warn}; use servicepoint::{ - BinaryOperation, BitVecCommand, Bitmap, BitmapCommand, BrightnessGrid, - BrightnessGridCommand, CharGridCommand, ClearCommand, CompressionCode, - Cp437GridCommand, FadeOutCommand, GlobalBrightnessCommand, Grid, GridMut, - HardResetCommand, Origin, TypedCommand, PIXEL_COUNT, PIXEL_WIDTH, - TILE_SIZE, + BinaryOperation, BitVecCommand, Bitmap, BitmapCommand, GlobalBrightnessCommand, + BrightnessGrid, BrightnessGridCommand, CharGridCommand, ClearCommand, + CompressionCode, Cp437GridCommand, FadeOutCommand, Grid, HardResetCommand, + Origin, TypedCommand, PIXEL_COUNT, PIXEL_WIDTH, TILE_SIZE, }; use std::{ ops::{BitAnd, BitOr, BitXor}, @@ -22,7 +21,6 @@ pub struct CommandExecutionContext<'t> { luma: &'t RwLock, cp437_font: Cp437Font, font_renderer: FontRenderer8x8, - experimental_null_char_handling: bool, } #[must_use] @@ -48,11 +46,11 @@ impl CommandExecute for BitmapCommand { fn execute(&self, context: &CommandExecutionContext) -> ExecutionResult { let Self { origin: - Origin { - x: offset_x, - y: offset_y, - .. - }, + Origin { + x: offset_x, + y: offset_y, + .. + }, bitmap: pixels, .. } = self; @@ -145,7 +143,7 @@ impl CommandExecute for Cp437GridCommand { bitmap: context.cp437_font[char_code].clone(), compression: CompressionCode::default(), } - .execute(context); + .execute(context); match execute_result { Success => {} Failure => { @@ -194,30 +192,16 @@ impl CommandExecute for CharGridCommand { for char_y in 0usize..grid.height() { for char_x in 0usize..grid.width() { let char = grid.get(char_x, char_y); - let mut bitmap_window = { - let pixel_x = (char_x + x) * TILE_SIZE; - let pixel_y = (char_y + y) * TILE_SIZE; - display - .window_mut( - pixel_x..pixel_x + TILE_SIZE, - pixel_y..pixel_y + TILE_SIZE, - ) - .unwrap() - }; - - if char == '\0' { - if context.experimental_null_char_handling { - trace!("skipping {char:?}"); - } else { - bitmap_window.fill(false); - } - continue; - } - trace!("drawing {char}"); - if let Err(e) = - context.font_renderer.render(char, &mut bitmap_window) - { + + let tile_x = char_x + x; + let tile_y = char_y + y; + + if let Err(e) = context.font_renderer.render( + char, + &mut display, + Origin::new(tile_x * TILE_SIZE, tile_y * TILE_SIZE), + ) { error!( "stopping drawing text because char draw failed: {e}" ); @@ -267,14 +251,12 @@ impl<'t> CommandExecutionContext<'t> { display: &'t RwLock, luma: &'t RwLock, font_renderer: FontRenderer8x8, - experimental_null_char_handling: bool, ) -> Self { CommandExecutionContext { display, luma, font_renderer, cp437_font: Cp437Font::default(), - experimental_null_char_handling, } } } diff --git a/src/font_renderer.rs b/src/font_renderer.rs index efe243f..d9f5fd7 100644 --- a/src/font_renderer.rs +++ b/src/font_renderer.rs @@ -12,11 +12,8 @@ use pathfinder_geometry::{ transform2d::Transform2F, vector::{vec2f, vec2i}, }; -use servicepoint::{Bitmap, GridMut, WindowMut, TILE_SIZE}; -use std::{ - collections::HashMap, - sync::{Mutex, MutexGuard}, -}; +use servicepoint::{Bitmap, Grid, Origin, Pixels, TILE_SIZE}; +use std::sync::{Mutex, MutexGuard}; #[derive(Debug)] struct SendFont(Font); @@ -35,7 +32,6 @@ pub struct FontRenderer8x8 { font: SendFont, canvas: Mutex, fallback_char: Option, - cache: Mutex>, } #[derive(Debug, thiserror::Error)] @@ -60,7 +56,6 @@ impl FontRenderer8x8 { font: SendFont(font), fallback_char, canvas: Mutex::new(canvas), - cache: Mutex::new(HashMap::new()), } } @@ -79,13 +74,9 @@ impl FontRenderer8x8 { pub fn render( &self, char: char, - target: &mut WindowMut, + bitmap: &mut Bitmap, + offset: Origin, ) -> Result<(), RenderError> { - let cache = &mut *self.cache.lock().unwrap(); - if let Some(drawn_char) = cache.get(&char) { - target.deref_assign(drawn_char); - } - let glyph_id = self.get_glyph(char)?; let mut canvas = self.canvas.lock().unwrap(); @@ -100,21 +91,20 @@ impl FontRenderer8x8 { RasterizationOptions::Bilevel, )?; - let mut bitmap = Bitmap::new(TILE_SIZE, TILE_SIZE).unwrap(); - Self::copy_to_bitmap(canvas, &mut bitmap)?; - target.deref_assign(&bitmap); - cache.insert(char, bitmap); - Ok(()) + Self::copy_to_bitmap(canvas, bitmap, offset) } fn copy_to_bitmap( canvas: MutexGuard, bitmap: &mut Bitmap, + offset: Origin, ) -> Result<(), RenderError> { for y in 0..TILE_SIZE { for x in 0..TILE_SIZE { let canvas_val = canvas.pixels[x + y * TILE_SIZE] != 0; - if !bitmap.set_optional(x, y, canvas_val) { + let bitmap_x = offset.x + x; + let bitmap_y = offset.y + y; + if !bitmap.set_optional(bitmap_x, bitmap_y, canvas_val) { return Err(OutOfBounds(x, y)); } } diff --git a/src/gui.rs b/src/gui.rs index ad3fa26..e5f08d4 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -24,7 +24,6 @@ const PIXEL_HEIGHT_WITH_SPACERS: usize = PIXEL_HEIGHT + NUM_SPACERS * SPACER_HEIGHT; const OFF_COLOR: u32 = u32::from_ne_bytes([0u8, 0, 0, 0]); -const SPACER_COLOR: u32 = u32::from_ne_bytes([100u8, 100, 100, 0]); #[derive(Debug)] pub enum AppEvents { @@ -62,7 +61,7 @@ impl<'t> Gui<'t> { if self.options.spacers && tile_y != 0 { // cannot just frame.skip(PIXEL_WIDTH as usize * SPACER_HEIGHT as usize) because of typing for _ in 0..PIXEL_WIDTH * SPACER_HEIGHT { - *frame.next().unwrap() = SPACER_COLOR; + frame.next().unwrap(); } } diff --git a/src/main.rs b/src/main.rs index 0648b2d..06e0b28 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,12 +39,7 @@ fn main() { .font .map(FontRenderer8x8::from_name) .unwrap_or_else(FontRenderer8x8::default); - let context = CommandExecutionContext::new( - &display, - &luma, - font_renderer, - cli.experimental_null_char_handling, - ); + let context = CommandExecutionContext::new(&display, &luma, font_renderer); let mut udp_server = UdpServer::new( cli.bind, stop_udp_rx,