From 6b5fdca654e569d22339c50b7dcdd99418921f25 Mon Sep 17 00:00:00 2001 From: Vinzenz Schroeter Date: Fri, 10 May 2024 00:53:12 +0200 Subject: [PATCH] split out more files --- src/bit_vec.rs | 14 +++---- src/command.rs | 63 +++++++++++++++++++++++++++++++ src/connection.rs | 12 ++++-- src/lib.rs | 94 ++++------------------------------------------- src/main.rs | 4 +- src/packet.rs | 22 +++++++++++ src/pixel_grid.rs | 8 ++-- 7 files changed, 112 insertions(+), 105 deletions(-) create mode 100644 src/command.rs create mode 100644 src/packet.rs diff --git a/src/bit_vec.rs b/src/bit_vec.rs index 977f13c..881c5c4 100644 --- a/src/bit_vec.rs +++ b/src/bit_vec.rs @@ -1,17 +1,9 @@ -use crate::Packet; - /// A vector of bits #[derive(Debug)] pub struct BitVec { data: Vec, } -impl From for Packet { - fn from(value: BitVec) -> Self { - value.data - } -} - impl BitVec { pub fn new(size: usize) -> BitVec { assert_eq!(size % 8, 0); @@ -42,3 +34,9 @@ impl BitVec { return self.data[byte_index] & bit_mask != 0; } } + +impl Into> for BitVec { + fn into(self) -> Vec { + self.data + } +} diff --git a/src/command.rs b/src/command.rs new file mode 100644 index 0000000..e030679 --- /dev/null +++ b/src/command.rs @@ -0,0 +1,63 @@ +use crate::{BitVec, Header, Packet, PixelGrid, ToPacket}; + +/// A window +#[derive(Debug)] +pub struct Window(pub Origin, pub Size); + +/// An origin marks the top left position of the +/// data sent to the display. +/// A window +#[derive(Debug)] +pub struct Origin(pub u16, pub u16); + +/// Size defines the width and height of a window +/// A window +#[derive(Debug)] +pub struct Size(pub u16, pub u16); + +type Offset = u16; + +type Brightness = u8; + + +#[derive(Debug)] +pub enum Command { + Clear, + HardReset, + FadeOut, + CharBrightness(Window, Vec), + Brightness(Brightness), + BitmapLinear(Offset, BitVec), + BitmapLinearAnd(Offset, BitVec), + BitmapLinearOr(Offset, BitVec), + BitmapLinearXor(Offset, BitVec), + Cp437Data(Window, Vec), + BitmapLinearWin(Window, PixelGrid), +} + +fn offset_and_payload(command: u16, offset: Offset, payload: Vec) -> Packet { + Packet(Header(command, offset, payload.len() as u16, 0, 0), payload) +} + +fn window_and_payload(command: u16, window: Window, payload: Vec) -> Packet { + let Window(Origin(x, y), Size(w, h)) = window; + Packet(Header(command, x, y, w, h), payload.into()) +} + +impl ToPacket for Command { + fn to_packet(self) -> Packet { + match self { + Command::Clear => Packet(Header(0x0002, 0x0000, 0x0000, 0x0000, 0x0000), vec!()), + Command::CharBrightness(window, payload) => window_and_payload(0x0005, window, payload), + Command::Brightness(brightness) => Packet(Header(0x0007, 0x00000, 0x0000, 0x0000, 0x0000), vec!(brightness)), + Command::HardReset => Packet(Header(0x000b, 0x0000, 0x0000, 0x0000, 0x0000), vec!()), + Command::FadeOut => Packet(Header(0x000d, 0x0000, 0x0000, 0x0000, 0x0000), vec!()), + Command::BitmapLinear(offset, bits) => offset_and_payload(0x0012, offset, bits.into()), + Command::BitmapLinearWin(window, pixels) => window_and_payload(0x0013, window, pixels.into()), + Command::BitmapLinearAnd(offset, bits) => offset_and_payload(0x0014, offset, bits.into()), + Command::BitmapLinearOr(offset, bits) => offset_and_payload(0x0015, offset, bits.into()), + Command::BitmapLinearXor(offset, bits) => offset_and_payload(0x0016, offset, bits.into()), + Command::Cp437Data(window, payload) => window_and_payload(0x0003, window, payload), + } + } +} diff --git a/src/connection.rs b/src/connection.rs index 5f77425..92b8dfc 100644 --- a/src/connection.rs +++ b/src/connection.rs @@ -1,10 +1,14 @@ use std::net::{ToSocketAddrs, UdpSocket}; -use crate::{Command, Packet}; +use crate::{Packet}; pub struct Connection { socket: UdpSocket, } +pub trait ToPacket { + fn to_packet(self) -> Packet; +} + impl Connection { /// Open a new UDP socket and create a display instance pub fn open(addr: impl ToSocketAddrs) -> std::io::Result { @@ -14,9 +18,9 @@ impl Connection { } /// Send a command to the display - pub fn send(&self, command: Command) -> std::io::Result<()> { - let packet: Packet = command.into(); - self.socket.send(&packet)?; + pub fn send(&self, packet: impl ToPacket) -> std::io::Result<()> { + let packet = packet.to_packet(); + self.socket.send(&*packet.to_bytes())?; Ok(()) } } diff --git a/src/lib.rs b/src/lib.rs index 3ca9bc7..55ba617 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,98 +1,18 @@ mod connection; mod pixel_grid; mod bit_vec; +mod packet; +mod command; -pub use crate::connection::*; -pub use crate::pixel_grid::*; -pub use crate::bit_vec::*; +pub use crate::connection::{Connection, ToPacket}; +pub use crate::pixel_grid::{PixelGrid}; +pub use crate::bit_vec::{BitVec}; +pub use crate::packet::{Packet, Header, Payload}; +pub use crate::command::{Command, Size, Origin, Window}; pub const TILE_SIZE: u16 = 8; pub const TILE_WIDTH: u16 = 56; pub const TILE_HEIGHT: u16 = 20; pub const PIXEL_WIDTH: u16 = TILE_WIDTH * TILE_SIZE; pub const PIXEL_HEIGHT: u16 = TILE_HEIGHT * TILE_SIZE; - pub const PIXEL_COUNT: usize = PIXEL_WIDTH as usize * PIXEL_HEIGHT as usize; - -/// A window -#[derive(Debug)] -pub struct Window(pub Origin, pub Size); - -/// An origin marks the top left position of the -/// data sent to the display. -/// A window -#[derive(Debug)] -pub struct Origin(pub u16, pub u16); - -/// Size defines the width and height of a window -/// A window -#[derive(Debug)] -pub struct Size(pub u16, pub u16); - -type Offset = u16; - -type Brightness = u8; - -type Packet = Vec; - -#[derive(Debug)] -pub enum Command { - Clear, - HardReset, - FadeOut, - CharBrightness(Window, Vec), - Brightness(Brightness), - BitmapLinear(Offset, BitVec), - BitmapLinearAnd(Offset, BitVec), - BitmapLinearOr(Offset, BitVec), - BitmapLinearXor(Offset, BitVec), - Cp437Data(Window, Vec), - BitmapLinearWin(Window, PixelGrid), -} - -fn offset_and_payload(command: u16, offset: Offset, payload: Vec) -> Packet { - let mut packet = vec!(0u8; 10 + payload.len()); - - packet[0..=1].copy_from_slice(&u16::to_be_bytes(command)); - packet[2..=3].copy_from_slice(&u16::to_be_bytes(offset)); - packet[4..=5].copy_from_slice(&u16::to_be_bytes(payload.len() as u16)); - packet[6..=7].copy_from_slice(&[0x00, 0x00]); // subcommand 0 => no compression - packet[8..=9].copy_from_slice(&[0x00, 0x00]); // reserved - - packet[10..].copy_from_slice(&*payload); - - packet -} - -fn window_and_payload(command: u16, window: Window, payload: Vec) -> Packet { - let Window(Origin(x, y), Size(w, h)) = window; - - let mut packet = vec!(0u8; 10 + payload.len()); - packet[0..=1].copy_from_slice(&u16::to_be_bytes(command)); - packet[2..=3].copy_from_slice(&u16::to_be_bytes(x)); - packet[4..=5].copy_from_slice(&u16::to_be_bytes(y)); - packet[6..=7].copy_from_slice(&u16::to_be_bytes(w)); - packet[8..=9].copy_from_slice(&u16::to_be_bytes(h)); - - packet[10..].copy_from_slice(&*payload); - - packet -} - -impl From for Packet { - fn from(value: Command) -> Self { - match value { - Command::Clear => vec!(0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - Command::CharBrightness(window, payload) => window_and_payload(0x0005, window, payload), - Command::Brightness(brightness) => vec!(0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, brightness), - Command::HardReset => vec!(0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - Command::FadeOut => vec!(0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), - Command::BitmapLinear(offset, payload) => offset_and_payload(0x0012, offset, payload.into()), - Command::BitmapLinearWin(window, payload) => window_and_payload(0x0013, window, payload.into()), - Command::BitmapLinearAnd(offset, payload) => offset_and_payload(0x0014, offset, payload.into()), - Command::BitmapLinearOr(offset, payload) => offset_and_payload(0x0015, offset, payload.into()), - Command::BitmapLinearXor(offset, payload) => offset_and_payload(0x0016, offset, payload.into()), - Command::Cp437Data(window, payload) => window_and_payload(0x0003, window, payload), - } - } -} diff --git a/src/main.rs b/src/main.rs index 6a7d5bf..e76a082 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,8 +13,8 @@ fn main() { for x_offset in 0..usize::MAX { let mut pixels = PixelGrid::new(PIXEL_WIDTH as usize, PIXEL_HEIGHT as usize); for y in 0..PIXEL_HEIGHT as usize { - for x_add in 0..=y%8 { - pixels.set((y + x_offset +x_add) % PIXEL_WIDTH as usize, y, true); + for x_add in 0..=y % 8 { + pixels.set((y + x_offset + x_add) % PIXEL_WIDTH as usize, y, true); } } diff --git a/src/packet.rs b/src/packet.rs new file mode 100644 index 0000000..8473dba --- /dev/null +++ b/src/packet.rs @@ -0,0 +1,22 @@ +pub struct Header(pub u16, pub u16, pub u16, pub u16, pub u16); + +pub type Payload = Vec; + +pub struct Packet(pub Header, pub Payload); + +impl Packet { + pub fn to_bytes(&self) -> Vec { + let Packet(Header(mode, a, b, c, d), payload) = self; + + let mut packet = vec!(0u8; 10 + payload.len()); + packet[0..=1].copy_from_slice(&u16::to_be_bytes(*mode)); + packet[2..=3].copy_from_slice(&u16::to_be_bytes(*a)); + packet[4..=5].copy_from_slice(&u16::to_be_bytes(*b)); + packet[6..=7].copy_from_slice(&u16::to_be_bytes(*c)); + packet[8..=9].copy_from_slice(&u16::to_be_bytes(*d)); + + packet[10..].copy_from_slice(&*payload); + + return packet; + } +} \ No newline at end of file diff --git a/src/pixel_grid.rs b/src/pixel_grid.rs index 2a30c5b..2c7a958 100644 --- a/src/pixel_grid.rs +++ b/src/pixel_grid.rs @@ -1,4 +1,4 @@ -use crate::{BitVec, Packet}; +use crate::{BitVec}; #[derive(Debug)] pub struct PixelGrid { @@ -27,8 +27,8 @@ impl PixelGrid { } } -impl From for Packet { - fn from(value: PixelGrid) -> Self { - value.bit_vec.into() +impl Into> for PixelGrid { + fn into(self) -> Vec { + self.bit_vec.into() } }