chore: add implementation planning for G635L/G835L support

This commit is contained in:
Ghoul
2026-01-21 00:06:56 +05:00
parent 7edb77b41f
commit c7de3fb0c8
8 changed files with 738 additions and 7 deletions

View File

@@ -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,
}
}

View File

@@ -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<AnimeDataBuffer> {
// 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)
// }
}

View File

@@ -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),
}