add new compression commands to BitmapLinearWin
This commit is contained in:
		
							parent
							
								
									6834bb084b
								
							
						
					
					
						commit
						da4df32878
					
				
					 8 changed files with 84 additions and 60 deletions
				
			
		|  | @ -4,7 +4,7 @@ use std::time::Duration; | |||
| use clap::Parser; | ||||
| use rand::{distributions, Rng}; | ||||
| 
 | ||||
| use servicepoint2::{Command, Connection, Origin, PixelGrid}; | ||||
| use servicepoint2::{Command, CompressionCode, Connection, Origin, PixelGrid}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  | @ -23,7 +23,7 @@ fn main() { | |||
| 
 | ||||
|     loop { | ||||
|         connection | ||||
|             .send(Command::BitmapLinearWin(Origin::top_left(), field.clone()).into()) | ||||
|             .send(Command::BitmapLinearWin(Origin::top_left(), field.clone(), CompressionCode::Bzip2).into()) | ||||
|             .expect("could not send"); | ||||
|         thread::sleep(Duration::from_millis(30)); | ||||
|         field = iteration(field); | ||||
|  | @ -36,6 +36,7 @@ fn iteration(field: PixelGrid) -> PixelGrid { | |||
|         for y in 0..field.height { | ||||
|             let old_state = field.get(x, y); | ||||
|             let neighbors = count_neighbors(&field, x as i32, y as i32); | ||||
| 
 | ||||
|             let new_state = matches!((old_state, neighbors), (true, 2) | (true, 3) | (false, 3)); | ||||
|             next.set(x, y, new_state); | ||||
|         } | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ use std::time::Duration; | |||
| 
 | ||||
| use clap::Parser; | ||||
| 
 | ||||
| use servicepoint2::{Command, Connection, Origin, PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; | ||||
| use servicepoint2::{Command, CompressionCode, Connection, Origin, PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  | @ -24,7 +24,7 @@ fn main() { | |||
|             pixels.set((y + x_offset) % PIXEL_WIDTH as usize, y, true); | ||||
|         } | ||||
|         connection | ||||
|             .send(Command::BitmapLinearWin(Origin::top_left(), pixels.clone()).into()) | ||||
|             .send(Command::BitmapLinearWin(Origin::top_left(), pixels.clone(), CompressionCode::Lzma).into()) | ||||
|             .unwrap(); | ||||
|         thread::sleep(Duration::from_millis(14)); | ||||
|     } | ||||
|  |  | |||
|  | @ -4,9 +4,7 @@ use clap::Parser; | |||
| use rand::Rng; | ||||
| 
 | ||||
| use servicepoint2::Command::{BitmapLinearWin, Brightness, CharBrightness}; | ||||
| use servicepoint2::{ | ||||
|     ByteGrid, Connection, Origin, PixelGrid, TILE_HEIGHT, TILE_WIDTH, | ||||
| }; | ||||
| use servicepoint2::{ByteGrid, CompressionCode, Connection, Origin, PixelGrid, TILE_HEIGHT, TILE_WIDTH}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  | @ -30,7 +28,7 @@ fn main() { | |||
|         let mut filled_grid = PixelGrid::max_sized(); | ||||
|         filled_grid.fill(true); | ||||
|         connection | ||||
|             .send(BitmapLinearWin(Origin::top_left(), filled_grid).into()) | ||||
|             .send(BitmapLinearWin(Origin::top_left(), filled_grid, CompressionCode::Lzma).into()) | ||||
|             .unwrap(); | ||||
|     } | ||||
| 
 | ||||
|  |  | |||
|  | @ -3,7 +3,7 @@ use std::time::Duration; | |||
| 
 | ||||
| use clap::Parser; | ||||
| 
 | ||||
| use servicepoint2::{BitVec, Command, CompressionCode, Connection, Origin, PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; | ||||
| use servicepoint2::{BitVec, Command, CompressionCode, Connection, PIXEL_HEIGHT, PIXEL_WIDTH, PixelGrid}; | ||||
| 
 | ||||
| #[derive(Parser, Debug)] | ||||
| struct Cli { | ||||
|  | @ -16,16 +16,10 @@ struct Cli { | |||
| fn main() { | ||||
|     env_logger::init(); | ||||
|     let cli = Cli::parse(); | ||||
|     let sleep_duration = Duration::from_millis(cli.time / PIXEL_WIDTH as u64); | ||||
| 
 | ||||
|     let connection = Connection::open(cli.destination).unwrap(); | ||||
| 
 | ||||
|     let mut buf = PixelGrid::max_sized(); | ||||
|     buf.fill(true); | ||||
|     connection.send(Command::BitmapLinearWin(Origin(0, 0), buf).into()) | ||||
|         .expect("send failed"); | ||||
| 
 | ||||
|     let sleep_duration = Duration::from_millis(cli.time / PIXEL_WIDTH as u64); | ||||
| 
 | ||||
|     let mut enabled_pixels = | ||||
|         PixelGrid::new(PIXEL_WIDTH as usize, PIXEL_HEIGHT as usize); | ||||
|     enabled_pixels.fill(true); | ||||
|  |  | |||
|  | @ -284,7 +284,8 @@ struct sp2_Command *sp2_command_bitmap_linear_or(sp2_Offset offset, | |||
|  */ | ||||
| struct sp2_Command *sp2_command_bitmap_linear_win(uint16_t x, | ||||
|                                                   uint16_t y, | ||||
|                                                   struct sp2_PixelGrid *byte_grid); | ||||
|                                                   struct sp2_PixelGrid *byte_grid, | ||||
|                                                   sp2_CompressionCode compression_code); | ||||
| 
 | ||||
| /**
 | ||||
|  * Allocates a new `Command::BitmapLinearXor` instance. | ||||
|  |  | |||
|  | @ -149,7 +149,7 @@ namespace ServicePoint2.BindGen | |||
| 
 | ||||
|         /// <summary>Allocates a new `Command::BitmapLinearWin` instance. The passed `PixelGrid` gets deallocated in the process.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_bitmap_linear_win", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|         public static extern Command* sp2_command_bitmap_linear_win(ushort x, ushort y, PixelGrid* byte_grid); | ||||
|         public static extern Command* sp2_command_bitmap_linear_win(ushort x, ushort y, PixelGrid* byte_grid, CompressionCode compression_code); | ||||
| 
 | ||||
|         /// <summary>Deallocates a `Command`. Note that connection_send does this implicitly, so you only need to do this if you use the library for parsing commands.</summary> | ||||
|         [DllImport(__DllName, EntryPoint = "sp2_command_dealloc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)] | ||||
|  |  | |||
|  | @ -1,7 +1,4 @@ | |||
| use crate::{ | ||||
|     BitVec, ByteGrid, CompressionCode, Header, Packet, PixelGrid, | ||||
|     TILE_SIZE, | ||||
| }; | ||||
| use crate::{BitVec, ByteGrid, CompressionCode, Header, Packet, PixelGrid, TILE_SIZE}; | ||||
| use crate::command_code::CommandCode; | ||||
| use crate::compression::{into_compressed, into_decompressed}; | ||||
| 
 | ||||
|  | @ -56,7 +53,7 @@ pub enum Command { | |||
|     /// Show text on the screen. Note that the byte data has to be CP437 encoded.
 | ||||
|     Cp437Data(Origin, ByteGrid), | ||||
|     /// Sets a window of pixels to the specified values
 | ||||
|     BitmapLinearWin(Origin, PixelGrid), | ||||
|     BitmapLinearWin(Origin, PixelGrid, CompressionCode), | ||||
| } | ||||
| 
 | ||||
| impl From<Command> for Packet { | ||||
|  | @ -85,18 +82,25 @@ impl From<Command> for Packet { | |||
|                 ), | ||||
|                 vec![brightness], | ||||
|             ), | ||||
|             Command::BitmapLinearWin(Origin(pixel_x, pixel_y), pixels) => { | ||||
|             Command::BitmapLinearWin(Origin(pixel_x, pixel_y), pixels, compression) => { | ||||
|                 debug_assert_eq!(pixel_x % 8, 0); | ||||
|                 debug_assert_eq!(pixels.width % 8, 0); | ||||
| 
 | ||||
|                 let tile_x = pixel_x / TILE_SIZE; | ||||
|                 let tile_w = pixels.width as u16 / TILE_SIZE; | ||||
|                 let pixel_h = pixels.height as u16; | ||||
|                 let payload = into_compressed(compression, pixels.into()); | ||||
|                 let command = match compression { | ||||
|                     CompressionCode::Uncompressed => CommandCode::BitmapLinearWinUncompressed, | ||||
|                     CompressionCode::Zlib => CommandCode::BitmapLinearWinZlib, | ||||
|                     CompressionCode::Bzip2 => CommandCode::BitmapLinearWinBzip2, | ||||
|                     CompressionCode::Lzma => CommandCode::BitmapLinearWinLzma, | ||||
|                     CompressionCode::Zstd => CommandCode::BitmapLinearWinZstd, | ||||
|                 }; | ||||
| 
 | ||||
|                 Packet( | ||||
|                     Header( | ||||
|                         CommandCode::BitmapLinearWin.into(), | ||||
|                         pixel_x / TILE_SIZE, | ||||
|                         pixel_y, | ||||
|                         pixels.width as u16 / TILE_SIZE, | ||||
|                         pixels.height as u16, | ||||
|                     ), | ||||
|                     pixels.into(), | ||||
|                     Header(command.into(), tile_x, pixel_y, tile_w, pixel_h), | ||||
|                     payload, | ||||
|                 ) | ||||
|             } | ||||
|             Command::BitmapLinear(offset, bits, compression) => { | ||||
|  | @ -160,8 +164,8 @@ impl TryFrom<Packet> for Command { | |||
|     type Error = TryFromPacketError; | ||||
| 
 | ||||
|     /// Try to interpret the `Packet` as one containing a `Command`
 | ||||
|     fn try_from(value: Packet) -> Result<Self, Self::Error> { | ||||
|         let Packet(Header(command_u16, a, b, c, d), _) = value; | ||||
|     fn try_from(packet: Packet) -> Result<Self, Self::Error> { | ||||
|         let Packet(Header(command_u16, a, b, c, d), _) = packet; | ||||
|         let command_code = match CommandCode::try_from(command_u16) { | ||||
|             Err(_) => { | ||||
|                 return Err(TryFromPacketError::InvalidCommand(command_u16)); | ||||
|  | @ -170,12 +174,12 @@ impl TryFrom<Packet> for Command { | |||
|         }; | ||||
| 
 | ||||
|         match command_code { | ||||
|             CommandCode::Clear => match check_command_only(value) { | ||||
|             CommandCode::Clear => match check_command_only(packet) { | ||||
|                 Some(err) => Err(err), | ||||
|                 None => Ok(Command::Clear), | ||||
|             }, | ||||
|             CommandCode::Brightness => { | ||||
|                 let Packet(header, payload) = value; | ||||
|                 let Packet(header, payload) = packet; | ||||
|                 if payload.len() != 1 { | ||||
|                     return Err(TryFromPacketError::UnexpectedPayloadSize( | ||||
|                         1, | ||||
|  | @ -190,23 +194,23 @@ impl TryFrom<Packet> for Command { | |||
|                     Ok(Command::Brightness(payload[0])) | ||||
|                 } | ||||
|             } | ||||
|             CommandCode::HardReset => match check_command_only(value) { | ||||
|             CommandCode::HardReset => match check_command_only(packet) { | ||||
|                 Some(err) => Err(err), | ||||
|                 None => Ok(Command::HardReset), | ||||
|             }, | ||||
|             CommandCode::FadeOut => match check_command_only(value) { | ||||
|             CommandCode::FadeOut => match check_command_only(packet) { | ||||
|                 Some(err) => Err(err), | ||||
|                 None => Ok(Command::FadeOut), | ||||
|             }, | ||||
|             CommandCode::Cp437Data => { | ||||
|                 let Packet(_, payload) = value; | ||||
|                 let Packet(_, payload) = packet; | ||||
|                 Ok(Command::Cp437Data( | ||||
|                     Origin(a, b), | ||||
|                     ByteGrid::load(c as usize, d as usize, &payload), | ||||
|                 )) | ||||
|             } | ||||
|             CommandCode::CharBrightness => { | ||||
|                 let Packet(_, payload) = value; | ||||
|                 let Packet(_, payload) = packet; | ||||
|                 Ok(Command::CharBrightness( | ||||
|                     Origin(a, b), | ||||
|                     ByteGrid::load(c as usize, d as usize, &payload), | ||||
|  | @ -214,37 +218,60 @@ impl TryFrom<Packet> for Command { | |||
|             } | ||||
|             #[allow(deprecated)] | ||||
|             CommandCode::BitmapLegacy => Ok(Command::BitmapLegacy), | ||||
|             CommandCode::BitmapLinearWin => { | ||||
|                 let Packet(_, payload) = value; | ||||
|                 Ok(Command::BitmapLinearWin( | ||||
|                     Origin(a * TILE_SIZE, b), | ||||
|                     PixelGrid::load( | ||||
|                         c as usize * TILE_SIZE as usize, | ||||
|                         d as usize, | ||||
|                         &payload, | ||||
|                     ), | ||||
|                 )) | ||||
|             } | ||||
|             CommandCode::BitmapLinear => { | ||||
|                 let (vec, compression) = packet_into_linear_bitmap(value)?; | ||||
|                 let (vec, compression) = packet_into_linear_bitmap(packet)?; | ||||
|                 Ok(Command::BitmapLinear(a, vec, compression)) | ||||
|             } | ||||
|             CommandCode::BitmapLinearAnd => { | ||||
|                 let (vec, compression) = packet_into_linear_bitmap(value)?; | ||||
|                 let (vec, compression) = packet_into_linear_bitmap(packet)?; | ||||
|                 Ok(Command::BitmapLinearAnd(a, vec, compression)) | ||||
|             } | ||||
|             CommandCode::BitmapLinearOr => { | ||||
|                 let (vec, compression) = packet_into_linear_bitmap(value)?; | ||||
|                 let (vec, compression) = packet_into_linear_bitmap(packet)?; | ||||
|                 Ok(Command::BitmapLinearOr(a, vec, compression)) | ||||
|             } | ||||
|             CommandCode::BitmapLinearXor => { | ||||
|                 let (vec, compression) = packet_into_linear_bitmap(value)?; | ||||
|                 let (vec, compression) = packet_into_linear_bitmap(packet)?; | ||||
|                 Ok(Command::BitmapLinearXor(a, vec, compression)) | ||||
|             } | ||||
|             CommandCode::BitmapLinearWinUncompressed => { | ||||
|                 packet_into_bitmap_win(packet, CompressionCode::Uncompressed) | ||||
|             } | ||||
|             CommandCode::BitmapLinearWinZlib => { | ||||
|                 packet_into_bitmap_win(packet, CompressionCode::Zlib) | ||||
|             } | ||||
|             CommandCode::BitmapLinearWinBzip2 => { | ||||
|                 packet_into_bitmap_win(packet, CompressionCode::Bzip2) | ||||
|             } | ||||
|             CommandCode::BitmapLinearWinLzma => { | ||||
|                 packet_into_bitmap_win(packet, CompressionCode::Lzma) | ||||
|             } | ||||
|             CommandCode::BitmapLinearWinZstd => { | ||||
|                 packet_into_bitmap_win(packet, CompressionCode::Zstd) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn packet_into_bitmap_win(packet: Packet, compression: CompressionCode) -> Result<Command, TryFromPacketError> { | ||||
|     let Packet(Header(_, tiles_x, pixels_y, tile_w, pixel_h), payload) = packet; | ||||
| 
 | ||||
|     let payload = match into_decompressed(compression, payload) { | ||||
|         None => return Err(TryFromPacketError::DecompressionFailed), | ||||
|         Some(decompressed) => decompressed, | ||||
|     }; | ||||
| 
 | ||||
|     Ok(Command::BitmapLinearWin( | ||||
|         Origin(tiles_x * TILE_SIZE, pixels_y), | ||||
|         PixelGrid::load( | ||||
|             tile_w as usize * TILE_SIZE as usize, | ||||
|             pixel_h as usize, | ||||
|             &payload, | ||||
|         ), | ||||
|         CompressionCode::Uncompressed, | ||||
|     )) | ||||
| } | ||||
| 
 | ||||
| /// Helper method for BitMapLinear*-Commands into Packet
 | ||||
| fn bitmap_linear_into_packet( | ||||
|     command: CommandCode, | ||||
|  | @ -315,7 +342,6 @@ pub mod c_api | |||
| 
 | ||||
|     use crate::{BitVec, Brightness, ByteGrid, Command, CompressionCode, Offset, Origin, Packet, PixelGrid}; | ||||
| 
 | ||||
| 
 | ||||
|     /// Tries to turn a `Packet` into a `Command`. The packet is gets deallocated in the process.
 | ||||
|     ///
 | ||||
|     /// Returns: pointer to command or NULL
 | ||||
|  | @ -409,9 +435,9 @@ pub mod c_api | |||
|     /// Allocates a new `Command::BitmapLinearWin` instance.
 | ||||
|     /// The passed `PixelGrid` gets deallocated in the process.
 | ||||
|     #[no_mangle] | ||||
|     pub unsafe extern "C" fn sp2_command_bitmap_linear_win(x: u16, y: u16, byte_grid: *mut PixelGrid) -> *mut Command { | ||||
|     pub unsafe extern "C" fn sp2_command_bitmap_linear_win(x: u16, y: u16, byte_grid: *mut PixelGrid, compression_code: CompressionCode) -> *mut Command { | ||||
|         let byte_grid = *Box::from_raw(byte_grid); | ||||
|         Box::into_raw(Box::new(Command::BitmapLinearWin(Origin(x, y), byte_grid))) | ||||
|         Box::into_raw(Box::new(Command::BitmapLinearWin(Origin(x, y), byte_grid, compression_code))) | ||||
|     } | ||||
| 
 | ||||
|     /// Deallocates a `Command`. Note that connection_send does this implicitly, so you only need
 | ||||
|  |  | |||
|  | @ -11,10 +11,14 @@ pub(crate) enum CommandCode { | |||
|     #[deprecated] | ||||
|     BitmapLegacy = 0x0010, | ||||
|     BitmapLinear = 0x0012, | ||||
|     BitmapLinearWin = 0x0013, | ||||
|     BitmapLinearWinUncompressed = 0x0013, | ||||
|     BitmapLinearAnd = 0x0014, | ||||
|     BitmapLinearOr = 0x0015, | ||||
|     BitmapLinearXor = 0x0016, | ||||
|     BitmapLinearWinZlib = 0x0017, | ||||
|     BitmapLinearWinBzip2 = 0x0018, | ||||
|     BitmapLinearWinLzma = 0x0019, | ||||
|     BitmapLinearWinZstd = 0x001A, | ||||
| } | ||||
| 
 | ||||
| impl From<CommandCode> for u16 { | ||||
|  | @ -41,7 +45,7 @@ impl TryFrom<u16> for CommandCode { | |||
|             #[allow(deprecated)] | ||||
|             value if value == BitmapLegacy as u16 => Ok(BitmapLegacy), | ||||
|             value if value == BitmapLinear as u16 => Ok(BitmapLinear), | ||||
|             value if value == BitmapLinearWin as u16 => Ok(BitmapLinearWin), | ||||
|             value if value == BitmapLinearWinUncompressed as u16 => Ok(BitmapLinearWinUncompressed), | ||||
|             value if value == BitmapLinearAnd as u16 => Ok(BitmapLinearAnd), | ||||
|             value if value == BitmapLinearOr as u16 => Ok(BitmapLinearOr), | ||||
|             value if value == BitmapLinearXor as u16 => Ok(BitmapLinearXor), | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Vinzenz Schroeter
						Vinzenz Schroeter