mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
First pass of Anime update for new matrix display
Co-authored with @I-Al-Istannen Part of #189
This commit is contained in:
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased ]
|
## [Unreleased ]
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Data for anime-matrix now requires passing the laptop model as enum
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Support for GA503R LED modes
|
- Support for GA503R LED modes
|
||||||
### Changed
|
### Changed
|
||||||
|
|||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1027,6 +1027,8 @@ dependencies = [
|
|||||||
"png_pong",
|
"png_pong",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
"sysfs-class",
|
||||||
|
"udev",
|
||||||
"zvariant",
|
"zvariant",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -7,122 +7,122 @@ use rog_dbus::RogDbusClientBlocking;
|
|||||||
fn main() {
|
fn main() {
|
||||||
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
let (client, _) = RogDbusClientBlocking::new().unwrap();
|
||||||
let mut matrix = AnimeDataBuffer::new();
|
let mut matrix = AnimeDataBuffer::new();
|
||||||
matrix.get_mut()[1] = 100; // start = 1
|
matrix.data_mut()[1] = 100; // start = 1
|
||||||
for n in matrix.get_mut()[2..32].iter_mut() {
|
for n in matrix.data_mut()[2..32].iter_mut() {
|
||||||
*n = 250;
|
*n = 250;
|
||||||
}
|
}
|
||||||
matrix.get_mut()[32] = 100; // end
|
matrix.data_mut()[32] = 100; // end
|
||||||
matrix.get_mut()[34] = 100; // start x = 0
|
matrix.data_mut()[34] = 100; // start x = 0
|
||||||
matrix.get_mut()[66] = 100; // end
|
matrix.data_mut()[66] = 100; // end
|
||||||
matrix.get_mut()[69] = 100; // start x = 1
|
matrix.data_mut()[69] = 100; // start x = 1
|
||||||
matrix.get_mut()[101] = 100; // end
|
matrix.data_mut()[101] = 100; // end
|
||||||
matrix.get_mut()[102] = 100; // start
|
matrix.data_mut()[102] = 100; // start
|
||||||
matrix.get_mut()[134] = 100; // end
|
matrix.data_mut()[134] = 100; // end
|
||||||
matrix.get_mut()[137] = 100; // start
|
matrix.data_mut()[137] = 100; // start
|
||||||
matrix.get_mut()[169] = 100; // end
|
matrix.data_mut()[169] = 100; // end
|
||||||
matrix.get_mut()[170] = 100; // start
|
matrix.data_mut()[170] = 100; // start
|
||||||
matrix.get_mut()[202] = 100; // end
|
matrix.data_mut()[202] = 100; // end
|
||||||
matrix.get_mut()[204] = 100; // start
|
matrix.data_mut()[204] = 100; // start
|
||||||
matrix.get_mut()[236] = 100; // end
|
matrix.data_mut()[236] = 100; // end
|
||||||
matrix.get_mut()[237] = 100; // start
|
matrix.data_mut()[237] = 100; // start
|
||||||
matrix.get_mut()[268] = 100; // end
|
matrix.data_mut()[268] = 100; // end
|
||||||
matrix.get_mut()[270] = 100; // start
|
matrix.data_mut()[270] = 100; // start
|
||||||
matrix.get_mut()[301] = 100; // end
|
matrix.data_mut()[301] = 100; // end
|
||||||
matrix.get_mut()[302] = 100; // start
|
matrix.data_mut()[302] = 100; // start
|
||||||
matrix.get_mut()[332] = 100; // end
|
matrix.data_mut()[332] = 100; // end
|
||||||
matrix.get_mut()[334] = 100; // start
|
matrix.data_mut()[334] = 100; // start
|
||||||
matrix.get_mut()[364] = 100; // end
|
matrix.data_mut()[364] = 100; // end
|
||||||
matrix.get_mut()[365] = 100; // start
|
matrix.data_mut()[365] = 100; // start
|
||||||
matrix.get_mut()[394] = 100; // end
|
matrix.data_mut()[394] = 100; // end
|
||||||
matrix.get_mut()[396] = 100; // start
|
matrix.data_mut()[396] = 100; // start
|
||||||
matrix.get_mut()[425] = 100; // end
|
matrix.data_mut()[425] = 100; // end
|
||||||
matrix.get_mut()[426] = 100; // start
|
matrix.data_mut()[426] = 100; // start
|
||||||
matrix.get_mut()[454] = 100; // end
|
matrix.data_mut()[454] = 100; // end
|
||||||
matrix.get_mut()[456] = 100; // start
|
matrix.data_mut()[456] = 100; // start
|
||||||
matrix.get_mut()[484] = 100; // end
|
matrix.data_mut()[484] = 100; // end
|
||||||
matrix.get_mut()[485] = 100; // start
|
matrix.data_mut()[485] = 100; // start
|
||||||
matrix.get_mut()[512] = 100; // end
|
matrix.data_mut()[512] = 100; // end
|
||||||
matrix.get_mut()[514] = 100; // start
|
matrix.data_mut()[514] = 100; // start
|
||||||
matrix.get_mut()[541] = 100; // end
|
matrix.data_mut()[541] = 100; // end
|
||||||
matrix.get_mut()[542] = 100; // start
|
matrix.data_mut()[542] = 100; // start
|
||||||
matrix.get_mut()[568] = 100; // end
|
matrix.data_mut()[568] = 100; // end
|
||||||
matrix.get_mut()[570] = 100; // start
|
matrix.data_mut()[570] = 100; // start
|
||||||
matrix.get_mut()[596] = 100; // end
|
matrix.data_mut()[596] = 100; // end
|
||||||
matrix.get_mut()[597] = 100; // start
|
matrix.data_mut()[597] = 100; // start
|
||||||
matrix.get_mut()[622] = 100; // end
|
matrix.data_mut()[622] = 100; // end
|
||||||
matrix.get_mut()[624] = 100; // start
|
matrix.data_mut()[624] = 100; // start
|
||||||
matrix.get_mut()[649] = 100; // end
|
matrix.data_mut()[649] = 100; // end
|
||||||
matrix.get_mut()[650] = 100; // start
|
matrix.data_mut()[650] = 100; // start
|
||||||
matrix.get_mut()[674] = 100; // end
|
matrix.data_mut()[674] = 100; // end
|
||||||
matrix.get_mut()[676] = 100; // start
|
matrix.data_mut()[676] = 100; // start
|
||||||
matrix.get_mut()[700] = 100; // end
|
matrix.data_mut()[700] = 100; // end
|
||||||
matrix.get_mut()[701] = 100; // start
|
matrix.data_mut()[701] = 100; // start
|
||||||
matrix.get_mut()[724] = 100; // end
|
matrix.data_mut()[724] = 100; // end
|
||||||
matrix.get_mut()[726] = 100; // start
|
matrix.data_mut()[726] = 100; // start
|
||||||
matrix.get_mut()[749] = 100; // end
|
matrix.data_mut()[749] = 100; // end
|
||||||
matrix.get_mut()[750] = 100; // start
|
matrix.data_mut()[750] = 100; // start
|
||||||
matrix.get_mut()[772] = 100; // end
|
matrix.data_mut()[772] = 100; // end
|
||||||
matrix.get_mut()[774] = 100; // start
|
matrix.data_mut()[774] = 100; // start
|
||||||
matrix.get_mut()[796] = 100; // end
|
matrix.data_mut()[796] = 100; // end
|
||||||
matrix.get_mut()[797] = 100; // start
|
matrix.data_mut()[797] = 100; // start
|
||||||
matrix.get_mut()[818] = 100; // end
|
matrix.data_mut()[818] = 100; // end
|
||||||
matrix.get_mut()[820] = 100; // start
|
matrix.data_mut()[820] = 100; // start
|
||||||
matrix.get_mut()[841] = 100; // end
|
matrix.data_mut()[841] = 100; // end
|
||||||
matrix.get_mut()[842] = 100; // start
|
matrix.data_mut()[842] = 100; // start
|
||||||
matrix.get_mut()[862] = 100; // end
|
matrix.data_mut()[862] = 100; // end
|
||||||
matrix.get_mut()[864] = 100; // start
|
matrix.data_mut()[864] = 100; // start
|
||||||
matrix.get_mut()[884] = 100; // end
|
matrix.data_mut()[884] = 100; // end
|
||||||
matrix.get_mut()[885] = 100; // start
|
matrix.data_mut()[885] = 100; // start
|
||||||
matrix.get_mut()[904] = 100; // end
|
matrix.data_mut()[904] = 100; // end
|
||||||
matrix.get_mut()[906] = 100; // start
|
matrix.data_mut()[906] = 100; // start
|
||||||
matrix.get_mut()[925] = 100; // end
|
matrix.data_mut()[925] = 100; // end
|
||||||
matrix.get_mut()[926] = 100; // start
|
matrix.data_mut()[926] = 100; // start
|
||||||
matrix.get_mut()[944] = 100; // end
|
matrix.data_mut()[944] = 100; // end
|
||||||
matrix.get_mut()[946] = 100; // start
|
matrix.data_mut()[946] = 100; // start
|
||||||
matrix.get_mut()[964] = 100; // end
|
matrix.data_mut()[964] = 100; // end
|
||||||
matrix.get_mut()[965] = 100; // start
|
matrix.data_mut()[965] = 100; // start
|
||||||
matrix.get_mut()[982] = 100; // end
|
matrix.data_mut()[982] = 100; // end
|
||||||
matrix.get_mut()[984] = 100; // start
|
matrix.data_mut()[984] = 100; // start
|
||||||
matrix.get_mut()[1001] = 100; // end
|
matrix.data_mut()[1001] = 100; // end
|
||||||
matrix.get_mut()[1002] = 100; // start
|
matrix.data_mut()[1002] = 100; // start
|
||||||
matrix.get_mut()[1018] = 100; // end
|
matrix.data_mut()[1018] = 100; // end
|
||||||
matrix.get_mut()[1020] = 100; // start
|
matrix.data_mut()[1020] = 100; // start
|
||||||
matrix.get_mut()[1036] = 100; // end
|
matrix.data_mut()[1036] = 100; // end
|
||||||
matrix.get_mut()[1037] = 100; // start
|
matrix.data_mut()[1037] = 100; // start
|
||||||
matrix.get_mut()[1052] = 100; // end
|
matrix.data_mut()[1052] = 100; // end
|
||||||
matrix.get_mut()[1054] = 100; // start
|
matrix.data_mut()[1054] = 100; // start
|
||||||
matrix.get_mut()[1069] = 100; // end
|
matrix.data_mut()[1069] = 100; // end
|
||||||
matrix.get_mut()[1070] = 100; // start
|
matrix.data_mut()[1070] = 100; // start
|
||||||
matrix.get_mut()[1084] = 100; // end
|
matrix.data_mut()[1084] = 100; // end
|
||||||
matrix.get_mut()[1086] = 100; // start
|
matrix.data_mut()[1086] = 100; // start
|
||||||
matrix.get_mut()[1100] = 100; // end
|
matrix.data_mut()[1100] = 100; // end
|
||||||
matrix.get_mut()[1101] = 100; // start
|
matrix.data_mut()[1101] = 100; // start
|
||||||
matrix.get_mut()[1114] = 100; // end
|
matrix.data_mut()[1114] = 100; // end
|
||||||
matrix.get_mut()[1116] = 100; // start
|
matrix.data_mut()[1116] = 100; // start
|
||||||
matrix.get_mut()[1129] = 100; // end
|
matrix.data_mut()[1129] = 100; // end
|
||||||
matrix.get_mut()[1130] = 100; // start
|
matrix.data_mut()[1130] = 100; // start
|
||||||
matrix.get_mut()[1142] = 100; // end
|
matrix.data_mut()[1142] = 100; // end
|
||||||
matrix.get_mut()[1144] = 100; // start
|
matrix.data_mut()[1144] = 100; // start
|
||||||
matrix.get_mut()[1156] = 100; // end
|
matrix.data_mut()[1156] = 100; // end
|
||||||
matrix.get_mut()[1157] = 100; // start
|
matrix.data_mut()[1157] = 100; // start
|
||||||
matrix.get_mut()[1168] = 100; // end
|
matrix.data_mut()[1168] = 100; // end
|
||||||
matrix.get_mut()[1170] = 100; // start
|
matrix.data_mut()[1170] = 100; // start
|
||||||
matrix.get_mut()[1181] = 100; // end
|
matrix.data_mut()[1181] = 100; // end
|
||||||
matrix.get_mut()[1182] = 100; // start
|
matrix.data_mut()[1182] = 100; // start
|
||||||
matrix.get_mut()[1192] = 100; // end
|
matrix.data_mut()[1192] = 100; // end
|
||||||
matrix.get_mut()[1194] = 100; // start
|
matrix.data_mut()[1194] = 100; // start
|
||||||
matrix.get_mut()[1204] = 100; // end
|
matrix.data_mut()[1204] = 100; // end
|
||||||
matrix.get_mut()[1205] = 100; // start
|
matrix.data_mut()[1205] = 100; // start
|
||||||
matrix.get_mut()[1214] = 100; // end
|
matrix.data_mut()[1214] = 100; // end
|
||||||
matrix.get_mut()[1216] = 100; // start
|
matrix.data_mut()[1216] = 100; // start
|
||||||
matrix.get_mut()[1225] = 100; // end
|
matrix.data_mut()[1225] = 100; // end
|
||||||
matrix.get_mut()[1226] = 100; // start
|
matrix.data_mut()[1226] = 100; // start
|
||||||
matrix.get_mut()[1234] = 100; // end
|
matrix.data_mut()[1234] = 100; // end
|
||||||
matrix.get_mut()[1236] = 100; // start
|
matrix.data_mut()[1236] = 100; // start
|
||||||
for n in matrix.get_mut()[1237..1244].iter_mut() {
|
for n in matrix.data_mut()[1237..1244].iter_mut() {
|
||||||
*n = 250;
|
*n = 250;
|
||||||
}
|
}
|
||||||
matrix.get_mut()[1244] = 100; // end
|
matrix.data_mut()[1244] = 100; // end
|
||||||
println!("{:?}", &matrix);
|
println!("{:?}", &matrix);
|
||||||
|
|
||||||
client.proxies().anime().write(matrix).unwrap();
|
client.proxies().anime().write(matrix).unwrap();
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ use gumdrop::{Opt, Options};
|
|||||||
|
|
||||||
use anime_cli::{AnimeActions, AnimeCommand};
|
use anime_cli::{AnimeActions, AnimeCommand};
|
||||||
use profiles_cli::{FanCurveCommand, ProfileCommand};
|
use profiles_cli::{FanCurveCommand, ProfileCommand};
|
||||||
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, Vec2};
|
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, Vec2};
|
||||||
use rog_aura::usb::AuraControl;
|
use rog_aura::usb::AuraControl;
|
||||||
use rog_aura::{self, AuraEffect};
|
use rog_aura::{self, AuraEffect};
|
||||||
@@ -234,6 +235,7 @@ fn handle_anime(
|
|||||||
dbus.proxies().anime().set_brightness(bright as f32)?
|
dbus.proxies().anime().set_brightness(bright as f32)?
|
||||||
}
|
}
|
||||||
if let Some(action) = cmd.command.as_ref() {
|
if let Some(action) = cmd.command.as_ref() {
|
||||||
|
let anime_type = get_anime_type()?;
|
||||||
match action {
|
match action {
|
||||||
AnimeActions::Image(image) => {
|
AnimeActions::Image(image) => {
|
||||||
if image.help_requested() || image.path.is_empty() {
|
if image.help_requested() || image.path.is_empty() {
|
||||||
@@ -250,6 +252,7 @@ fn handle_anime(
|
|||||||
image.angle,
|
image.angle,
|
||||||
Vec2::new(image.x_pos, image.y_pos),
|
Vec2::new(image.x_pos, image.y_pos),
|
||||||
image.bright,
|
image.bright,
|
||||||
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
dbus.proxies()
|
dbus.proxies()
|
||||||
@@ -269,7 +272,7 @@ fn handle_anime(
|
|||||||
|
|
||||||
dbus.proxies()
|
dbus.proxies()
|
||||||
.anime()
|
.anime()
|
||||||
.write(<AnimeDataBuffer>::from(&matrix))?;
|
.write(matrix.into_data_buffer(anime_type))?;
|
||||||
}
|
}
|
||||||
AnimeActions::Gif(gif) => {
|
AnimeActions::Gif(gif) => {
|
||||||
if gif.help_requested() || gif.path.is_empty() {
|
if gif.help_requested() || gif.path.is_empty() {
|
||||||
@@ -287,6 +290,7 @@ fn handle_anime(
|
|||||||
Vec2::new(gif.x_pos, gif.y_pos),
|
Vec2::new(gif.x_pos, gif.y_pos),
|
||||||
AnimTime::Count(1),
|
AnimTime::Count(1),
|
||||||
gif.bright,
|
gif.bright,
|
||||||
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut loops = gif.loops as i32;
|
let mut loops = gif.loops as i32;
|
||||||
@@ -316,6 +320,7 @@ fn handle_anime(
|
|||||||
Path::new(&gif.path),
|
Path::new(&gif.path),
|
||||||
AnimTime::Count(1),
|
AnimTime::Count(1),
|
||||||
gif.bright,
|
gif.bright,
|
||||||
|
anime_type,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut loops = gif.loops as i32;
|
let mut loops = gif.loops as i32;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::RogDbusClientBlocking;
|
||||||
use rog_user::{
|
use rog_user::{
|
||||||
ctrl_anime::{CtrlAnime, CtrlAnimeInner},
|
ctrl_anime::{CtrlAnime, CtrlAnimeInner},
|
||||||
@@ -28,8 +29,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let early_return = Arc::new(AtomicBool::new(false));
|
let early_return = Arc::new(AtomicBool::new(false));
|
||||||
// Set up the anime data and run loop/thread
|
// Set up the anime data and run loop/thread
|
||||||
if supported.anime_ctrl.0 {
|
if supported.anime_ctrl.0 {
|
||||||
|
let anime_type = get_anime_type()?;
|
||||||
let anime_config = UserAnimeConfig::load_config(config.active_anime)?;
|
let anime_config = UserAnimeConfig::load_config(config.active_anime)?;
|
||||||
let anime = anime_config.create_anime()?;
|
let anime = anime_config.create_anime(anime_type)?;
|
||||||
let anime_config = Arc::new(Mutex::new(anime_config));
|
let anime_config = Arc::new(Mutex::new(anime_config));
|
||||||
|
|
||||||
executor
|
executor
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::{
|
|||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
use rog_anime::{ActionLoader, AnimTime, Fade, Sequences, Vec2};
|
use rog_anime::{ActionLoader, AnimTime, AnimeType, Fade, Sequences, Vec2};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
@@ -16,8 +16,8 @@ pub struct UserAnimeConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl UserAnimeConfig {
|
impl UserAnimeConfig {
|
||||||
pub fn create_anime(&self) -> Result<Sequences, Error> {
|
pub fn create_anime(&self, anime_type: AnimeType) -> Result<Sequences, Error> {
|
||||||
let mut seq = Sequences::new();
|
let mut seq = Sequences::new(anime_type);
|
||||||
|
|
||||||
for (idx, action) in self.anime.iter().enumerate() {
|
for (idx, action) in self.anime.iter().enumerate() {
|
||||||
seq.insert(idx, action)?;
|
seq.insert(idx, action)?;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::VERSION;
|
use crate::VERSION;
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use rog_anime::Fade;
|
|
||||||
use rog_anime::{error::AnimeError, ActionData, ActionLoader, AnimTime, Vec2};
|
use rog_anime::{error::AnimeError, ActionData, ActionLoader, AnimTime, Vec2};
|
||||||
|
use rog_anime::{AnimeType, Fade};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
@@ -81,27 +81,28 @@ pub struct AnimeConfigCached {
|
|||||||
|
|
||||||
impl AnimeConfigCached {
|
impl AnimeConfigCached {
|
||||||
pub fn init_from_config(&mut self, config: &AnimeConfig) -> Result<(), AnimeError> {
|
pub fn init_from_config(&mut self, config: &AnimeConfig) -> Result<(), AnimeError> {
|
||||||
|
let anime_type = AnimeType::GA401; // TODO: detect
|
||||||
let mut sys = Vec::with_capacity(config.system.len());
|
let mut sys = Vec::with_capacity(config.system.len());
|
||||||
for ani in config.system.iter() {
|
for ani in config.system.iter() {
|
||||||
sys.push(ActionData::from_anime_action(ani)?);
|
sys.push(ActionData::from_anime_action(anime_type, ani)?);
|
||||||
}
|
}
|
||||||
self.system = sys;
|
self.system = sys;
|
||||||
|
|
||||||
let mut boot = Vec::with_capacity(config.boot.len());
|
let mut boot = Vec::with_capacity(config.boot.len());
|
||||||
for ani in config.boot.iter() {
|
for ani in config.boot.iter() {
|
||||||
boot.push(ActionData::from_anime_action(ani)?);
|
boot.push(ActionData::from_anime_action(anime_type, ani)?);
|
||||||
}
|
}
|
||||||
self.boot = boot;
|
self.boot = boot;
|
||||||
|
|
||||||
let mut wake = Vec::with_capacity(config.wake.len());
|
let mut wake = Vec::with_capacity(config.wake.len());
|
||||||
for ani in config.wake.iter() {
|
for ani in config.wake.iter() {
|
||||||
wake.push(ActionData::from_anime_action(ani)?);
|
wake.push(ActionData::from_anime_action(anime_type, ani)?);
|
||||||
}
|
}
|
||||||
self.wake = wake;
|
self.wake = wake;
|
||||||
|
|
||||||
let mut shutdown = Vec::with_capacity(config.shutdown.len());
|
let mut shutdown = Vec::with_capacity(config.shutdown.len());
|
||||||
for ani in config.shutdown.iter() {
|
for ani in config.shutdown.iter() {
|
||||||
shutdown.push(ActionData::from_anime_action(ani)?);
|
shutdown.push(ActionData::from_anime_action(anime_type, ani)?);
|
||||||
}
|
}
|
||||||
self.shutdown = shutdown;
|
self.shutdown = shutdown;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -8,10 +8,11 @@ use logind_zbus::manager::ManagerProxy;
|
|||||||
use rog_anime::{
|
use rog_anime::{
|
||||||
error::AnimeError,
|
error::AnimeError,
|
||||||
usb::{
|
usb::{
|
||||||
pkt_for_apply, pkt_for_flush, pkt_for_set_boot, pkt_for_set_on, pkts_for_init, PROD_ID,
|
find_node, get_anime_type, pkt_for_apply, pkt_for_flush, pkt_for_set_boot, pkt_for_set_on,
|
||||||
VENDOR_ID,
|
pkts_for_init, PROD_ID, VENDOR_ID,
|
||||||
},
|
},
|
||||||
ActionData, AnimeDataBuffer, AnimePacketType, ANIME_DATA_LEN,
|
ActionData, AnimeDataBuffer, AnimePacketType, AnimeType, ANIME_GA401_DATA_LEN,
|
||||||
|
ANIME_GA402_DATA_LEN,
|
||||||
};
|
};
|
||||||
use rog_supported::AnimeSupportedFunctions;
|
use rog_supported::AnimeSupportedFunctions;
|
||||||
use rusb::{Device, DeviceHandle};
|
use rusb::{Device, DeviceHandle};
|
||||||
@@ -41,6 +42,7 @@ impl GetSupported for CtrlAnime {
|
|||||||
|
|
||||||
pub struct CtrlAnime {
|
pub struct CtrlAnime {
|
||||||
_node: String,
|
_node: String,
|
||||||
|
anime_type: AnimeType,
|
||||||
handle: RefCell<DeviceHandle<rusb::GlobalContext>>,
|
handle: RefCell<DeviceHandle<rusb::GlobalContext>>,
|
||||||
cache: AnimeConfigCached,
|
cache: AnimeConfigCached,
|
||||||
config: AnimeConfig,
|
config: AnimeConfig,
|
||||||
@@ -53,7 +55,8 @@ pub struct CtrlAnime {
|
|||||||
impl CtrlAnime {
|
impl CtrlAnime {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(config: AnimeConfig) -> Result<CtrlAnime, Box<dyn Error>> {
|
pub fn new(config: AnimeConfig) -> Result<CtrlAnime, Box<dyn Error>> {
|
||||||
let node = Self::find_node("193b")?;
|
let node = find_node("193b")?;
|
||||||
|
let anime_type = get_anime_type()?;
|
||||||
let device = Self::get_dev_handle()?;
|
let device = Self::get_dev_handle()?;
|
||||||
|
|
||||||
info!("Device has an AniMe Matrix display");
|
info!("Device has an AniMe Matrix display");
|
||||||
@@ -62,6 +65,7 @@ impl CtrlAnime {
|
|||||||
|
|
||||||
let ctrl = CtrlAnime {
|
let ctrl = CtrlAnime {
|
||||||
_node: node,
|
_node: node,
|
||||||
|
anime_type,
|
||||||
handle: RefCell::new(device),
|
handle: RefCell::new(device),
|
||||||
cache,
|
cache,
|
||||||
config,
|
config,
|
||||||
@@ -73,34 +77,6 @@ impl CtrlAnime {
|
|||||||
Ok(ctrl)
|
Ok(ctrl)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_node(id_product: &str) -> Result<String, RogError> {
|
|
||||||
let mut enumerator = udev::Enumerator::new().map_err(|err| {
|
|
||||||
warn!("{}", err);
|
|
||||||
RogError::Udev("enumerator failed".into(), err)
|
|
||||||
})?;
|
|
||||||
enumerator.match_subsystem("usb").map_err(|err| {
|
|
||||||
warn!("{}", err);
|
|
||||||
RogError::Udev("match_subsystem failed".into(), err)
|
|
||||||
})?;
|
|
||||||
|
|
||||||
for device in enumerator.scan_devices().map_err(|err| {
|
|
||||||
warn!("{}", err);
|
|
||||||
RogError::Udev("scan_devices failed".into(), err)
|
|
||||||
})? {
|
|
||||||
if let Some(attr) = device.attribute_value("idProduct") {
|
|
||||||
if attr == id_product {
|
|
||||||
if let Some(dev_node) = device.devnode() {
|
|
||||||
info!("Using device at: {:?} for AniMe control", dev_node);
|
|
||||||
return Ok(dev_node.to_string_lossy().to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(RogError::MissingFunction(
|
|
||||||
"ASUS AniMe device node not found".into(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_dev_handle() -> Result<DeviceHandle<rusb::GlobalContext>, Box<dyn Error>> {
|
fn get_dev_handle() -> Result<DeviceHandle<rusb::GlobalContext>, Box<dyn Error>> {
|
||||||
// We don't expect this ID to ever change
|
// We don't expect this ID to ever change
|
||||||
let device = CtrlAnime::get_device(0x0b05, 0x193b)?;
|
let device = CtrlAnime::get_device(0x0b05, 0x193b)?;
|
||||||
@@ -156,10 +132,12 @@ impl CtrlAnime {
|
|||||||
// we don't block other threads/main
|
// we don't block other threads/main
|
||||||
let thread_exit;
|
let thread_exit;
|
||||||
let thread_running;
|
let thread_running;
|
||||||
|
let anime_type;
|
||||||
loop {
|
loop {
|
||||||
if let Ok(lock) = inner.try_lock() {
|
if let Ok(lock) = inner.try_lock() {
|
||||||
thread_exit = lock.thread_exit.clone();
|
thread_exit = lock.thread_exit.clone();
|
||||||
thread_running = lock.thread_running.clone();
|
thread_running = lock.thread_running.clone();
|
||||||
|
anime_type = lock.anime_type;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -224,7 +202,16 @@ impl CtrlAnime {
|
|||||||
}
|
}
|
||||||
// Clear the display on exit
|
// Clear the display on exit
|
||||||
if let Ok(lock) = inner.try_lock() {
|
if let Ok(lock) = inner.try_lock() {
|
||||||
let data = AnimeDataBuffer::from_vec([0u8; ANIME_DATA_LEN].to_vec());
|
let data = match anime_type {
|
||||||
|
AnimeType::GA401 => AnimeDataBuffer::from_vec(
|
||||||
|
anime_type,
|
||||||
|
[0u8; ANIME_GA401_DATA_LEN].to_vec(),
|
||||||
|
),
|
||||||
|
AnimeType::GA402 => AnimeDataBuffer::from_vec(
|
||||||
|
anime_type,
|
||||||
|
[0u8; ANIME_GA402_DATA_LEN].to_vec(),
|
||||||
|
),
|
||||||
|
};
|
||||||
lock.write_data_buffer(data);
|
lock.write_data_buffer(data);
|
||||||
}
|
}
|
||||||
// Loop ended, set the atmonics
|
// Loop ended, set the atmonics
|
||||||
@@ -277,7 +264,7 @@ impl CtrlAnime {
|
|||||||
/// Write only a data packet. This will modify the leds brightness using the
|
/// Write only a data packet. This will modify the leds brightness using the
|
||||||
/// global brightness set in config.
|
/// global brightness set in config.
|
||||||
fn write_data_buffer(&self, mut buffer: AnimeDataBuffer) {
|
fn write_data_buffer(&self, mut buffer: AnimeDataBuffer) {
|
||||||
for led in buffer.get_mut()[7..].iter_mut() {
|
for led in buffer.data_mut()[7..].iter_mut() {
|
||||||
let mut bright = *led as f32 * self.config.brightness;
|
let mut bright = *led as f32 * self.config.brightness;
|
||||||
if bright > 254.0 {
|
if bright > 254.0 {
|
||||||
bright = 254.0;
|
bright = 254.0;
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ edition = "2018"
|
|||||||
exclude = ["data"]
|
exclude = ["data"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["dbus"]
|
default = ["dbus", "detect"]
|
||||||
dbus = ["zvariant"]
|
dbus = ["zvariant"]
|
||||||
|
detect = ["udev", "sysfs-class"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
png_pong = "^0.8.0"
|
png_pong = "^0.8.0"
|
||||||
@@ -28,3 +29,6 @@ serde_derive = "^1.0"
|
|||||||
glam = { version = "0.20.5", features = ["serde"] }
|
glam = { version = "0.20.5", features = ["serde"] }
|
||||||
|
|
||||||
zvariant = { version = "^3.0", optional = true }
|
zvariant = { version = "^3.0", optional = true }
|
||||||
|
|
||||||
|
udev = { version = "^0.6", optional = true }
|
||||||
|
sysfs-class = { version = "^0.1", optional = true }
|
||||||
@@ -17,10 +17,15 @@ const BLOCK_END: usize = 634;
|
|||||||
/// Individual usable data length of each USB packet
|
/// Individual usable data length of each USB packet
|
||||||
const PANE_LEN: usize = BLOCK_END - BLOCK_START;
|
const PANE_LEN: usize = BLOCK_END - BLOCK_START;
|
||||||
/// The length of usable data
|
/// The length of usable data
|
||||||
pub const ANIME_DATA_LEN: usize = PANE_LEN * 2;
|
pub const ANIME_GA401_DATA_LEN: usize = PANE_LEN * 2;
|
||||||
|
pub const ANIME_GA402_DATA_LEN: usize = PANE_LEN * 3;
|
||||||
|
|
||||||
|
/// First packet is for GA401 + GA402
|
||||||
const USB_PREFIX1: [u8; 7] = [0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02];
|
const USB_PREFIX1: [u8; 7] = [0x5e, 0xc0, 0x02, 0x01, 0x00, 0x73, 0x02];
|
||||||
|
/// Second packet is for GA401 + GA402
|
||||||
const USB_PREFIX2: [u8; 7] = [0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02];
|
const USB_PREFIX2: [u8; 7] = [0x5e, 0xc0, 0x02, 0x74, 0x02, 0x73, 0x02];
|
||||||
|
/// Third packet is for GA402 matrix
|
||||||
|
const USB_PREFIX3: [u8; 7] = [0x5e, 0xc0, 0x02, 0xe7, 0x04, 0x73, 0x02];
|
||||||
|
|
||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
#[derive(Debug, PartialEq, Copy, Clone, Deserialize, Serialize)]
|
#[derive(Debug, PartialEq, Copy, Clone, Deserialize, Serialize)]
|
||||||
@@ -30,34 +35,46 @@ pub struct AnimePowerStates {
|
|||||||
pub boot_anim_enabled: bool,
|
pub boot_anim_enabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
|
#[derive(Debug, Copy, Clone, Deserialize, Serialize)]
|
||||||
|
pub enum AnimeType {
|
||||||
|
GA401,
|
||||||
|
GA402,
|
||||||
|
}
|
||||||
|
|
||||||
/// The minimal serializable data that can be transferred over wire types.
|
/// The minimal serializable data that can be transferred over wire types.
|
||||||
/// Other data structures in `rog_anime` will convert to this.
|
/// Other data structures in `rog_anime` will convert to this.
|
||||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct AnimeDataBuffer(Vec<u8>);
|
pub struct AnimeDataBuffer {
|
||||||
|
data: Vec<u8>,
|
||||||
impl Default for AnimeDataBuffer {
|
anime: AnimeType,
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnimeDataBuffer {
|
impl AnimeDataBuffer {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new(anime: AnimeType) -> Self {
|
||||||
AnimeDataBuffer(vec![0u8; ANIME_DATA_LEN])
|
let len = match anime {
|
||||||
|
AnimeType::GA401 => ANIME_GA401_DATA_LEN,
|
||||||
|
AnimeType::GA402 => ANIME_GA402_DATA_LEN,
|
||||||
|
};
|
||||||
|
|
||||||
|
AnimeDataBuffer {
|
||||||
|
data: vec![0u8; len],
|
||||||
|
anime,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the inner data buffer
|
/// Get the inner data buffer
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get(&self) -> &[u8] {
|
pub fn data(&self) -> &[u8] {
|
||||||
&self.0
|
&self.data
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a mutable slice of the inner buffer
|
/// Get a mutable slice of the inner buffer
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_mut(&mut self) -> &mut [u8] {
|
pub fn data_mut(&mut self) -> &mut [u8] {
|
||||||
&mut self.0
|
&mut self.data
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create from a vector of bytes
|
/// Create from a vector of bytes
|
||||||
@@ -65,25 +82,41 @@ impl AnimeDataBuffer {
|
|||||||
/// # Panics
|
/// # Panics
|
||||||
/// Will panic if the vector length is not `ANIME_DATA_LEN`
|
/// Will panic if the vector length is not `ANIME_DATA_LEN`
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_vec(input: Vec<u8>) -> Self {
|
pub fn from_vec(anime: AnimeType, data: Vec<u8>) -> Self {
|
||||||
assert_eq!(input.len(), ANIME_DATA_LEN);
|
match anime {
|
||||||
Self(input)
|
AnimeType::GA401 => assert_eq!(data.len(), ANIME_GA401_DATA_LEN),
|
||||||
|
AnimeType::GA402 => assert_eq!(data.len(), ANIME_GA402_DATA_LEN),
|
||||||
|
}
|
||||||
|
Self { data, anime }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The two packets to be written to USB
|
/// The two packets to be written to USB
|
||||||
pub type AnimePacketType = [[u8; 640]; 2];
|
pub type AnimePacketType = Vec<[u8; 640]>;
|
||||||
|
|
||||||
impl From<AnimeDataBuffer> for AnimePacketType {
|
impl From<AnimeDataBuffer> for AnimePacketType {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(anime: AnimeDataBuffer) -> Self {
|
fn from(anime: AnimeDataBuffer) -> Self {
|
||||||
assert!(anime.0.len() == ANIME_DATA_LEN);
|
let mut buffers = match anime.anime {
|
||||||
let mut buffers = [[0; 640]; 2];
|
AnimeType::GA401 => {
|
||||||
for (idx, chunk) in anime.0.as_slice().chunks(PANE_LEN).enumerate() {
|
assert!(anime.data.len() == ANIME_GA401_DATA_LEN);
|
||||||
|
vec![[0; 640]; 2]
|
||||||
|
}
|
||||||
|
AnimeType::GA402 => {
|
||||||
|
assert!(anime.data.len() == ANIME_GA402_DATA_LEN);
|
||||||
|
vec![[0; 640]; 3]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (idx, chunk) in anime.data.as_slice().chunks(PANE_LEN).enumerate() {
|
||||||
buffers[idx][BLOCK_START..BLOCK_END].copy_from_slice(chunk);
|
buffers[idx][BLOCK_START..BLOCK_END].copy_from_slice(chunk);
|
||||||
}
|
}
|
||||||
buffers[0][..7].copy_from_slice(&USB_PREFIX1);
|
buffers[0][..7].copy_from_slice(&USB_PREFIX1);
|
||||||
buffers[1][..7].copy_from_slice(&USB_PREFIX2);
|
buffers[1][..7].copy_from_slice(&USB_PREFIX2);
|
||||||
|
|
||||||
|
if matches!(anime.anime, AnimeType::GA402) {
|
||||||
|
buffers[2][..7].copy_from_slice(&USB_PREFIX3);
|
||||||
|
}
|
||||||
buffers
|
buffers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -142,7 +175,7 @@ pub fn run_animation(
|
|||||||
|
|
||||||
if let AnimTime::Fade(_) = frames.duration() {
|
if let AnimTime::Fade(_) = frames.duration() {
|
||||||
if frame_start <= start + fade_in {
|
if frame_start <= start + fade_in {
|
||||||
for pixel in output.get_mut() {
|
for pixel in output.data_mut() {
|
||||||
*pixel = (*pixel as f32 * fade_in_accum) as u8;
|
*pixel = (*pixel as f32 * fade_in_accum) as u8;
|
||||||
}
|
}
|
||||||
fade_in_accum = fade_in_step * (frame_start - start).as_secs_f32();
|
fade_in_accum = fade_in_step * (frame_start - start).as_secs_f32();
|
||||||
@@ -153,7 +186,7 @@ pub fn run_animation(
|
|||||||
} else {
|
} else {
|
||||||
fade_out_accum = 0.0;
|
fade_out_accum = 0.0;
|
||||||
}
|
}
|
||||||
for pixel in output.get_mut() {
|
for pixel in output.data_mut() {
|
||||||
*pixel = (*pixel as f32 * fade_out_accum) as u8;
|
*pixel = (*pixel as f32 * fade_out_accum) as u8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
use std::{path::Path, time::Duration};
|
use std::{path::Path, time::Duration};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
data::{AnimeDataBuffer, ANIME_DATA_LEN},
|
data::{AnimeDataBuffer, ANIME_GA401_DATA_LEN},
|
||||||
error::AnimeError,
|
error::AnimeError,
|
||||||
|
AnimeType, ANIME_GA402_DATA_LEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
const WIDTH: usize = 74;
|
const WIDTH: usize = 74;
|
||||||
|
// TODO: Change for GA402
|
||||||
const HEIGHT: usize = 36;
|
const HEIGHT: usize = 36;
|
||||||
|
|
||||||
/// Mostly intended to be used with ASUS gifs, but can be used for other purposes (like images)
|
/// Mostly intended to be used with ASUS gifs, but can be used for other purposes (like images)
|
||||||
@@ -127,71 +129,262 @@ impl AnimeDiagonal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&AnimeDiagonal> for AnimeDataBuffer {
|
/// Convert to a data buffer that can be sent over dbus
|
||||||
|
#[inline]
|
||||||
|
pub fn into_data_buffer(&self, anime_type: AnimeType) -> AnimeDataBuffer {
|
||||||
|
match anime_type {
|
||||||
|
AnimeType::GA401 => self.into_ga401_packets(),
|
||||||
|
AnimeType::GA402 => self.into_ga402_packets(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Do conversion from the nested Vec in AnimeMatrix to the two required
|
/// Do conversion from the nested Vec in AnimeMatrix to the two required
|
||||||
/// packets suitable for sending over USB
|
/// packets suitable for sending over USB
|
||||||
#[inline]
|
fn into_ga401_packets(&self) -> AnimeDataBuffer {
|
||||||
fn from(anime: &AnimeDiagonal) -> Self {
|
let mut buf = vec![0u8; ANIME_GA401_DATA_LEN];
|
||||||
let mut buf = vec![0u8; ANIME_DATA_LEN];
|
|
||||||
|
|
||||||
buf[1..=32].copy_from_slice(&anime.get_row(0, 3, 32));
|
buf[1..=32].copy_from_slice(&self.get_row(0, 3, 32));
|
||||||
buf[34..=66].copy_from_slice(&anime.get_row(0, 2, 33));
|
buf[34..=66].copy_from_slice(&self.get_row(0, 2, 33));
|
||||||
buf[69..=101].copy_from_slice(&anime.get_row(1, 2, 33)); // ?!
|
buf[69..=101].copy_from_slice(&self.get_row(1, 2, 33)); // ?!
|
||||||
buf[102..=134].copy_from_slice(&anime.get_row(1, 1, 33));
|
buf[102..=134].copy_from_slice(&self.get_row(1, 1, 33));
|
||||||
buf[137..=169].copy_from_slice(&anime.get_row(2, 1, 33));
|
buf[137..=169].copy_from_slice(&self.get_row(2, 1, 33));
|
||||||
buf[170..=202].copy_from_slice(&anime.get_row(2, 0, 33));
|
buf[170..=202].copy_from_slice(&self.get_row(2, 0, 33));
|
||||||
buf[204..=236].copy_from_slice(&anime.get_row(3, 0, 33));
|
buf[204..=236].copy_from_slice(&self.get_row(3, 0, 33));
|
||||||
buf[237..=268].copy_from_slice(&anime.get_row(4, 0, 32));
|
buf[237..=268].copy_from_slice(&self.get_row(4, 0, 32));
|
||||||
buf[270..=301].copy_from_slice(&anime.get_row(5, 0, 32));
|
buf[270..=301].copy_from_slice(&self.get_row(5, 0, 32));
|
||||||
buf[302..=332].copy_from_slice(&anime.get_row(6, 0, 31));
|
buf[302..=332].copy_from_slice(&self.get_row(6, 0, 31));
|
||||||
buf[334..=364].copy_from_slice(&anime.get_row(7, 0, 31));
|
buf[334..=364].copy_from_slice(&self.get_row(7, 0, 31));
|
||||||
buf[365..=394].copy_from_slice(&anime.get_row(8, 0, 30));
|
buf[365..=394].copy_from_slice(&self.get_row(8, 0, 30));
|
||||||
buf[396..=425].copy_from_slice(&anime.get_row(9, 0, 30));
|
buf[396..=425].copy_from_slice(&self.get_row(9, 0, 30));
|
||||||
buf[426..=454].copy_from_slice(&anime.get_row(10, 0, 29));
|
buf[426..=454].copy_from_slice(&self.get_row(10, 0, 29));
|
||||||
buf[456..=484].copy_from_slice(&anime.get_row(11, 0, 29));
|
buf[456..=484].copy_from_slice(&self.get_row(11, 0, 29));
|
||||||
buf[485..=512].copy_from_slice(&anime.get_row(12, 0, 28));
|
buf[485..=512].copy_from_slice(&self.get_row(12, 0, 28));
|
||||||
buf[514..=541].copy_from_slice(&anime.get_row(13, 0, 28));
|
buf[514..=541].copy_from_slice(&self.get_row(13, 0, 28));
|
||||||
buf[542..=568].copy_from_slice(&anime.get_row(14, 0, 27));
|
buf[542..=568].copy_from_slice(&self.get_row(14, 0, 27));
|
||||||
buf[570..=596].copy_from_slice(&anime.get_row(15, 0, 27));
|
buf[570..=596].copy_from_slice(&self.get_row(15, 0, 27));
|
||||||
buf[597..=622].copy_from_slice(&anime.get_row(16, 0, 26));
|
buf[597..=622].copy_from_slice(&self.get_row(16, 0, 26));
|
||||||
buf[624..=649].copy_from_slice(&anime.get_row(17, 0, 26));
|
buf[624..=649].copy_from_slice(&self.get_row(17, 0, 26));
|
||||||
buf[650..=674].copy_from_slice(&anime.get_row(18, 0, 25));
|
buf[650..=674].copy_from_slice(&self.get_row(18, 0, 25));
|
||||||
buf[676..=700].copy_from_slice(&anime.get_row(19, 0, 25));
|
buf[676..=700].copy_from_slice(&self.get_row(19, 0, 25));
|
||||||
buf[701..=724].copy_from_slice(&anime.get_row(20, 0, 24));
|
buf[701..=724].copy_from_slice(&self.get_row(20, 0, 24));
|
||||||
buf[726..=749].copy_from_slice(&anime.get_row(21, 0, 24));
|
buf[726..=749].copy_from_slice(&self.get_row(21, 0, 24));
|
||||||
buf[750..=772].copy_from_slice(&anime.get_row(22, 0, 23));
|
buf[750..=772].copy_from_slice(&self.get_row(22, 0, 23));
|
||||||
buf[774..=796].copy_from_slice(&anime.get_row(23, 0, 23));
|
buf[774..=796].copy_from_slice(&self.get_row(23, 0, 23));
|
||||||
buf[797..=818].copy_from_slice(&anime.get_row(24, 0, 22));
|
buf[797..=818].copy_from_slice(&self.get_row(24, 0, 22));
|
||||||
buf[820..=841].copy_from_slice(&anime.get_row(25, 0, 22));
|
buf[820..=841].copy_from_slice(&self.get_row(25, 0, 22));
|
||||||
buf[842..=862].copy_from_slice(&anime.get_row(26, 0, 21));
|
buf[842..=862].copy_from_slice(&self.get_row(26, 0, 21));
|
||||||
buf[864..=884].copy_from_slice(&anime.get_row(27, 0, 21));
|
buf[864..=884].copy_from_slice(&self.get_row(27, 0, 21));
|
||||||
buf[885..=904].copy_from_slice(&anime.get_row(28, 0, 20));
|
buf[885..=904].copy_from_slice(&self.get_row(28, 0, 20));
|
||||||
buf[906..=925].copy_from_slice(&anime.get_row(29, 0, 20));
|
buf[906..=925].copy_from_slice(&self.get_row(29, 0, 20));
|
||||||
buf[926..=944].copy_from_slice(&anime.get_row(30, 0, 19));
|
buf[926..=944].copy_from_slice(&self.get_row(30, 0, 19));
|
||||||
buf[946..=964].copy_from_slice(&anime.get_row(31, 0, 19));
|
buf[946..=964].copy_from_slice(&self.get_row(31, 0, 19));
|
||||||
buf[965..=982].copy_from_slice(&anime.get_row(32, 0, 18));
|
buf[965..=982].copy_from_slice(&self.get_row(32, 0, 18));
|
||||||
buf[984..=1001].copy_from_slice(&anime.get_row(33, 0, 18));
|
buf[984..=1001].copy_from_slice(&self.get_row(33, 0, 18));
|
||||||
buf[1002..=1018].copy_from_slice(&anime.get_row(34, 0, 17));
|
buf[1002..=1018].copy_from_slice(&self.get_row(34, 0, 17));
|
||||||
buf[1020..=1036].copy_from_slice(&anime.get_row(35, 0, 17));
|
buf[1020..=1036].copy_from_slice(&self.get_row(35, 0, 17));
|
||||||
buf[1037..=1052].copy_from_slice(&anime.get_row(36, 0, 16));
|
buf[1037..=1052].copy_from_slice(&self.get_row(36, 0, 16));
|
||||||
buf[1054..=1069].copy_from_slice(&anime.get_row(37, 0, 16));
|
buf[1054..=1069].copy_from_slice(&self.get_row(37, 0, 16));
|
||||||
buf[1070..=1084].copy_from_slice(&anime.get_row(38, 0, 15));
|
buf[1070..=1084].copy_from_slice(&self.get_row(38, 0, 15));
|
||||||
buf[1086..=1100].copy_from_slice(&anime.get_row(39, 0, 15));
|
buf[1086..=1100].copy_from_slice(&self.get_row(39, 0, 15));
|
||||||
buf[1101..=1114].copy_from_slice(&anime.get_row(40, 0, 14));
|
buf[1101..=1114].copy_from_slice(&self.get_row(40, 0, 14));
|
||||||
buf[1116..=1129].copy_from_slice(&anime.get_row(41, 0, 14));
|
buf[1116..=1129].copy_from_slice(&self.get_row(41, 0, 14));
|
||||||
buf[1130..=1142].copy_from_slice(&anime.get_row(42, 0, 13));
|
buf[1130..=1142].copy_from_slice(&self.get_row(42, 0, 13));
|
||||||
buf[1144..=1156].copy_from_slice(&anime.get_row(43, 0, 13));
|
buf[1144..=1156].copy_from_slice(&self.get_row(43, 0, 13));
|
||||||
buf[1157..=1168].copy_from_slice(&anime.get_row(44, 0, 12));
|
buf[1157..=1168].copy_from_slice(&self.get_row(44, 0, 12));
|
||||||
buf[1170..=1181].copy_from_slice(&anime.get_row(45, 0, 12));
|
buf[1170..=1181].copy_from_slice(&self.get_row(45, 0, 12));
|
||||||
buf[1182..=1192].copy_from_slice(&anime.get_row(46, 0, 11));
|
buf[1182..=1192].copy_from_slice(&self.get_row(46, 0, 11));
|
||||||
buf[1194..=1204].copy_from_slice(&anime.get_row(47, 0, 11));
|
buf[1194..=1204].copy_from_slice(&self.get_row(47, 0, 11));
|
||||||
buf[1205..=1214].copy_from_slice(&anime.get_row(48, 0, 10));
|
buf[1205..=1214].copy_from_slice(&self.get_row(48, 0, 10));
|
||||||
buf[1216..=1225].copy_from_slice(&anime.get_row(49, 0, 10));
|
buf[1216..=1225].copy_from_slice(&self.get_row(49, 0, 10));
|
||||||
buf[1226..=1234].copy_from_slice(&anime.get_row(50, 0, 9));
|
buf[1226..=1234].copy_from_slice(&self.get_row(50, 0, 9));
|
||||||
buf[1236..=1244].copy_from_slice(&anime.get_row(51, 0, 9));
|
buf[1236..=1244].copy_from_slice(&self.get_row(51, 0, 9));
|
||||||
|
|
||||||
AnimeDataBuffer::from_vec(buf)
|
AnimeDataBuffer::from_vec(crate::AnimeType::GA401, buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_ga402_packets(&self) -> AnimeDataBuffer {
|
||||||
|
let mut buf = vec![0u8; ANIME_GA402_DATA_LEN];
|
||||||
|
let mut start_index: usize = 0;
|
||||||
|
|
||||||
|
fn copy_slice(
|
||||||
|
buf: &mut Vec<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, 0, 5, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 1, 5, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 1, 4, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 2, 4, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 2, 3, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 3, 3, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 3, 2, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 4, 2, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 4, 1, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 5, 1, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 5, 0, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 6, 0, &mut start_index, 34);
|
||||||
|
copy_slice(b, a, 7, 0, &mut start_index, 33);
|
||||||
|
copy_slice(b, a, 8, 0, &mut start_index, 33);
|
||||||
|
copy_slice(b, a, 9, 0, &mut start_index, 32);
|
||||||
|
copy_slice(b, a, 10, 0, &mut start_index, 32);
|
||||||
|
copy_slice(b, a, 11, 0, &mut start_index, 31);
|
||||||
|
copy_slice(b, a, 12, 0, &mut start_index, 31);
|
||||||
|
copy_slice(b, a, 13, 0, &mut start_index, 30);
|
||||||
|
copy_slice(b, a, 14, 0, &mut start_index, 30);
|
||||||
|
copy_slice(b, a, 15, 0, &mut start_index, 29);
|
||||||
|
copy_slice(b, a, 16, 0, &mut start_index, 29);
|
||||||
|
copy_slice(b, a, 17, 0, &mut start_index, 28);
|
||||||
|
copy_slice(b, a, 18, 0, &mut start_index, 28);
|
||||||
|
copy_slice(b, a, 19, 0, &mut start_index, 27);
|
||||||
|
copy_slice(b, a, 20, 0, &mut start_index, 27);
|
||||||
|
copy_slice(b, a, 21, 0, &mut start_index, 26);
|
||||||
|
copy_slice(b, a, 22, 0, &mut start_index, 26);
|
||||||
|
copy_slice(b, a, 23, 0, &mut start_index, 25);
|
||||||
|
copy_slice(b, a, 24, 0, &mut start_index, 25);
|
||||||
|
copy_slice(b, a, 25, 0, &mut start_index, 24);
|
||||||
|
copy_slice(b, a, 26, 0, &mut start_index, 24);
|
||||||
|
copy_slice(b, a, 27, 0, &mut start_index, 23);
|
||||||
|
copy_slice(b, a, 28, 0, &mut start_index, 23);
|
||||||
|
copy_slice(b, a, 29, 0, &mut start_index, 22);
|
||||||
|
copy_slice(b, a, 30, 0, &mut start_index, 22);
|
||||||
|
copy_slice(b, a, 31, 0, &mut start_index, 21);
|
||||||
|
copy_slice(b, a, 32, 0, &mut start_index, 21);
|
||||||
|
copy_slice(b, a, 33, 0, &mut start_index, 20);
|
||||||
|
copy_slice(b, a, 34, 0, &mut start_index, 20);
|
||||||
|
copy_slice(b, a, 35, 0, &mut start_index, 19);
|
||||||
|
copy_slice(b, a, 36, 0, &mut start_index, 19);
|
||||||
|
copy_slice(b, a, 37, 0, &mut start_index, 18);
|
||||||
|
copy_slice(b, a, 38, 0, &mut start_index, 18);
|
||||||
|
copy_slice(b, a, 39, 0, &mut start_index, 17);
|
||||||
|
copy_slice(b, a, 40, 0, &mut start_index, 17);
|
||||||
|
copy_slice(b, a, 41, 0, &mut start_index, 16);
|
||||||
|
copy_slice(b, a, 42, 0, &mut start_index, 16);
|
||||||
|
copy_slice(b, a, 43, 0, &mut start_index, 15);
|
||||||
|
copy_slice(b, a, 44, 0, &mut start_index, 15);
|
||||||
|
copy_slice(b, a, 45, 0, &mut start_index, 14);
|
||||||
|
copy_slice(b, a, 46, 0, &mut start_index, 14);
|
||||||
|
copy_slice(b, a, 47, 0, &mut start_index, 13);
|
||||||
|
copy_slice(b, a, 48, 0, &mut start_index, 13);
|
||||||
|
copy_slice(b, a, 49, 0, &mut start_index, 12);
|
||||||
|
copy_slice(b, a, 50, 0, &mut start_index, 12);
|
||||||
|
copy_slice(b, a, 51, 0, &mut start_index, 11);
|
||||||
|
copy_slice(b, a, 52, 0, &mut start_index, 11);
|
||||||
|
copy_slice(b, a, 53, 0, &mut start_index, 10);
|
||||||
|
copy_slice(b, a, 54, 0, &mut start_index, 10);
|
||||||
|
copy_slice(b, a, 55, 0, &mut start_index, 9);
|
||||||
|
|
||||||
|
AnimeDataBuffer::from_vec(crate::AnimeType::GA402, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
use crate::{AnimeDiagonal, AnimePacketType};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn ga401_diagonal_packet_check() {
|
||||||
|
let pkt0_check = [
|
||||||
|
0x5e, 0xc0, 0x2, 0x1, 0x0, 0x73, 0x2, 0x0, 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, 0x0, 0xff, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0xff, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0x0, 0xff, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff,
|
||||||
|
0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0,
|
||||||
|
];
|
||||||
|
let pkt1_check = [
|
||||||
|
0x5e, 0xc0, 0x2, 0x74, 0x2, 0x73, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
];
|
||||||
|
|
||||||
|
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
path.push("test/ga401-diagonal.png");
|
||||||
|
|
||||||
|
let matrix = AnimeDiagonal::from_png(&path, None, 255.0).unwrap();
|
||||||
|
let data = matrix.into_data_buffer(crate::AnimeType::GA401);
|
||||||
|
let pkt = AnimePacketType::from(data);
|
||||||
|
|
||||||
|
assert_eq!(pkt[0], pkt0_check);
|
||||||
|
assert_eq!(pkt[1], pkt1_check);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,9 @@ pub enum AnimeError {
|
|||||||
/// The input was incorrect size, expected size is `IncorrectSize(width, height)`
|
/// The input was incorrect size, expected size is `IncorrectSize(width, height)`
|
||||||
IncorrectSize(u32, u32),
|
IncorrectSize(u32, u32),
|
||||||
Dbus(String),
|
Dbus(String),
|
||||||
|
Udev(String, std::io::Error),
|
||||||
|
NoDevice,
|
||||||
|
UnsupportedDevice,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for AnimeError {
|
impl fmt::Display for AnimeError {
|
||||||
@@ -30,6 +33,9 @@ impl fmt::Display for AnimeError {
|
|||||||
width, height
|
width, height
|
||||||
),
|
),
|
||||||
AnimeError::Dbus(detail) => write!(f, "{}", detail),
|
AnimeError::Dbus(detail) => write!(f, "{}", detail),
|
||||||
|
AnimeError::Udev(deets, error) => write!(f, "udev {}: {}", deets, error),
|
||||||
|
AnimeError::NoDevice => write!(f, "No AniMe Matrix device found"),
|
||||||
|
AnimeError::UnsupportedDevice => write!(f, "Unsupported AniMe Matrix device found"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use glam::Vec2;
|
|||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::{fs::File, path::Path, time::Duration};
|
use std::{fs::File, path::Path, time::Duration};
|
||||||
|
|
||||||
use crate::{error::AnimeError, AnimeDataBuffer, AnimeDiagonal, AnimeImage, Pixel};
|
use crate::{error::AnimeError, AnimeDataBuffer, AnimeDiagonal, AnimeImage, AnimeType, Pixel};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||||
pub struct AnimeFrame {
|
pub struct AnimeFrame {
|
||||||
@@ -90,8 +90,10 @@ impl AnimeGif {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_diagonal_gif(
|
pub fn from_diagonal_gif(
|
||||||
file_name: &Path,
|
file_name: &Path,
|
||||||
|
|
||||||
duration: AnimTime,
|
duration: AnimTime,
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
|
anime_type: AnimeType,
|
||||||
) -> Result<Self, AnimeError> {
|
) -> Result<Self, AnimeError> {
|
||||||
let mut matrix = AnimeDiagonal::new(None);
|
let mut matrix = AnimeDiagonal::new(None);
|
||||||
|
|
||||||
@@ -121,7 +123,7 @@ impl AnimeGif {
|
|||||||
}
|
}
|
||||||
|
|
||||||
frames.push(AnimeFrame {
|
frames.push(AnimeFrame {
|
||||||
data: <AnimeDataBuffer>::from(&matrix),
|
data: matrix.into_data_buffer(anime_type),
|
||||||
delay: Duration::from_millis(wait as u64),
|
delay: Duration::from_millis(wait as u64),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -132,6 +134,7 @@ impl AnimeGif {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_diagonal_png(
|
pub fn from_diagonal_png(
|
||||||
file_name: &Path,
|
file_name: &Path,
|
||||||
|
anime_type: AnimeType,
|
||||||
duration: AnimTime,
|
duration: AnimTime,
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
) -> Result<Self, AnimeError> {
|
) -> Result<Self, AnimeError> {
|
||||||
@@ -148,7 +151,7 @@ impl AnimeGif {
|
|||||||
let frame_count = total.as_millis() / 30;
|
let frame_count = total.as_millis() / 30;
|
||||||
|
|
||||||
let single = AnimeFrame {
|
let single = AnimeFrame {
|
||||||
data: <AnimeDataBuffer>::from(&image),
|
data: image.into_data_buffer(anime_type),
|
||||||
delay: Duration::from_millis(30),
|
delay: Duration::from_millis(30),
|
||||||
};
|
};
|
||||||
let frames = vec![single; frame_count as usize];
|
let frames = vec![single; frame_count as usize];
|
||||||
@@ -166,6 +169,7 @@ impl AnimeGif {
|
|||||||
translation: Vec2,
|
translation: Vec2,
|
||||||
duration: AnimTime,
|
duration: AnimTime,
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
|
anime_type: AnimeType,
|
||||||
) -> Result<Self, AnimeError> {
|
) -> Result<Self, AnimeError> {
|
||||||
let mut frames = Vec::new();
|
let mut frames = Vec::new();
|
||||||
|
|
||||||
@@ -187,6 +191,7 @@ impl AnimeGif {
|
|||||||
brightness,
|
brightness,
|
||||||
pixels,
|
pixels,
|
||||||
decoder.width() as u32,
|
decoder.width() as u32,
|
||||||
|
anime_type,
|
||||||
);
|
);
|
||||||
|
|
||||||
while let Some(frame) = decoder.read_next_frame()? {
|
while let Some(frame) = decoder.read_next_frame()? {
|
||||||
@@ -201,6 +206,7 @@ impl AnimeGif {
|
|||||||
brightness,
|
brightness,
|
||||||
pixels,
|
pixels,
|
||||||
width as u32,
|
width as u32,
|
||||||
|
anime_type,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for (y, row) in frame.buffer.chunks(frame.width as usize * 4).enumerate() {
|
for (y, row) in frame.buffer.chunks(frame.width as usize * 4).enumerate() {
|
||||||
@@ -238,8 +244,10 @@ impl AnimeGif {
|
|||||||
translation: Vec2,
|
translation: Vec2,
|
||||||
duration: AnimTime,
|
duration: AnimTime,
|
||||||
brightness: f32,
|
brightness: f32,
|
||||||
|
anime_type: AnimeType,
|
||||||
) -> Result<Self, AnimeError> {
|
) -> Result<Self, AnimeError> {
|
||||||
let image = AnimeImage::from_png(file_name, scale, angle, translation, brightness)?;
|
let image =
|
||||||
|
AnimeImage::from_png(file_name, scale, angle, translation, brightness, anime_type)?;
|
||||||
|
|
||||||
let mut total = Duration::from_millis(1000);
|
let mut total = Duration::from_millis(1000);
|
||||||
if let AnimTime::Fade(fade) = duration {
|
if let AnimTime::Fade(fade) = duration {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
use std::time::Duration;
|
use crate::data::{AnimeDataBuffer, ANIME_GA401_DATA_LEN};
|
||||||
|
use crate::{AnimeImage, AnimeType, ANIME_GA402_DATA_LEN};
|
||||||
use crate::data::{AnimeDataBuffer, ANIME_DATA_LEN};
|
|
||||||
use crate::image::LED_IMAGE_POSITIONS;
|
|
||||||
|
|
||||||
|
// TODO: Adjust these sizes as WIDTH_GA401 WIDTH_GA402
|
||||||
const WIDTH: usize = 33;
|
const WIDTH: usize = 33;
|
||||||
const HEIGHT: usize = 55;
|
const HEIGHT: usize = 55;
|
||||||
|
|
||||||
@@ -14,41 +13,40 @@ const HEIGHT: usize = 55;
|
|||||||
///
|
///
|
||||||
/// **Note:** the columns in each odd row are offset by half a pixel left
|
/// **Note:** the columns in each odd row are offset by half a pixel left
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct AnimeGrid([[u8; WIDTH]; HEIGHT], Option<Duration>);
|
pub struct AnimeGrid {
|
||||||
|
anime_type: AnimeType,
|
||||||
impl Default for AnimeGrid {
|
data: [[u8; WIDTH]; HEIGHT],
|
||||||
#[inline]
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new(None)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AnimeGrid {
|
impl AnimeGrid {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(duration: Option<Duration>) -> Self {
|
pub fn new(anime_type: AnimeType) -> Self {
|
||||||
AnimeGrid([[0u8; WIDTH]; HEIGHT], duration)
|
Self {
|
||||||
|
anime_type,
|
||||||
|
data: [[0u8; WIDTH]; HEIGHT],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a position in the grid with a brightness value
|
/// Set a position in the grid with a brightness value
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set(&mut self, x: usize, y: usize, b: u8) {
|
pub fn set(&mut self, x: usize, y: usize, b: u8) {
|
||||||
self.0[y][x] = b;
|
self.data[y][x] = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get(&self) -> &[[u8; WIDTH]; HEIGHT] {
|
pub fn get(&self) -> &[[u8; WIDTH]; HEIGHT] {
|
||||||
&self.0
|
&self.data
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_mut(&mut self) -> &mut [[u8; WIDTH]; HEIGHT] {
|
pub fn get_mut(&mut self) -> &mut [[u8; WIDTH]; HEIGHT] {
|
||||||
&mut self.0
|
&mut self.data
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fill the grid with a value
|
/// Fill the grid with a value
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fill_with(&mut self, fill: u8) {
|
pub fn fill_with(&mut self, fill: u8) {
|
||||||
for row in self.0.iter_mut() {
|
for row in self.data.iter_mut() {
|
||||||
for x in row.iter_mut() {
|
for x in row.iter_mut() {
|
||||||
*x = fill;
|
*x = fill;
|
||||||
}
|
}
|
||||||
@@ -94,16 +92,22 @@ impl From<AnimeGrid> for AnimeDataBuffer {
|
|||||||
/// packets suitable for sending over USB
|
/// packets suitable for sending over USB
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(anime: AnimeGrid) -> Self {
|
fn from(anime: AnimeGrid) -> Self {
|
||||||
let mut buf = vec![0u8; ANIME_DATA_LEN];
|
let mut buf = match anime.anime_type {
|
||||||
|
AnimeType::GA401 => vec![0u8; ANIME_GA401_DATA_LEN],
|
||||||
|
AnimeType::GA402 => vec![0u8; ANIME_GA402_DATA_LEN],
|
||||||
|
};
|
||||||
|
|
||||||
for (idx, pos) in LED_IMAGE_POSITIONS.iter().enumerate() {
|
for (idx, pos) in AnimeImage::generate_image_positioning(anime.anime_type)
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
{
|
||||||
if let Some(pos) = pos {
|
if let Some(pos) = pos {
|
||||||
let x = pos.x().ceil() as usize;
|
let x = pos.x().ceil() as usize;
|
||||||
let y = pos.y().ceil() as usize;
|
let y = pos.y().ceil() as usize;
|
||||||
buf[idx + 1] = anime.0[y][x];
|
buf[idx + 1] = anime.data[y][x];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AnimeDataBuffer::from_vec(buf)
|
AnimeDataBuffer::from_vec(anime.anime_type, buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +117,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check_data_alignment() {
|
fn check_data_alignment() {
|
||||||
let mut matrix = AnimeGrid::new(None);
|
let mut matrix = AnimeGrid::new(AnimeType::GA401);
|
||||||
{
|
{
|
||||||
let tmp = matrix.get_mut();
|
let tmp = matrix.get_mut();
|
||||||
for row in tmp.iter_mut() {
|
for row in tmp.iter_mut() {
|
||||||
@@ -171,6 +175,6 @@ mod tests {
|
|||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
];
|
];
|
||||||
assert_eq!(matrix.get(), &data_cmp);
|
assert_eq!(matrix.data(), &data_cmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,9 @@ use std::{path::PathBuf, time::Duration};
|
|||||||
use glam::Vec2;
|
use glam::Vec2;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::{error::AnimeError, AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage};
|
use crate::{
|
||||||
|
error::AnimeError, AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType,
|
||||||
|
};
|
||||||
|
|
||||||
/// All the possible AniMe actions that can be used. This enum is intended to be
|
/// All the possible AniMe actions that can be used. This enum is intended to be
|
||||||
/// a helper for loading up `ActionData`.
|
/// a helper for loading up `ActionData`.
|
||||||
@@ -63,13 +65,21 @@ pub enum ActionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ActionData {
|
impl ActionData {
|
||||||
pub fn from_anime_action(action: &ActionLoader) -> Result<ActionData, AnimeError> {
|
pub fn from_anime_action(
|
||||||
|
anime_type: AnimeType,
|
||||||
|
action: &ActionLoader,
|
||||||
|
) -> Result<ActionData, AnimeError> {
|
||||||
let a = match action {
|
let a = match action {
|
||||||
ActionLoader::AsusAnimation {
|
ActionLoader::AsusAnimation {
|
||||||
file,
|
file,
|
||||||
time,
|
time,
|
||||||
brightness,
|
brightness,
|
||||||
} => ActionData::Animation(AnimeGif::from_diagonal_gif(file, *time, *brightness)?),
|
} => ActionData::Animation(AnimeGif::from_diagonal_gif(
|
||||||
|
file,
|
||||||
|
*time,
|
||||||
|
*brightness,
|
||||||
|
anime_type,
|
||||||
|
)?),
|
||||||
ActionLoader::AsusImage {
|
ActionLoader::AsusImage {
|
||||||
file,
|
file,
|
||||||
time,
|
time,
|
||||||
@@ -77,10 +87,15 @@ impl ActionData {
|
|||||||
} => match time {
|
} => match time {
|
||||||
AnimTime::Infinite => {
|
AnimTime::Infinite => {
|
||||||
let image = AnimeDiagonal::from_png(file, None, *brightness)?;
|
let image = AnimeDiagonal::from_png(file, None, *brightness)?;
|
||||||
let data = <AnimeDataBuffer>::from(&image);
|
let data = image.into_data_buffer(anime_type);
|
||||||
ActionData::Image(Box::new(data))
|
ActionData::Image(Box::new(data))
|
||||||
}
|
}
|
||||||
_ => ActionData::Animation(AnimeGif::from_diagonal_png(file, *time, *brightness)?),
|
_ => ActionData::Animation(AnimeGif::from_diagonal_png(
|
||||||
|
file,
|
||||||
|
anime_type,
|
||||||
|
*time,
|
||||||
|
*brightness,
|
||||||
|
)?),
|
||||||
},
|
},
|
||||||
ActionLoader::ImageAnimation {
|
ActionLoader::ImageAnimation {
|
||||||
file,
|
file,
|
||||||
@@ -99,6 +114,7 @@ impl ActionData {
|
|||||||
*translation,
|
*translation,
|
||||||
*time,
|
*time,
|
||||||
*brightness,
|
*brightness,
|
||||||
|
anime_type,
|
||||||
)?));
|
)?));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -109,6 +125,7 @@ impl ActionData {
|
|||||||
*translation,
|
*translation,
|
||||||
*time,
|
*time,
|
||||||
*brightness,
|
*brightness,
|
||||||
|
anime_type,
|
||||||
)?)
|
)?)
|
||||||
}
|
}
|
||||||
ActionLoader::Image {
|
ActionLoader::Image {
|
||||||
@@ -122,8 +139,14 @@ impl ActionData {
|
|||||||
match time {
|
match time {
|
||||||
AnimTime::Infinite => {
|
AnimTime::Infinite => {
|
||||||
// If no time then create a plain static image
|
// If no time then create a plain static image
|
||||||
let image =
|
let image = AnimeImage::from_png(
|
||||||
AnimeImage::from_png(file, *scale, *angle, *translation, *brightness)?;
|
file,
|
||||||
|
*scale,
|
||||||
|
*angle,
|
||||||
|
*translation,
|
||||||
|
*brightness,
|
||||||
|
anime_type,
|
||||||
|
)?;
|
||||||
let data = <AnimeDataBuffer>::from(&image);
|
let data = <AnimeDataBuffer>::from(&image);
|
||||||
ActionData::Image(Box::new(data))
|
ActionData::Image(Box::new(data))
|
||||||
}
|
}
|
||||||
@@ -134,6 +157,7 @@ impl ActionData {
|
|||||||
*translation,
|
*translation,
|
||||||
*time,
|
*time,
|
||||||
*brightness,
|
*brightness,
|
||||||
|
anime_type,
|
||||||
)?),
|
)?),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,20 +168,21 @@ impl ActionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// An optimised precomputed set of actions that the user can cycle through
|
/// An optimised precomputed set of actions that the user can cycle through
|
||||||
#[derive(Debug, Deserialize, Serialize, Default)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct Sequences(Vec<ActionData>);
|
pub struct Sequences(Vec<ActionData>, AnimeType);
|
||||||
|
|
||||||
impl Sequences {
|
impl Sequences {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new(anime_type: AnimeType) -> Self {
|
||||||
Self(Vec::new())
|
Self(Vec::new(), anime_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Use a base `AnimeAction` to generate the precomputed data and insert in to
|
/// Use a base `AnimeAction` to generate the precomputed data and insert in to
|
||||||
/// the run buffer
|
/// the run buffer
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn insert(&mut self, index: usize, action: &ActionLoader) -> Result<(), AnimeError> {
|
pub fn insert(&mut self, index: usize, action: &ActionLoader) -> Result<(), AnimeError> {
|
||||||
self.0.insert(index, ActionData::from_anime_action(action)?);
|
self.0
|
||||||
|
.insert(index, ActionData::from_anime_action(self.1, action)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
//!
|
//!
|
||||||
//! Step 1 need to applied only on fresh system boot.
|
//! Step 1 need to applied only on fresh system boot.
|
||||||
|
|
||||||
|
use crate::{error::AnimeError, AnimeType};
|
||||||
|
|
||||||
const INIT_STR: [u8; 15] = [
|
const INIT_STR: [u8; 15] = [
|
||||||
0x5e, b'A', b'S', b'U', b'S', b' ', b'T', b'e', b'c', b'h', b'.', b'I', b'n', b'c', b'.',
|
0x5e, b'A', b'S', b'U', b'S', b' ', b'T', b'e', b'c', b'h', b'.', b'I', b'n', b'c', b'.',
|
||||||
];
|
];
|
||||||
@@ -15,6 +17,47 @@ const DEV_PAGE: u8 = 0x5e;
|
|||||||
pub const VENDOR_ID: u16 = 0x0b05;
|
pub const VENDOR_ID: u16 = 0x0b05;
|
||||||
pub const PROD_ID: u16 = 0x193b;
|
pub const PROD_ID: u16 = 0x193b;
|
||||||
|
|
||||||
|
/// `get_anime_type` is very broad, matching on part of the laptop board name only. For this
|
||||||
|
/// reason `find_node()` must be used also to verify if the USB device is available.
|
||||||
|
///
|
||||||
|
/// The currently known USB device is `19b6`.
|
||||||
|
#[inline]
|
||||||
|
pub fn get_anime_type() -> Result<AnimeType, AnimeError> {
|
||||||
|
let dmi = sysfs_class::DmiId::default();
|
||||||
|
let board_name = dmi.board_name()?;
|
||||||
|
|
||||||
|
if board_name.contains("GA401Q") {
|
||||||
|
return Ok(AnimeType::GA401);
|
||||||
|
} else if board_name.contains("GA401R") {
|
||||||
|
return Ok(AnimeType::GA402);
|
||||||
|
}
|
||||||
|
Err(AnimeError::UnsupportedDevice)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Find the USB device node - known devices so far: `19b6`
|
||||||
|
#[inline]
|
||||||
|
pub fn find_node(id_product: &str) -> Result<String, AnimeError> {
|
||||||
|
let mut enumerator =
|
||||||
|
udev::Enumerator::new().map_err(|err| AnimeError::Udev("enumerator failed".into(), err))?;
|
||||||
|
enumerator
|
||||||
|
.match_subsystem("usb")
|
||||||
|
.map_err(|err| AnimeError::Udev("match_subsystem failed".into(), err))?;
|
||||||
|
|
||||||
|
for device in enumerator
|
||||||
|
.scan_devices()
|
||||||
|
.map_err(|err| AnimeError::Udev("scan_devices failed".into(), err))?
|
||||||
|
{
|
||||||
|
if let Some(attr) = device.attribute_value("idProduct") {
|
||||||
|
if attr == id_product {
|
||||||
|
if let Some(dev_node) = device.devnode() {
|
||||||
|
return Ok(dev_node.to_string_lossy().to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(AnimeError::NoDevice)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the two device initialization packets. These are required for device start
|
/// Get the two device initialization packets. These are required for device start
|
||||||
/// after the laptop boots.
|
/// after the laptop boots.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|||||||
BIN
rog-anime/test/ga401-diagonal.gif
Normal file
BIN
rog-anime/test/ga401-diagonal.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 981 B |
BIN
rog-anime/test/ga401-diagonal.png
Normal file
BIN
rog-anime/test/ga401-diagonal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.0 KiB |
BIN
rog-anime/test/ga402-diagonal.gif
Normal file
BIN
rog-anime/test/ga402-diagonal.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 189 B |
BIN
rog-anime/test/ga402-diagonal.png
Normal file
BIN
rog-anime/test/ga402-diagonal.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 670 B |
Reference in New Issue
Block a user