From d00683719868ebccb4685fb7f59960c509ed55ee Mon Sep 17 00:00:00 2001 From: Yaseen Date: Wed, 21 Jan 2026 00:06:56 +0500 Subject: [PATCH 1/4] chore: add implementation planning for G635L/G835L support --- rog-anime/src/data.rs | 11 +- rog-anime/src/diagonal.rs | 48 ++++++ rog-anime/src/image.rs | 54 +++++- rog-anime/tests/g635l.rs | 240 ++++++++++++++++++++++++++ rog-anime/tests/g835l.rs | 240 ++++++++++++++++++++++++++ simulators/src/animatrix/map_g635l.rs | 70 ++++++++ simulators/src/animatrix/map_g835l.rs | 70 ++++++++ simulators/src/animatrix/mod.rs | 12 +- 8 files changed, 738 insertions(+), 7 deletions(-) create mode 100644 rog-anime/tests/g635l.rs create mode 100644 rog-anime/tests/g835l.rs create mode 100644 simulators/src/animatrix/map_g635l.rs create mode 100644 simulators/src/animatrix/map_g835l.rs diff --git a/rog-anime/src/data.rs b/rog-anime/src/data.rs index 1389fe7b..45a9d15b 100644 --- a/rog-anime/src/data.rs +++ b/rog-anime/src/data.rs @@ -100,8 +100,10 @@ impl AnimeType { AnimeType::GA402 } else if board_name.contains("GU604V") { AnimeType::GU604 - } else if board_name.contains("G635L") || board_name.contains("G635L") { + } else if board_name.contains("G635L") { AnimeType::G635L + } else if board_name.contains("G835L") { + AnimeType::G835L } else { AnimeType::Unsupported } @@ -111,7 +113,9 @@ impl AnimeType { pub fn width(&self) -> usize { match self { AnimeType::GU604 => 70, - AnimeType::G835L => 74, + // TODO: Find G635L W*H + // AnimeType::G635L => 68 + AnimeType::G835L => 68, _ => 74, } } @@ -121,7 +125,8 @@ impl AnimeType { match self { AnimeType::GA401 => 36, AnimeType::GU604 => 43, - AnimeType::G835L => 39, + // AnimeType::G635L => 34, + AnimeType::G835L => 34, _ => 39, } } diff --git a/rog-anime/src/diagonal.rs b/rog-anime/src/diagonal.rs index a71f9f99..4418ae90 100644 --- a/rog-anime/src/diagonal.rs +++ b/rog-anime/src/diagonal.rs @@ -44,6 +44,8 @@ impl AnimeDiagonal { /// Generate the base image from inputs. The result can be displayed as is /// or updated via scale, position, or angle then displayed again after /// `update()`. + /// + /// TODO: G835L and G635L only supports grayscale #[inline] pub fn from_png( path: &Path, @@ -381,4 +383,50 @@ impl AnimeDiagonal { AnimeDataBuffer::from_vec(crate::AnimeType::GA402, buf) } + + // TODO: Implement `to_g635l_packets` and `to_g835l_packets` functions + // IMPORTANT NOTE: G635L and G835L ONLY SUPPORT GRAYSCALE + // + // fn to_g835l_packets(buf: &[u8]) -> Result { + // let mut buf = vec![0u8; AnimeType::GU604.data_length()]; + + // let mut start_index: usize = 0; + + // fn copy_slice( + // buf: &mut [u8], + // anime: &AnimeDiagonal, + // x: usize, + // y: usize, + // start_index: &mut usize, + // len: usize, + // ) { + // buf[*start_index..*start_index + len].copy_from_slice(&anime.get_row(x, y, len)); + // *start_index += len; + // } + + // let b = &mut buf; + // let a = &self; + + // copy_slice(b, a, 40, 0, &mut start_index, 21); + // copy_slice(b, a, 41, 0, &mut start_index, 21); + // copy_slice(b, a, 42, 0, &mut start_index, 20); + // copy_slice(b, a, 43, 0, &mut start_index, 20); + // copy_slice(b, a, 44, 0, &mut start_index, 19); + // copy_slice(b, a, 45, 0, &mut start_index, 19); + // copy_slice(b, a, 46, 0, &mut start_index, 18); + // copy_slice(b, a, 47, 0, &mut start_index, 18); + // copy_slice(b, a, 48, 0, &mut start_index, 17); + // copy_slice(b, a, 49, 0, &mut start_index, 17); + // copy_slice(b, a, 50, 0, &mut start_index, 16); + // copy_slice(b, a, 51, 0, &mut start_index, 16); + // copy_slice(b, a, 52, 0, &mut start_index, 15); + // copy_slice(b, a, 53, 0, &mut start_index, 15); + // copy_slice(b, a, 54, 0, &mut start_index, 14); + // copy_slice(b, a, 55, 0, &mut start_index, 14); + // copy_slice(b, a, 56, 0, &mut start_index, 13); + // copy_slice(b, a, 57, 0, &mut start_index, 13); + // copy_slice(b, a, 58, 0, &mut start_index, 12); + + // AnimeDataBuffer::from_vec(crate::AnimeType::G835L, buf) + // } } diff --git a/rog-anime/src/image.rs b/rog-anime/src/image.rs index fee51da7..8fd954fb 100644 --- a/rog-anime/src/image.rs +++ b/rog-anime/src/image.rs @@ -138,6 +138,10 @@ impl AnimeImage { match anime_type { AnimeType::GA401 => 0.3, AnimeType::GU604 => 0.28, + // TODO: Calculate correct values for G635L and G835L. + // Known values for G835L W*H is 34*68 + AnimeType::G635L => 0.28, + AnimeType::G835L => 0.28, _ => 0.283, } } @@ -162,6 +166,20 @@ impl AnimeImage { /// ^ ------+ /// first_x /// ``` + /// + /// TODO: add the cases for G635L and G835L + /// This is how it looks like, but calculation may be a bit more complex + /// ```text + /// |\ + /// | \ + /// | \ + /// | \ + /// \ \ + /// \ \ + /// \ \ + /// \ \ + /// \____\ + /// ``` fn first_x(anime_type: AnimeType, y: u32) -> u32 { match anime_type { AnimeType::GA401 => { @@ -221,6 +239,19 @@ impl AnimeImage { } 38 - Self::first_x(anime_type, y) + y % 2 } + // TODO: Implement this + // AnimeType::G635L => { + // if y <= 11 { + // return 34; + // } + // 39 - y / 2 + // } + // AnimeType::G635E => { + // if y <= 11 { + // return 34; + // } + // 39 - y / 2 + // } _ => { if y <= 11 { return 34; @@ -235,8 +266,10 @@ impl AnimeImage { match anime_type { // 33.0 = Longest row LED count (physical) plus half-pixel offset AnimeType::GA401 => (33.0 + 0.5) * Self::scale_x(anime_type), - AnimeType::GU604 => (38.0 + 0.5) * Self::scale_x(anime_type), + // TODO: Implement this + // AnimeType::G635L => (34.0 + 0.5) * Self::scale_x(anime_type), + // AnimeType::G835L => (34.0 + 0.5) * Self::scale_x(anime_type), _ => (35.0 + 0.5) * Self::scale_x(anime_type), } } @@ -246,6 +279,9 @@ impl AnimeImage { match anime_type { AnimeType::GA401 => 55, AnimeType::GU604 => 62, + // TODO: Implement this + // AnimeType::G635L => 68, + // AnimeType::G835L => 68, _ => 61, } } @@ -256,6 +292,11 @@ impl AnimeImage { // 54.0 = End column LED count (physical) plus one dead pixel AnimeType::GA401 => (54.0 + 1.0) * Self::scale_y(anime_type), AnimeType::GU604 => 62.0 * Self::scale_y(anime_type), + + // TODO: Implement this + // AnimeType::G635L => (34.0 + 0.5) * Self::scale_y(anime_type), + // AnimeType::G835L => (34.0 + 0.5) * Self::scale_y(anime_type), + // GA402 may not have dead pixels and require only the physical LED count _ => 61.0 * Self::scale_y(anime_type), } @@ -269,7 +310,18 @@ impl AnimeImage { 1 | 3 => 35, // Some rows are padded _ => 36 - y / 2, }, + + // TODO: Implement this + // AnimeType::G635L => match y { + + // }, + // AnimeType::G835L => match y { + + // }, + + // This seems redundant AnimeType::GU604 => AnimeImage::width(anime_type, y), + // GA402 does not have padding, equivalent to width _ => AnimeImage::width(anime_type, y), } diff --git a/rog-anime/tests/g635l.rs b/rog-anime/tests/g635l.rs new file mode 100644 index 00000000..bee0661b --- /dev/null +++ b/rog-anime/tests/g635l.rs @@ -0,0 +1,240 @@ +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use rog_anime::*; + + #[test] + fn g635l_image_edge_packet_check() { + let pkt0_check = [ + 0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + let pkt1_check = [ + 0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + + let mut matrix = AnimeImage::new( + Vec2::new(1.0, 1.0), + 0.0, + Vec2::default(), + 0.0, + vec![Pixel::default(); 1000], + 100, + AnimeType::G635L, + ) + .unwrap(); + matrix.edge_outline(); + let data = AnimeDataBuffer::try_from(&matrix).unwrap(); + let pkt = AnimePacketType::try_from(data).unwrap(); + + // print!("left: '["); + // for b in pkt[1] { + // print!("{b:#02x},"); + // } + // print!("]'"); + + assert_eq!(pkt[0], pkt0_check); + assert_eq!(pkt[1], pkt1_check); + } + + #[test] + fn g635l_diagonal_packet_check() { + let pkt0_check = [ + 0x5e, 0xc0, 0x02, 0x1, 0x00, 0x73, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + let pkt1_check = [ + 0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + // TODO: create a png file for G635L + path.push("tests/data/ga401-diagonal.png"); + + let matrix = AnimeDiagonal::from_png(&path, None, 255.0, AnimeType::G635L).unwrap(); + let data = matrix.into_data_buffer(AnimeType::G635L).unwrap(); + let pkt = AnimePacketType::try_from(data).unwrap(); + + assert_eq!(pkt[0], pkt0_check); + assert_eq!(pkt[1], pkt1_check); + } +} diff --git a/rog-anime/tests/g835l.rs b/rog-anime/tests/g835l.rs new file mode 100644 index 00000000..9c7701f1 --- /dev/null +++ b/rog-anime/tests/g835l.rs @@ -0,0 +1,240 @@ +#[cfg(test)] +mod tests { + use std::path::PathBuf; + + use rog_anime::*; + + #[test] + fn g835l_image_edge_packet_check() { + let pkt0_check = [ + 0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + let pkt1_check = [ + 0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + + let mut matrix = AnimeImage::new( + Vec2::new(1.0, 1.0), + 0.0, + Vec2::default(), + 0.0, + vec![Pixel::default(); 1000], + 100, + AnimeType::G835L, + ) + .unwrap(); + matrix.edge_outline(); + let data = AnimeDataBuffer::try_from(&matrix).unwrap(); + let pkt = AnimePacketType::try_from(data).unwrap(); + + // print!("left: '["); + // for b in pkt[1] { + // print!("{b:#02x},"); + // } + // print!("]'"); + + assert_eq!(pkt[0], pkt0_check); + assert_eq!(pkt[1], pkt1_check); + } + + #[test] + fn g835l_diagonal_packet_check() { + let pkt0_check = [ + 0x5e, 0xc0, 0x02, 0x1, 0x00, 0x73, 0x02, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + let pkt1_check = [ + 0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + + let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + // TODO: create a png file for G835L + path.push("tests/data/ga401-diagonal.png"); + + let matrix = AnimeDiagonal::from_png(&path, None, 255.0, AnimeType::G835L).unwrap(); + let data = matrix.into_data_buffer(AnimeType::G835L).unwrap(); + let pkt = AnimePacketType::try_from(data).unwrap(); + + assert_eq!(pkt[0], pkt0_check); + assert_eq!(pkt[1], pkt1_check); + } +} diff --git a/simulators/src/animatrix/map_g635l.rs b/simulators/src/animatrix/map_g635l.rs new file mode 100644 index 00000000..3615a79d --- /dev/null +++ b/simulators/src/animatrix/map_g635l.rs @@ -0,0 +1,70 @@ +use super::Row; + +// TODO: This is a placeholder for G635L map +pub const G635L: [Row; 63] = [ + Row(0x01, 7, 32, 0), + Row(0x01, 7 + 34, 32, 0), + Row(0x01, 7 + 68, 32, 0), + Row(0x01, 7 + 102, 32, 0), // 34 len + Row(0x01, 7 + 136, 32, 0), + Row(0x01, 7 + 170, 34, 0), + Row(0x01, 7 + 204, 34, 0), + Row(0x01, 7 + 238, 34, 0), + Row(0x01, 7 + 272, 34, 0), + Row(0x01, 7 + 306, 34, 0), + Row(0x01, 7 + 340, 34, 0), + Row(0x01, 7 + 374, 34, 0), + Row(0x01, 7 + 408, 33, 1), + Row(0x01, 7 + 441, 33, 1), + Row(0x01, 7 + 474, 32, 2), + Row(0x01, 7 + 506, 32, 2), + Row(0x01, 7 + 538, 31, 3), + Row(0x01, 7 + 569, 31, 3), + Row(0x01, 7 + 600, 28, 4), + // + Row(0x74, 7 + 1, 3, 28 + 4), // adds to end of previous + Row(0x74, 7 + 3, 30, 4), + Row(0x74, 7 + 33, 29, 5), + Row(0x74, 7 + 62, 29, 5), + Row(0x74, 7 + 91, 28, 6), + Row(0x74, 7 + 119, 28, 6), + Row(0x74, 7 + 147, 27, 7), + Row(0x74, 7 + 174, 27, 7), + Row(0x74, 7 + 202, 26, 9), + Row(0x74, 7 + 228, 26, 9), + Row(0x74, 7 + 254, 25, 10), + Row(0x74, 7 + 278, 25, 9), // WEIRD OFFSET + Row(0x74, 7 + 303, 24, 10), + Row(0x74, 7 + 327, 24, 10), + Row(0x74, 7 + 351, 23, 11), + Row(0x74, 7 + 374, 23, 11), + Row(0x74, 7 + 397, 22, 12), + Row(0x74, 7 + 419, 22, 12), + Row(0x74, 7 + 441, 21, 13), + Row(0x74, 7 + 462, 21, 13), + Row(0x74, 7 + 483, 20, 14), + Row(0x74, 7 + 503, 20, 14), + Row(0x74, 7 + 523, 19, 15), + Row(0x74, 7 + 542, 19, 15), + Row(0x74, 7 + 561, 18, 16), + Row(0x74, 7 + 579, 18, 16), + Row(0x74, 7 + 597, 17, 17), + Row(0x74, 7 + 614, 13, 17), + // + Row(0xe7, 7 + 1, 4, 13 + 18), // adds to end of previous + Row(0xe7, 7 + 4, 16, 18), + Row(0xe7, 7 + 20, 16, 18), + Row(0xe7, 7 + 36, 15, 19), + Row(0xe7, 7 + 51, 15, 19), + Row(0xe7, 7 + 66, 14, 20), + Row(0xe7, 7 + 80, 12, 20), // too long? 14 + Row(0xe7, 7 + 94, 13, 21), + Row(0xe7, 7 + 107, 13, 21), + Row(0xe7, 7 + 120, 12, 12), // Actual display end + Row(0xe7, 7 + 132, 12, 22), + Row(0xe7, 7 + 144, 11, 23), + Row(0xe7, 7 + 155, 11, 23), + Row(0xe7, 7 + 166, 10, 24), + Row(0xe7, 7 + 176, 10, 24), + Row(0xe7, 7 + 186, 9, 25), +]; diff --git a/simulators/src/animatrix/map_g835l.rs b/simulators/src/animatrix/map_g835l.rs new file mode 100644 index 00000000..8348c0a2 --- /dev/null +++ b/simulators/src/animatrix/map_g835l.rs @@ -0,0 +1,70 @@ +use super::Row; + +// TODO: This is a placeholder for G835L map +pub const G835L: [Row; 63] = [ + Row(0x01, 7, 32, 0), + Row(0x01, 7 + 34, 32, 0), + Row(0x01, 7 + 68, 32, 0), + Row(0x01, 7 + 102, 32, 0), // 34 len + Row(0x01, 7 + 136, 32, 0), + Row(0x01, 7 + 170, 34, 0), + Row(0x01, 7 + 204, 34, 0), + Row(0x01, 7 + 238, 34, 0), + Row(0x01, 7 + 272, 34, 0), + Row(0x01, 7 + 306, 34, 0), + Row(0x01, 7 + 340, 34, 0), + Row(0x01, 7 + 374, 34, 0), + Row(0x01, 7 + 408, 33, 1), + Row(0x01, 7 + 441, 33, 1), + Row(0x01, 7 + 474, 32, 2), + Row(0x01, 7 + 506, 32, 2), + Row(0x01, 7 + 538, 31, 3), + Row(0x01, 7 + 569, 31, 3), + Row(0x01, 7 + 600, 28, 4), + // + Row(0x74, 7 + 1, 3, 28 + 4), // adds to end of previous + Row(0x74, 7 + 3, 30, 4), + Row(0x74, 7 + 33, 29, 5), + Row(0x74, 7 + 62, 29, 5), + Row(0x74, 7 + 91, 28, 6), + Row(0x74, 7 + 119, 28, 6), + Row(0x74, 7 + 147, 27, 7), + Row(0x74, 7 + 174, 27, 7), + Row(0x74, 7 + 202, 26, 9), + Row(0x74, 7 + 228, 26, 9), + Row(0x74, 7 + 254, 25, 10), + Row(0x74, 7 + 278, 25, 9), // WEIRD OFFSET + Row(0x74, 7 + 303, 24, 10), + Row(0x74, 7 + 327, 24, 10), + Row(0x74, 7 + 351, 23, 11), + Row(0x74, 7 + 374, 23, 11), + Row(0x74, 7 + 397, 22, 12), + Row(0x74, 7 + 419, 22, 12), + Row(0x74, 7 + 441, 21, 13), + Row(0x74, 7 + 462, 21, 13), + Row(0x74, 7 + 483, 20, 14), + Row(0x74, 7 + 503, 20, 14), + Row(0x74, 7 + 523, 19, 15), + Row(0x74, 7 + 542, 19, 15), + Row(0x74, 7 + 561, 18, 16), + Row(0x74, 7 + 579, 18, 16), + Row(0x74, 7 + 597, 17, 17), + Row(0x74, 7 + 614, 13, 17), + // + Row(0xe7, 7 + 1, 4, 13 + 18), // adds to end of previous + Row(0xe7, 7 + 4, 16, 18), + Row(0xe7, 7 + 20, 16, 18), + Row(0xe7, 7 + 36, 15, 19), + Row(0xe7, 7 + 51, 15, 19), + Row(0xe7, 7 + 66, 14, 20), + Row(0xe7, 7 + 80, 12, 20), // too long? 14 + Row(0xe7, 7 + 94, 13, 21), + Row(0xe7, 7 + 107, 13, 21), + Row(0xe7, 7 + 120, 12, 12), // Actual display end + Row(0xe7, 7 + 132, 12, 22), + Row(0xe7, 7 + 144, 11, 23), + Row(0xe7, 7 + 155, 11, 23), + Row(0xe7, 7 + 166, 10, 24), + Row(0xe7, 7 + 176, 10, 24), + Row(0xe7, 7 + 186, 9, 25), +]; diff --git a/simulators/src/animatrix/mod.rs b/simulators/src/animatrix/mod.rs index efc8c9b2..f8daa4ea 100644 --- a/simulators/src/animatrix/mod.rs +++ b/simulators/src/animatrix/mod.rs @@ -1,9 +1,13 @@ use rog_anime::AnimeType; +use self::map_g635l::G635L; +use self::map_g835l::G835L; use self::map_ga401::GA401; use self::map_ga402::GA402; use self::map_gu604::GU604; +mod map_g635l; +mod map_g835l; mod map_ga401; mod map_ga402; mod map_gu604; @@ -39,6 +43,8 @@ pub struct AniMatrix { impl AniMatrix { pub fn new(model: AnimeType) -> Self { let led_shape = match model { + // TODO: Verify how this reacts on G635L and G835L + // These are all doing the same thing. Can be simplified AnimeType::GA401 => LedShape { vertical: 2, horizontal: 5, @@ -58,10 +64,10 @@ impl AniMatrix { // Do a hard mapping of each (derived from wireshardk captures) let rows = match model { AnimeType::GA401 => GA401.to_vec(), - AnimeType::GA402 | AnimeType::G635L | AnimeType::G835L | AnimeType::Unsupported => { - GA402.to_vec() - } + AnimeType::GA402 | AnimeType::Unsupported => GA402.to_vec(), AnimeType::GU604 => GU604.to_vec(), + AnimeType::G635L => G635L.to_vec(), + AnimeType::G835L => G835L.to_vec(), }; Self { rows, led_shape } From 6ef977f6ae4c143fb93c98babdb0132aa5aef14f Mon Sep 17 00:00:00 2001 From: Yaseen Date: Wed, 21 Jan 2026 16:26:16 +0500 Subject: [PATCH 2/4] chore: fix comments documenting Scar 18 implementation plan Removed comments mentioning monochrome/grayscale LEDs added under the impression G14 and M16 used to have RGB LED lighting. This assumption has been proved false. Additionally added agent md files to gitignore and uncommented G635L width as even a random value is likely necessary --- .gitignore | 4 ++++ rog-anime/src/data.rs | 4 ++-- rog-anime/src/diagonal.rs | 4 ---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index e5209aae..161718aa 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ desktop-extensions/gnome*/@types/gir-generated desktop-extensions/gnome*/node_modules desktop-extensions/gnome*/schemas/gschemas.compiled desktop-extensions/gnome*/*.zip + +# agents +CLAUDE.md +AGENT.md diff --git a/rog-anime/src/data.rs b/rog-anime/src/data.rs index 45a9d15b..fa8d06fc 100644 --- a/rog-anime/src/data.rs +++ b/rog-anime/src/data.rs @@ -114,7 +114,7 @@ impl AnimeType { match self { AnimeType::GU604 => 70, // TODO: Find G635L W*H - // AnimeType::G635L => 68 + AnimeType::G635L => 68, AnimeType::G835L => 68, _ => 74, } @@ -125,7 +125,7 @@ impl AnimeType { match self { AnimeType::GA401 => 36, AnimeType::GU604 => 43, - // AnimeType::G635L => 34, + AnimeType::G635L => 34, AnimeType::G835L => 34, _ => 39, } diff --git a/rog-anime/src/diagonal.rs b/rog-anime/src/diagonal.rs index 4418ae90..12199b77 100644 --- a/rog-anime/src/diagonal.rs +++ b/rog-anime/src/diagonal.rs @@ -44,8 +44,6 @@ impl AnimeDiagonal { /// Generate the base image from inputs. The result can be displayed as is /// or updated via scale, position, or angle then displayed again after /// `update()`. - /// - /// TODO: G835L and G635L only supports grayscale #[inline] pub fn from_png( path: &Path, @@ -385,8 +383,6 @@ impl AnimeDiagonal { } // TODO: Implement `to_g635l_packets` and `to_g835l_packets` functions - // IMPORTANT NOTE: G635L and G835L ONLY SUPPORT GRAYSCALE - // // fn to_g835l_packets(buf: &[u8]) -> Result { // let mut buf = vec![0u8; AnimeType::GU604.data_length()]; From b9c251d4039ab348e92632894a70775115be63d2 Mon Sep 17 00:00:00 2001 From: Yaseen Date: Wed, 21 Jan 2026 20:00:03 +0500 Subject: [PATCH 3/4] feat: add anime-led-scan tool Usage: cargo run --example anime-led-scan --- .gitignore | 5 +- asusctl/examples/anime-led-scan.rs | 547 +++++++++++++++++++++++++++++ rog-dbus/src/zbus_anime.rs | 2 +- 3 files changed, 551 insertions(+), 3 deletions(-) create mode 100644 asusctl/examples/anime-led-scan.rs diff --git a/.gitignore b/.gitignore index 161718aa..65253858 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ desktop-extensions/gnome*/node_modules desktop-extensions/gnome*/schemas/gschemas.compiled desktop-extensions/gnome*/*.zip -# agents +# agents and reference CLAUDE.md -AGENT.md +AGENTS.md +/reference diff --git a/asusctl/examples/anime-led-scan.rs b/asusctl/examples/anime-led-scan.rs new file mode 100644 index 00000000..c4ff9b94 --- /dev/null +++ b/asusctl/examples/anime-led-scan.rs @@ -0,0 +1,547 @@ +//! LED scanning tool for discovering AniMe Matrix buffer-to-LED mappings. +//! +//! This tool lights up one buffer index at a time, allowing you to observe +//! which physical LED corresponds to each buffer position. This is essential +//! for mapping new device types like G835L where the exact layout is unknown. +//! +//! You might want to use it slowly, as it sometimes doesn't work properly. +//! Maybe there's better ways to make this reliable but for now it works for my use case. +//! +//! # Usage +//! ``` +//! cargo run --example anime-led-scan -- [options] +//! ``` +//! +//! # Controls +//! - `n` or `Enter`: Next index +//! - `p` or `Backspace`: Previous index +//! - `j` followed by number: Jump to specific index +//! - `+` / `-`: Adjust step size (default 1) +//! - `s`: Save current index to notes file +//! - `r`: Mark current index as row start +//! - `q` or `Ctrl+C`: Quit +//! +//! # Output +//! Creates a `led-scan-notes.txt` file with recorded observations. + +use std::env; +use std::fs::OpenOptions; +use std::io::{self, BufRead, Write}; + +use rog_anime::usb::{get_anime_type, Brightness}; +use rog_anime::{AnimeDataBuffer, AnimeType}; +use rog_dbus::zbus_anime::AnimeProxyBlocking; +use zbus::blocking::Connection; + +/// Saved device state for restoration on exit +struct SavedState { + builtins_enabled: bool, + brightness: Brightness, + display_enabled: bool, +} + +fn print_help(scan_len: usize, buffer_len: usize) { + println!("\n=== LED Scan Tool ==="); + println!( + "Scan range: 0-{} (buffer size: {})", + scan_len - 1, + buffer_len + ); + println!("Commands:"); + println!(" n, Enter - Next index"); + println!(" p, Backspace - Previous index"); + println!(" j - Jump to index"); + println!(" + / - - Increase/decrease step size"); + println!(" s - Save note for current index"); + println!(" r - Mark as row start"); + println!(" a - Auto-scan (runs through all indices)"); + println!(" f - Fill all buffer bytes"); + println!(" f - Fill range (inclusive)"); + println!(" p1/p2/p3 - Fill pane 1/2/3 only (each is 627 bytes)"); + println!(" hold - Hold current LED (press Enter to release)"); + println!(" hold - Hold range (press Enter to release)"); + println!(" c - Clear display"); + println!(" row - Step through rows (G835L, provisional)"); + println!(" row - Show specific row (G835L, provisional)"); + println!(" allrows - Light all rows sequentially (G835L)"); + println!(" rowmap - Print the full row mapping (G835L)"); + println!(" h - Show this help"); + println!(" q - Quit and restore state"); + println!(); +} + +fn save_note(index: usize, note: &str) -> io::Result<()> { + let mut file = OpenOptions::new() + .create(true) + .append(true) + .open("led-scan-notes.txt")?; + writeln!(file, "Index {}: {}", index, note)?; + Ok(()) +} + +fn write_single_led( + proxy: &AnimeProxyBlocking, + anime_type: AnimeType, + index: usize, + brightness: u8, +) { + let mut buffer = AnimeDataBuffer::new(anime_type); + let data = buffer.data_mut(); + if index < data.len() { + data[index] = brightness; + } + if let Err(e) = proxy.write(buffer) { + eprintln!("Error writing to device: {}", e); + } +} + +fn clear_display(proxy: &AnimeProxyBlocking, anime_type: AnimeType) { + let buffer = AnimeDataBuffer::new(anime_type); + let _ = proxy.write(buffer); +} + +fn fill_display(proxy: &AnimeProxyBlocking, anime_type: AnimeType, brightness: u8) { + let mut buffer = AnimeDataBuffer::new(anime_type); + let data = buffer.data_mut(); + for byte in data.iter_mut() { + *byte = brightness; + } + if let Err(e) = proxy.write(buffer) { + eprintln!("Error writing to device: {}", e); + } +} + +/// Fill a range of LEDs. Both start and end are INCLUSIVE. +fn fill_range( + proxy: &AnimeProxyBlocking, + anime_type: AnimeType, + start: usize, + end: usize, + brightness: u8, +) { + let mut buffer = AnimeDataBuffer::new(anime_type); + let data = buffer.data_mut(); + for i in start..=end.min(data.len().saturating_sub(1)) { + data[i] = brightness; + } + if let Err(e) = proxy.write(buffer) { + eprintln!("Error writing to device: {}", e); + } +} + +fn fill_pane(proxy: &AnimeProxyBlocking, anime_type: AnimeType, pane: usize, brightness: u8) { + const PANE_LEN: usize = 627; + let start = pane * PANE_LEN; + let end = start + PANE_LEN - 1; + fill_range(proxy, anime_type, start, end, brightness); +} + +/// G835L row pattern (PROVISIONAL - needs hardware verification): +/// - Rows 0-1: 1 LED each +/// - Rows 2-3: 2 LEDs each +/// - ... (pairs of rows with same length) +/// - Rows 26-27: 14 LEDs each +/// - Rows 28+: 15 LEDs each (constant) +/// +/// Returns (start_index, end_index_inclusive, row_length) +fn g835l_row_bounds(row: usize) -> (usize, usize, usize) { + let triangle_rows = 28; + let triangle_leds = 210; + + if row < triangle_rows { + let length = row / 2 + 1; + let mut start = 0usize; + for r in 0..row { + start += r / 2 + 1; + } + (start, start + length - 1, length) + } else { + let rows_after_triangle = row - triangle_rows; + let start = triangle_leds + rows_after_triangle * 15; + (start, start + 14, 15) + } +} + +fn g835l_total_rows() -> usize { + 28 + 40 +} + +fn save_state(proxy: &AnimeProxyBlocking) -> SavedState { + SavedState { + builtins_enabled: proxy.builtins_enabled().unwrap_or(false), + brightness: proxy.brightness().unwrap_or(Brightness::Med), + display_enabled: proxy.enable_display().unwrap_or(true), + } +} + +fn restore_state(proxy: &AnimeProxyBlocking, state: &SavedState) { + let _ = proxy.set_builtins_enabled(state.builtins_enabled); + let _ = proxy.set_brightness(state.brightness); + let _ = proxy.set_enable_display(state.display_enabled); + let _ = proxy.run_main_loop(true); +} + +fn main() { + let args: Vec = env::args().collect(); + + let mut start_index = 0usize; + let mut brightness = 200u8; + let mut scan_limit: Option = None; + + let mut i = 1; + while i < args.len() { + match args[i].as_str() { + "--start" | "-s" => { + if i + 1 < args.len() { + start_index = args[i + 1].parse().unwrap_or(0); + i += 1; + } + } + "--brightness" | "-b" => { + if i + 1 < args.len() { + brightness = args[i + 1].parse().unwrap_or(200); + i += 1; + } + } + "--limit" | "-l" => { + if i + 1 < args.len() { + scan_limit = args[i + 1].parse().ok(); + i += 1; + } + } + "--help" | "-h" => { + println!("LED Scan Tool for AniMe Matrix"); + println!(); + println!("Usage: anime-led-scan [options]"); + println!(); + println!("Options:"); + println!(" -s, --start Start at index N (default: 0)"); + println!(" -b, --brightness LED brightness 0-255 (default: 200)"); + println!(" -l, --limit Cap scan range to N indices (e.g. 810 for G835L)"); + println!(" -h, --help Show this help"); + return; + } + _ => {} + } + i += 1; + } + + let conn = match Connection::system() { + Ok(c) => c, + Err(e) => { + eprintln!("Failed to connect to D-Bus: {}", e); + eprintln!("Make sure asusd is running."); + return; + } + }; + + let proxy = match AnimeProxyBlocking::new(&conn) { + Ok(p) => p, + Err(e) => { + eprintln!("Failed to create Anime proxy: {}", e); + eprintln!("Make sure asusd supports your device."); + return; + } + }; + + let anime_type = get_anime_type(); + let buffer_len = anime_type.data_length(); + let scan_len = scan_limit.unwrap_or(buffer_len).min(buffer_len); + + println!("=== LED Scan Tool ==="); + println!("Device type: {:?}", anime_type); + println!("Buffer length: {} bytes", buffer_len); + println!("Scan range: 0-{}", scan_len - 1); + println!("Brightness: {}", brightness); + println!(); + + // Save current state for restoration + let saved_state = save_state(&proxy); + println!("Saved device state for restoration on exit."); + + // Stop system animations + if let Err(e) = proxy.run_main_loop(false) { + eprintln!("Warning: Could not stop main loop: {}", e); + } + println!("Stopped system animations."); + + print_help(scan_len, buffer_len); + + let mut current_index = start_index.min(scan_len - 1); + let mut step = 1usize; + + write_single_led(&proxy, anime_type, current_index, brightness); + println!(">>> Index: {} (step: {})", current_index, step); + + let stdin = io::stdin(); + let mut input = String::new(); + + loop { + input.clear(); + print!("> "); + io::stdout().flush().unwrap(); + + if stdin.lock().read_line(&mut input).is_err() { + break; + } + + let cmd = input.trim(); + + match cmd { + "q" | "quit" | "exit" => { + clear_display(&proxy, anime_type); + restore_state(&proxy, &saved_state); + println!("Restored device state. Goodbye!"); + break; + } + "n" | "" => { + current_index = (current_index + step).min(scan_len - 1); + write_single_led(&proxy, anime_type, current_index, brightness); + println!(">>> Index: {} (step: {})", current_index, step); + } + "p" => { + current_index = current_index.saturating_sub(step); + write_single_led(&proxy, anime_type, current_index, brightness); + println!(">>> Index: {} (step: {})", current_index, step); + } + "+" => { + step = step.saturating_mul(2).max(1); + println!("Step size: {}", step); + } + "-" => { + step = step.saturating_div(2).max(1); + println!("Step size: {}", step); + } + "r" => { + if let Err(e) = save_note(current_index, "ROW START") { + eprintln!("Error saving note: {}", e); + } else { + println!("Saved: Index {} marked as ROW START", current_index); + } + } + "h" | "help" | "?" => { + print_help(scan_len, buffer_len); + } + cmd if cmd.starts_with('j') => { + let num_str = cmd.trim_start_matches('j').trim(); + if let Ok(idx) = num_str.parse::() { + if idx < scan_len { + current_index = idx; + write_single_led(&proxy, anime_type, current_index, brightness); + println!(">>> Index: {} (step: {})", current_index, step); + } else { + println!("Index {} out of range (max: {})", idx, scan_len - 1); + } + } else { + println!("Usage: j "); + } + } + cmd if cmd.starts_with('s') && !cmd.starts_with("show") => { + let note = cmd.trim_start_matches('s').trim(); + let note = if note.is_empty() { "observed" } else { note }; + if let Err(e) = save_note(current_index, note) { + eprintln!("Error saving note: {}", e); + } else { + println!("Saved note for index {}", current_index); + } + } + "a" => { + println!("Auto-scan mode (0 to {})...", scan_len - 1); + let delay = std::time::Duration::from_millis(10); + for idx in current_index..scan_len { + write_single_led(&proxy, anime_type, idx, brightness); + print!("\rIndex: {} / {} ", idx, scan_len - 1); + io::stdout().flush().unwrap(); + std::thread::sleep(delay); + current_index = idx; + } + println!(); + println!("Auto-scan complete. Current index: {}", current_index); + } + "c" => { + clear_display(&proxy, anime_type); + println!("Display cleared"); + } + "f" => { + fill_display(&proxy, anime_type, brightness); + println!("All buffer bytes filled at brightness {}", brightness); + } + "p1" => { + fill_pane(&proxy, anime_type, 0, brightness); + println!("Pane 1 (indices 0-626) filled"); + } + "p2" => { + fill_pane(&proxy, anime_type, 1, brightness); + println!("Pane 2 (indices 627-1253) filled"); + } + "p3" => { + fill_pane(&proxy, anime_type, 2, brightness); + println!("Pane 3 (indices 1254-1880) filled"); + } + cmd if cmd.starts_with("f ") => { + let parts: Vec<&str> = cmd.split_whitespace().collect(); + if parts.len() == 3 { + if let (Ok(start), Ok(end)) = + (parts[1].parse::(), parts[2].parse::()) + { + fill_range(&proxy, anime_type, start, end, brightness); + println!("Filled indices {} to {}", start, end); + } else { + println!("Usage: f "); + } + } else { + println!("Usage: f "); + } + } + "show" => { + write_single_led(&proxy, anime_type, current_index, brightness); + println!(">>> Index: {} (step: {})", current_index, step); + } + "row" => { + if anime_type != AnimeType::G835L { + println!("Warning: Row commands use G835L mapping (provisional). You can add to this code to support other types. `examples/anime-led-scan.rs[402:425]`"); + } + println!("Row stepping mode. Press Enter for next row, 'q' to quit."); + let total = g835l_total_rows(); + for row_num in 0..total { + let (start, end, len) = g835l_row_bounds(row_num); + if end >= scan_len { + println!("Row {} exceeds scan limit, stopping.", row_num); + break; + } + println!("Row {}: indices {}-{} ({} LEDs)", row_num, start, end, len); + fill_range(&proxy, anime_type, start, end, brightness); + input.clear(); + print!("(Enter=next, q=quit) > "); + io::stdout().flush().unwrap(); + if stdin.lock().read_line(&mut input).is_err() { + break; + } + if input.trim() == "q" { + break; + } + clear_display(&proxy, anime_type); + } + println!("Row stepping done."); + } + cmd if cmd.starts_with("row ") => { + if anime_type != AnimeType::G835L { + println!("Warning: Row commands use G835L mapping (provisional)."); + } + let row_str = cmd.trim_start_matches("row ").trim(); + if let Ok(row_num) = row_str.parse::() { + let total = g835l_total_rows(); + if row_num < total { + let (start, end, len) = g835l_row_bounds(row_num); + if end < scan_len { + println!("Row {}: indices {}-{} ({} LEDs)", row_num, start, end, len); + fill_range(&proxy, anime_type, start, end, brightness); + } else { + println!("Row {} exceeds scan limit", row_num); + } + } else { + println!("Row {} out of range (max: {})", row_num, total - 1); + } + } else { + println!("Usage: row "); + } + } + "allrows" => { + if anime_type != AnimeType::G835L { + println!("Warning: Row commands use G835L mapping (provisional)."); + } + println!("Lighting all rows sequentially (200ms each)..."); + let total = g835l_total_rows(); + let delay = std::time::Duration::from_millis(200); + for row_num in 0..total { + let (start, end, len) = g835l_row_bounds(row_num); + if end >= scan_len { + println!("\nRow {} exceeds scan limit, stopping.", row_num); + break; + } + print!( + "\rRow {}/{}: indices {}-{} ({} LEDs) ", + row_num, + total - 1, + start, + end, + len + ); + io::stdout().flush().unwrap(); + fill_range(&proxy, anime_type, start, end, brightness); + std::thread::sleep(delay); + clear_display(&proxy, anime_type); + } + println!("\nDone."); + } + "rowmap" => { + if anime_type != AnimeType::G835L { + println!("Warning: Row map is for G835L (provisional)."); + } + println!("G835L Row Map:"); + let total = g835l_total_rows(); + for row_num in 0..total { + let (start, end, len) = g835l_row_bounds(row_num); + let marker = if end >= scan_len { + " (exceeds limit)" + } else { + "" + }; + println!( + " Row {:2}: indices {:4}-{:4} ({:2} LEDs){}", + row_num, start, end, len, marker + ); + } + } + "hold" => { + // Single write, wait for Enter to release + println!("Holding index {}. Press Enter to release...", current_index); + write_single_led(&proxy, anime_type, current_index, brightness); + input.clear(); + let _ = stdin.lock().read_line(&mut input); + clear_display(&proxy, anime_type); + println!("Released."); + } + cmd if cmd.starts_with("hold ") => { + let arg = cmd.trim_start_matches("hold ").trim(); + let (start, end): (usize, usize) = match arg { + "p1" | "1" => (0, 626), + "p2" | "2" => (627, 1253), + _ => { + let parts: Vec<&str> = arg.split_whitespace().collect(); + if parts.len() == 2 { + if let (Ok(s), Ok(e)) = (parts[0].parse(), parts[1].parse()) { + (s, e) + } else { + println!("Usage: hold p1, hold p2, or hold "); + continue; + } + } else { + println!("Usage: hold p1, hold p2, or hold "); + continue; + } + } + }; + println!("Holding range {}-{}. Press Enter to release...", start, end); + fill_range(&proxy, anime_type, start, end, brightness); + input.clear(); + let _ = stdin.lock().read_line(&mut input); + clear_display(&proxy, anime_type); + println!("Released."); + } + _ => { + if let Ok(idx) = cmd.parse::() { + if idx < scan_len { + current_index = idx; + write_single_led(&proxy, anime_type, current_index, brightness); + println!(">>> Index: {} (step: {})", current_index, step); + } else { + println!("Index {} out of range (max: {})", idx, scan_len - 1); + } + } else { + println!("Unknown command: '{}'. Type 'h' for help.", cmd); + } + } + } + } +} diff --git a/rog-dbus/src/zbus_anime.rs b/rog-dbus/src/zbus_anime.rs index ed0df009..2fdec4b4 100644 --- a/rog-dbus/src/zbus_anime.rs +++ b/rog-dbus/src/zbus_anime.rs @@ -5,7 +5,7 @@ use zbus::proxy; #[proxy( interface = "xyz.ljones.Anime", default_service = "xyz.ljones.Asusd", - default_path = "/xyz/ljones" + default_path = "/xyz/ljones/aura/anime" )] pub trait Anime { /// DeviceState method From 7cf6c477eb5765f24cc915a2467c6d8d3c49fd92 Mon Sep 17 00:00:00 2001 From: Yaseen Date: Wed, 21 Jan 2026 20:00:15 +0500 Subject: [PATCH 4/4] feat: add G835L diagonal test images --- .../tests/data/g835l-diagonal-fullbright.png | Bin 0 -> 187 bytes rog-anime/tests/data/g835l-diagonal.gif | Bin 0 -> 829 bytes rog-anime/tests/data/g835l-diagonal.png | Bin 0 -> 148 bytes 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 rog-anime/tests/data/g835l-diagonal-fullbright.png create mode 100644 rog-anime/tests/data/g835l-diagonal.gif create mode 100644 rog-anime/tests/data/g835l-diagonal.png diff --git a/rog-anime/tests/data/g835l-diagonal-fullbright.png b/rog-anime/tests/data/g835l-diagonal-fullbright.png new file mode 100644 index 0000000000000000000000000000000000000000..cd93a8539aff2e5189d6ed62c7b1c6954ea2dcc7 GIT binary patch literal 187 zcmeAS@N?(olHy`uVBq!ia0vp^EUsccqQca#Njv*Cu)?P7WI-tPAwAQ;gC^B&g26Qwyu}o>4ajL)Kl#5QPV&5h~XU&dvAueH3i?n0~ zMeP_{IW(Y3-K>^328KpnWv@9WJ|r@9Nf>*H2rO89tY3k<>8>y+hVzC*||9e!FGQ%FE0w{c8R=KlWCF`G{LrVSq<0J zmzQQauT0w_CA#cdPteXsf2=lYhHch9Y4)beZ1t^#%)i zZhj8AGU28jF9*nfj3NxoApbD}eWwTx5_o`c%w%9^k#Kj8JKyXvBb^gb7I3o zM@BwnH4%ouMMoP&*!A|j*pSrFD1VlUrU&Mzz6r`on2QmG1j88S(AZB*{A5Us0ye!KTwsWQ$! zv%zHXwwA7MPi}0EohSx$u-5fm+1{&oe_d1eo|-aqQ}6GP{M!tSjL2@s5$YW9P#1xQ NIvX(569+uhtpTiPOm6@H literal 0 HcmV?d00001 diff --git a/rog-anime/tests/data/g835l-diagonal.png b/rog-anime/tests/data/g835l-diagonal.png new file mode 100644 index 0000000000000000000000000000000000000000..6dd084df3d37a64bd64477a57dd6b5e4192f61bc GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^EUsccqQqi6+jv*Cu-d?umI$*%V9N_wW z|7PPYKOMakF9~fhYp$peWUAt5c9IZT^nxof0L(hHz@}rxo{nWEE tW1RP2=ws=UNnTnj@2s3M_fvdiFr&n)h)d_hH}Zk3^K|udS?83{1OSnrF^K>G literal 0 HcmV?d00001