diff --git a/Cargo.lock b/Cargo.lock index b7a3fce8..9a926b9e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "adler" version = "1.0.2" @@ -74,15 +76,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "async-lock" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1996609732bde4a9988bc42125f55f2af5f3c36370e27c778d5191a4a1b63bfb" -dependencies = [ - "event-listener", -] - [[package]] name = "atty" version = "0.2.14" @@ -229,7 +222,7 @@ dependencies = [ "sysfs-class", "toml", "udev", - "zbus 2.0.0-beta.3", + "zbus", "zvariant", ] @@ -303,12 +296,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "event-listener" -version = "2.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" - [[package]] name = "fastrand" version = "1.4.0" @@ -433,18 +420,7 @@ checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ "cfg-if 1.0.0", "libc", - "wasi 0.9.0+wasi-snapshot-preview1", -] - -[[package]] -name = "getrandom" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -495,12 +471,6 @@ dependencies = [ "libc", ] -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - [[package]] name = "humantime" version = "2.1.0" @@ -583,14 +553,14 @@ dependencies = [ [[package]] name = "logind-zbus" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6671f6cf88b63e9d63009f4f6f8826fcc265c51a9977e4c7dc1263d743e0dfbb" +checksum = "dca64bea11e365933e0c4a1a9342f0122d1d2822a09c87dab0e1d314adb353a2" dependencies = [ "serde", "serde_json", - "zbus 2.0.0-beta.3", - "zbus_macros 2.0.0-beta.3", + "zbus", + "zbus_macros", "zvariant", "zvariant_derive", ] @@ -655,18 +625,6 @@ dependencies = [ "void", ] -[[package]] -name = "nix" -version = "0.19.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ccba0cfe4fdf15982d1674c69b1fd80bad427d293849982668dfe454bd61f2" -dependencies = [ - "bitflags 1.2.1", - "cc", - "cfg-if 1.0.0", - "libc", -] - [[package]] name = "nom" version = "5.1.2" @@ -686,7 +644,7 @@ dependencies = [ "mac-notification-sys", "serde", "winrt-notification", - "zbus 1.8.0", + "zbus", "zvariant", "zvariant_derive", ] @@ -805,12 +763,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - [[package]] name = "proc-macro-crate" version = "0.1.5" @@ -880,46 +832,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" -dependencies = [ - "getrandom 0.2.2", -] - -[[package]] -name = "rand_hc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" -dependencies = [ - "rand_core", -] - [[package]] name = "redox_syscall" version = "0.1.57" @@ -932,7 +844,7 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" dependencies = [ - "getrandom 0.1.16", + "getrandom", "redox_syscall", "rust-argon2", ] @@ -976,8 +888,8 @@ dependencies = [ "rog_fan_curve", "rog_types", "serde_json", - "zbus 1.8.0", - "zbus_macros 1.8.0", + "zbus", + "zbus_macros", "zvariant", ] @@ -1084,27 +996,12 @@ dependencies = [ "syn 1.0.64", ] -[[package]] -name = "sha1" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" - [[package]] name = "slab" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -[[package]] -name = "slotmap" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3003725ae562cf995f3dc82bb99e70926e09000396816765bb6d7adbe740b1" -dependencies = [ - "version_check", -] - [[package]] name = "smart-default" version = "0.6.0" @@ -1312,12 +1209,6 @@ version = "0.9.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" -[[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - [[package]] name = "weezl" version = "0.1.4" @@ -1406,9 +1297,9 @@ dependencies = [ [[package]] name = "zbus" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40b4d4aa39daed4e32aed75f0c37b969184949a0fdfd5f2e1277abfda61f02a8" +checksum = "2326acc379a3ac4e34b794089f5bdb17086bf29a5fdf619b7b4cc772dc2e9dad" dependencies = [ "async-io", "byteorder", @@ -1417,61 +1308,21 @@ dependencies = [ "fastrand", "futures", "nb-connect", - "nix 0.17.0", + "nix", "once_cell", "polling", "scoped-tls", "serde", "serde_repr", - "zbus_macros 1.8.0", - "zvariant", -] - -[[package]] -name = "zbus" -version = "2.0.0-beta.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e1e656194618d167524f97e88ff9bf87f2b1e8bf58f357b2a7abfdff8cc85c9" -dependencies = [ - "async-io", - "async-lock", - "byteorder", - "derivative", - "enumflags2", - "event-listener", - "futures-core", - "futures-sink", - "futures-util", - "hex", - "nix 0.19.1", - "once_cell", - "rand", - "scoped-tls", - "serde", - "serde_repr", - "sha1", - "slotmap", - "zbus_macros 2.0.0-beta.3", + "zbus_macros", "zvariant", ] [[package]] name = "zbus_macros" -version = "1.8.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc141cda72384bef359badf1808e391d3968f9299e8f3c3cbb78dafa1e0930" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote 1.0.9", - "syn 1.0.64", -] - -[[package]] -name = "zbus_macros" -version = "2.0.0-beta.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcd4cb372bc2cade3f2323e4104112dceb6819f5dd9afa98515b4e821d232932" +checksum = "a482c56029e48681b89b92b5db3c446db0915e8dd1052c0328a574eda38d5f93" dependencies = [ "proc-macro-crate", "proc-macro2", diff --git a/asusctl/examples/animatrix-gif.rs b/asusctl/examples/animatrix-gif.rs index e95d54f4..1cc387a5 100644 --- a/asusctl/examples/animatrix-gif.rs +++ b/asusctl/examples/animatrix-gif.rs @@ -1,6 +1,6 @@ -use std::{env, fs::File, path::Path, thread::sleep, time::Duration}; +use std::{env, path::Path, thread::sleep}; -use rog_anime::AniMeSequence; +use rog_anime::AniMeBlock; use rog_dbus::AuraDbusClient; fn main() { @@ -14,7 +14,7 @@ fn main() { let path = Path::new(&args[1]); let brightness = args[2].parse::().unwrap(); - let gif = AniMeSequence::gif(path, brightness).unwrap(); + let gif = AniMeBlock::asus_gif(path, brightness).unwrap(); loop { for frame in gif.get_animation().unwrap().frames() { diff --git a/asusctl/examples/animatrix-png-gif.rs b/asusctl/examples/animatrix-png-gif.rs new file mode 100644 index 00000000..5d1a8ef9 --- /dev/null +++ b/asusctl/examples/animatrix-png-gif.rs @@ -0,0 +1,39 @@ +use std::{env, path::Path, thread::sleep}; + +use glam::Vec2; +use rog_anime::AniMeBlock; +use rog_dbus::AuraDbusClient; + +fn main() { + let (client, _) = AuraDbusClient::new().unwrap(); + + let args: Vec = env::args().into_iter().collect(); + if args.len() != 7 { + println!("Usage: "); + println!("e.g, asusctl/examples/file.gif 0.9 0.4 0.0 0.0 0.8"); + return; + } + + let gif = AniMeBlock::image_gif( + Path::new(&args[1]), + args[2].parse::().unwrap(), + args[3].parse::().unwrap(), + Vec2::new( + args[4].parse::().unwrap(), + args[5].parse::().unwrap(), + ), + args[6].parse::().unwrap(), + ) + .unwrap(); + + loop { + for frame in gif.get_animation().unwrap().frames() { + client + .proxies() + .anime() + .write(frame.frame().clone()) + .unwrap(); + sleep(frame.delay()); + } + } +} diff --git a/asusctl/examples/animatrix-png.rs b/asusctl/examples/animatrix-png.rs index 53bc88df..e8449fc6 100644 --- a/asusctl/examples/animatrix-png.rs +++ b/asusctl/examples/animatrix-png.rs @@ -9,24 +9,21 @@ fn main() -> Result<(), Box> { let (client, _) = AuraDbusClient::new().unwrap(); let args: Vec = env::args().into_iter().collect(); - if args.len() != 8 { - println!("Usage: "); - println!("e.g, asusctl/examples/doom_large.png 0.9 0.9 0.4 0.0 0.0,0.8"); + if args.len() != 7 { + println!("Usage: "); + println!("e.g, asusctl/examples/doom_large.png 0.9 0.4 0.0 0.0 0.8"); exit(-1); } let matrix = AniMeImage::from_png( Path::new(&args[1]), + args[2].parse::().unwrap(), + args[3].parse::().unwrap(), Vec2::new( - args[2].parse::().unwrap(), - args[3].parse::().unwrap(), - ), - args[4].parse::().unwrap(), - Vec2::new( + args[4].parse::().unwrap(), args[5].parse::().unwrap(), - args[6].parse::().unwrap(), ), - args[7].parse::().unwrap(), + args[6].parse::().unwrap(), )?; client diff --git a/asusctl/examples/animatrix-spinning.rs b/asusctl/examples/animatrix-spinning.rs index c28074f9..80fa7774 100644 --- a/asusctl/examples/animatrix-spinning.rs +++ b/asusctl/examples/animatrix-spinning.rs @@ -11,25 +11,21 @@ fn main() -> Result<(), Box> { let (client, _) = AuraDbusClient::new().unwrap(); let args: Vec = env::args().into_iter().collect(); - if args.len() != 8 { - println!("Usage: "); - println!("e.g, asusctl/examples/doom_large.bmp 0.9 0.9 0.4 0.0 0.0, 0.8"); - println!("All args except path and fineness are floats"); + if args.len() != 7 { + println!("Usage: "); + println!("e.g, asusctl/examples/doom_large.png 0.9 0.4 0.0 0.0 0.8"); exit(-1); } let mut matrix = AniMeImage::from_png( Path::new(&args[1]), + args[2].parse::().unwrap(), + args[3].parse::().unwrap(), Vec2::new( - args[2].parse::().unwrap(), - args[3].parse::().unwrap(), - ), - args[4].parse::().unwrap(), - Vec2::new( + args[4].parse::().unwrap(), args[5].parse::().unwrap(), - args[6].parse::().unwrap(), ), - args[7].parse::().unwrap(), + args[6].parse::().unwrap(), )?; loop { diff --git a/asusctl/src/main.rs b/asusctl/src/main.rs index a7354c33..e3be97bb 100644 --- a/asusctl/src/main.rs +++ b/asusctl/src/main.rs @@ -177,7 +177,7 @@ fn main() -> Result<(), Box> { let matrix = AniMeImage::from_png( Path::new(&image.path), - Vec2::new(image.scale, image.scale), + image.scale, image.angle, Vec2::new(image.x_pos, image.y_pos), image.bright, diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index f3a5fb7a..8e191705 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -28,9 +28,9 @@ udev = "^0.6" log = "^0.4" env_logger = "^0.8" -zbus = "^2.0.0-beta.3" -zvariant = "^2.5" -logind-zbus = "*" +zbus = "^1.9.1" +zvariant = "^2.6" +logind-zbus = "^0.7.1" # serialisation serde = "^1.0" diff --git a/daemon/src/ctrl_anime.rs b/daemon/src/ctrl_anime.rs index e7e9e713..8ee2fdc5 100644 --- a/daemon/src/ctrl_anime.rs +++ b/daemon/src/ctrl_anime.rs @@ -16,6 +16,7 @@ const ON_OFF: u8 = 0x04; use log::{error, info, warn}; use rog_anime::{AniMeDataBuffer, AniMePacketType}; use rusb::{Device, DeviceHandle}; +use zvariant::ObjectPath; use std::error::Error; use std::time::Duration; use zbus::dbus_interface; @@ -51,7 +52,7 @@ pub trait Dbus { impl crate::ZbusAdd for CtrlAnimeDisplay { fn add_to_server(self, server: &mut zbus::ObjectServer) { server - .at("/org/asuslinux/Anime", self) + .at(&ObjectPath::from_str_unchecked("/org/asuslinux/Anime"), self) .map_err(|err| { warn!("CtrlAnimeDisplay: add_to_server {}", err); err diff --git a/daemon/src/ctrl_charge.rs b/daemon/src/ctrl_charge.rs index 56e577da..e5509634 100644 --- a/daemon/src/ctrl_charge.rs +++ b/daemon/src/ctrl_charge.rs @@ -2,6 +2,7 @@ use crate::{config::Config, error::RogError, GetSupported}; //use crate::dbus::DbusEvents; use log::{info, warn}; use serde_derive::{Deserialize, Serialize}; +use zvariant::ObjectPath; use std::fs::OpenOptions; use std::io::Write; use std::path::Path; @@ -63,7 +64,7 @@ impl CtrlCharge { impl crate::ZbusAdd for CtrlCharge { fn add_to_server(self, server: &mut zbus::ObjectServer) { server - .at("/org/asuslinux/Charge", self) + .at(&ObjectPath::from_str_unchecked("/org/asuslinux/Charge"), self) .map_err(|err| { warn!("CtrlCharge: add_to_server {}", err); err diff --git a/daemon/src/ctrl_fan_cpu.rs b/daemon/src/ctrl_fan_cpu.rs index a33fdeb3..601d1614 100644 --- a/daemon/src/ctrl_fan_cpu.rs +++ b/daemon/src/ctrl_fan_cpu.rs @@ -3,6 +3,7 @@ use crate::{config::Config, GetSupported}; use log::{info, warn}; use rog_types::profile::{FanLevel, Profile, ProfileEvent}; use serde_derive::{Deserialize, Serialize}; +use zvariant::ObjectPath; use std::fs::OpenOptions; use std::io::Write; use std::path::Path; @@ -180,7 +181,7 @@ impl DbusFanAndCpu { impl crate::ZbusAdd for DbusFanAndCpu { fn add_to_server(self, server: &mut zbus::ObjectServer) { server - .at("/org/asuslinux/Profile", self) + .at(&ObjectPath::from_str_unchecked("/org/asuslinux/Profile"), self) .map_err(|err| { warn!("DbusFanAndCpu: add_to_server {}", err); err diff --git a/daemon/src/ctrl_gfx/gfx.rs b/daemon/src/ctrl_gfx/gfx.rs index cac9e174..e9c8a3e9 100644 --- a/daemon/src/ctrl_gfx/gfx.rs +++ b/daemon/src/ctrl_gfx/gfx.rs @@ -7,6 +7,7 @@ use logind_zbus::{ ManagerProxy, SessionProxy, }; use rog_types::gfx_vendors::{GfxPower, GfxRequiredUserAction, GfxVendors}; +use zvariant::ObjectPath; use std::{io::Write, ops::Add, path::Path, time::Instant}; use std::{iter::FromIterator, thread::JoinHandle}; use std::{process::Command, thread::sleep, time::Duration}; @@ -78,7 +79,7 @@ impl Dbus for CtrlGraphics { impl ZbusAdd for CtrlGraphics { fn add_to_server(self, server: &mut zbus::ObjectServer) { server - .at("/org/asuslinux/Gfx", self) + .at(&ObjectPath::from_str_unchecked("/org/asuslinux/Gfx"), self) .map_err(|err| { warn!("GFX: CtrlGraphics: add_to_server {}", err); err @@ -495,7 +496,7 @@ impl CtrlGraphics { sessions: &[SessionInfo], ) -> Result { for session in sessions { - let session_proxy = SessionProxy::new(&connection, session)?; + let session_proxy = SessionProxy::new(connection, session)?; if session_proxy.get_class()? == SessionClass::User { match session_proxy.get_type()? { SessionType::X11 | SessionType::Wayland | SessionType::MIR => { diff --git a/daemon/src/ctrl_leds.rs b/daemon/src/ctrl_leds.rs index 2fa93046..8643e339 100644 --- a/daemon/src/ctrl_leds.rs +++ b/daemon/src/ctrl_leds.rs @@ -14,6 +14,7 @@ use rog_types::{ aura_modes::{AuraEffect, AuraModeNum, LedBrightness}, LED_MSG_LEN, }; +use zvariant::ObjectPath; use std::fs::OpenOptions; use std::io::{Read, Write}; use std::path::Path; @@ -82,7 +83,7 @@ trait Dbus { impl crate::ZbusAdd for DbusKbdBacklight { fn add_to_server(self, server: &mut zbus::ObjectServer) { server - .at("/org/asuslinux/Led", self) + .at(&ObjectPath::from_str_unchecked("/org/asuslinux/Led"), self) .map_err(|err| { error!("DbusKbdBacklight: add_to_server {}", err); }) diff --git a/daemon/src/ctrl_rog_bios.rs b/daemon/src/ctrl_rog_bios.rs index 4cfdd8e4..c12d6607 100644 --- a/daemon/src/ctrl_rog_bios.rs +++ b/daemon/src/ctrl_rog_bios.rs @@ -1,6 +1,7 @@ use crate::{config::Config, error::RogError, GetSupported}; use log::{error, info, warn}; use serde_derive::{Deserialize, Serialize}; +use zvariant::ObjectPath; use std::fs::OpenOptions; use std::io::BufRead; use std::io::{Read, Write}; @@ -101,7 +102,7 @@ impl CtrlRogBios { impl crate::ZbusAdd for CtrlRogBios { fn add_to_server(self, server: &mut zbus::ObjectServer) { server - .at("/org/asuslinux/RogBios", self) + .at(&ObjectPath::from_str_unchecked("/org/asuslinux/RogBios"), self) .map_err(|err| { warn!("CtrlRogBios: add_to_server {}", err); err diff --git a/daemon/src/ctrl_supported.rs b/daemon/src/ctrl_supported.rs index c52a56bc..1c1c8f7d 100644 --- a/daemon/src/ctrl_supported.rs +++ b/daemon/src/ctrl_supported.rs @@ -1,6 +1,7 @@ use log::warn; use serde_derive::{Deserialize, Serialize}; use zbus::dbus_interface; +use zvariant::ObjectPath; use crate::{ ctrl_anime::{AnimeSupportedFunctions, CtrlAnimeDisplay}, @@ -30,7 +31,7 @@ impl SupportedFunctions { impl crate::ZbusAdd for SupportedFunctions { fn add_to_server(self, server: &mut zbus::ObjectServer) { server - .at("/org/asuslinux/Supported", self) + .at(&ObjectPath::from_str_unchecked("/org/asuslinux/Supported"), self) .map_err(|err| { warn!("SupportedFunctions: add_to_server {}", err); err diff --git a/daemon/src/daemon.rs b/daemon/src/daemon.rs index 9f8199cf..64cd601f 100644 --- a/daemon/src/daemon.rs +++ b/daemon/src/daemon.rs @@ -23,6 +23,7 @@ use daemon::ctrl_rog_bios::CtrlRogBios; use std::convert::Into; use zbus::fdo; use zbus::Connection; +use zvariant::ObjectPath; pub fn main() -> Result<(), Box> { let mut logger = env_logger::Builder::new(); @@ -157,7 +158,7 @@ fn start_daemon() -> Result<(), Box> { // TODO: implement messaging between threads to check fails // These tasks generally read a sys path or file to check for a // change - let _handle = std::thread::Builder::new() + let handle = std::thread::Builder::new() .name("asusd watch".to_string()) .spawn(move || loop { std::thread::sleep(std::time::Duration::from_millis(100)); @@ -174,7 +175,7 @@ fn start_daemon() -> Result<(), Box> { }); object_server - .with("/org/asuslinux/Charge", |obj: &CtrlCharge| { + .with(&ObjectPath::from_str_unchecked("/org/asuslinux/Charge"), |obj: &CtrlCharge| { let x = obj.limit(); obj.notify_charge(x as u8) }) @@ -184,8 +185,11 @@ fn start_daemon() -> Result<(), Box> { .ok(); loop { + if let Err(err) = &handle { + error!("{}", err); + } if let Err(err) = object_server.try_handle_next() { - eprintln!("{}", err); + error!("{}", err); } } } diff --git a/data/anime/custom/nyancat_zombie.gif b/data/anime/custom/nyancat_zombie.gif new file mode 100644 index 00000000..b48d9c88 Binary files /dev/null and b/data/anime/custom/nyancat_zombie.gif differ diff --git a/data/anime/custom/sonic-run.gif b/data/anime/custom/sonic-run.gif new file mode 100644 index 00000000..cb7aaa07 Binary files /dev/null and b/data/anime/custom/sonic-run.gif differ diff --git a/data/anime/custom/sonic-wait.gif b/data/anime/custom/sonic-wait.gif new file mode 100644 index 00000000..685cc8fa Binary files /dev/null and b/data/anime/custom/sonic-wait.gif differ diff --git a/rog-anime/src/anime_gif.rs b/rog-anime/src/anime_gif.rs index 7ef5b2cf..e5e7e07e 100644 --- a/rog-anime/src/anime_gif.rs +++ b/rog-anime/src/anime_gif.rs @@ -1,7 +1,8 @@ +use glam::Vec2; use serde_derive::{Deserialize, Serialize}; use std::{fs::File, path::Path, time::Duration}; -use crate::{error::AnimeError, AniMeDataBuffer, AniMeDiagonal}; +use crate::{error::AnimeError, AniMeDataBuffer, AniMeDiagonal, AniMeImage, Pixel}; #[derive(Debug, Clone, Deserialize, Serialize)] pub struct AniMeFrame { @@ -25,8 +26,8 @@ impl AniMeFrame { pub struct AniMeGif(Vec); impl AniMeGif { - pub fn new(file_name: &Path, brightness: f32) -> Result { - let mut frames = Vec::new(); + /// Create an animation using the 74x36 ASUS gif format + pub fn create_diagonal_gif(file_name: &Path, brightness: f32) -> Result { let mut matrix = AniMeDiagonal::new(); let mut decoder = gif::DecodeOptions::new(); @@ -36,8 +37,12 @@ impl AniMeGif { let file = File::open(file_name)?; let mut decoder = decoder.read_info(file)?; + let mut frames = Vec::with_capacity(decoder.buffer_size()); while let Some(frame) = decoder.read_next_frame()? { let wait = frame.delay * 10; + if matches!(frame.dispose, gif::DisposalMethod::Background) { + frames = Vec::new(); + } for (y, row) in frame.buffer.chunks(frame.width as usize * 4).enumerate() { for (x, px) in row.chunks(4).enumerate() { if px[3] != 255 { @@ -57,6 +62,69 @@ impl AniMeGif { Ok(Self(frames)) } + /// Create an animation using a gif of any size. This method must precompute the + /// result. + pub fn create_png_gif( + file_name: &Path, + scale: f32, + angle: f32, + translation: Vec2, + brightness: f32, + ) -> Result { + let mut frames = Vec::new(); + + let mut decoder = gif::DecodeOptions::new(); + // Configure the decoder such that it will expand the image to RGBA. + decoder.set_color_output(gif::ColorOutput::RGBA); + // Read the file header + let file = File::open(file_name)?; + let mut decoder = decoder.read_info(file)?; + + let height = decoder.height(); + let width = decoder.width(); + let pixels: Vec = + vec![Pixel::default(); (decoder.width() as u32 * decoder.height() as u32) as usize]; + let mut image = AniMeImage::new( + Vec2::new(scale, scale), + angle, + translation, + brightness, + pixels, + decoder.width() as u32, + ); + + while let Some(frame) = decoder.read_next_frame()? { + let wait = frame.delay * 10; + if matches!(frame.dispose, gif::DisposalMethod::Background) { + let pixels: Vec = + vec![Pixel::default(); (width as u32 * height as u32) as usize]; + image = + AniMeImage::new(Vec2::new(scale,scale), angle, translation, brightness, pixels, width as u32); + } + for (y, row) in frame.buffer.chunks(frame.width as usize * 4).enumerate() { + for (x, px) in row.chunks(4).enumerate() { + if px[3] != 255 { + // should be t but not in some gifs? What, ASUS, what? + continue; + } + let pos = + (x + frame.left as usize) + ((y + frame.top as usize) * width as usize); + image.get_mut()[pos] = Pixel { + color: ((px[0] as u32 + px[1] as u32 + px[2] as u32) / 3), + alpha: 1.0, + }; + } + } + image.update(); + + frames.push(AniMeFrame { + data: ::from(&image), + delay: Duration::from_millis(wait as u64), + }); + } + Ok(Self(frames)) + } + pub fn frames(&self) -> &[AniMeFrame] { &self.0 } diff --git a/rog-anime/src/anime_image.rs b/rog-anime/src/anime_image.rs index d0972987..d9901348 100644 --- a/rog-anime/src/anime_image.rs +++ b/rog-anime/src/anime_image.rs @@ -10,10 +10,19 @@ use crate::{ const LED_PIXEL_LEN: usize = 1244; -#[derive(Copy, Clone, Debug, Default)] -struct Pixel { - color: u32, - alpha: f32, +#[derive(Copy, Clone, Debug)] +pub(crate) struct Pixel { + pub color: u32, + pub alpha: f32, +} + +impl Default for Pixel { + fn default() -> Self { + Pixel { + color: 0, + alpha: 0.0, + } + } } /// A single LED position and brightness. The intention of this struct @@ -64,7 +73,7 @@ pub struct AniMeImage { } impl AniMeImage { - const fn new( + pub(crate) const fn new( scale: Vec2, angle: f32, translation: Vec2, @@ -131,6 +140,10 @@ impl AniMeImage { } } + pub(crate) fn get_mut(&mut self) -> &mut [Pixel] { + &mut self.img_pixels + } + /// Really only used to generate the output for including as a full const in `LED_IMAGE_POSITIONS` pub fn generate() -> Vec> { (0..AniMeImage::height()) @@ -172,18 +185,10 @@ impl AniMeImage { for v in GROUP.iter() { let sample = x0 + *u * du + *v * dv; - let mut y = sample.y as i32; - if y > height - 1 { - y = height - 1 - } else if y < 0 { - y = 0; - } - - let mut x = sample.x as i32; - if x > width - 1 { - x = width - 1; - } else if x < 0 { - x = 0; + let x = sample.x as i32; + let y = sample.y as i32; + if x > width - 1 || y > height - 1 || x < 0 || y < 0 { + continue; } let p = self.img_pixels[(x + (y * width)) as usize]; @@ -230,7 +235,7 @@ impl AniMeImage { /// updated via scale, position, or angle then displayed again after `update()`. pub fn from_png( path: &Path, - scale: Vec2, + scale: f32, angle: f32, translation: Vec2, bright: f32, @@ -256,7 +261,7 @@ impl AniMeImage { _ => return Err(AnimeError::Format), }; - let mut matrix = AniMeImage::new(scale, angle, translation, bright, pixels, width); + let mut matrix = AniMeImage::new(Vec2::new(scale, scale), angle, translation, bright, pixels, width); matrix.update(); Ok(matrix) diff --git a/rog-anime/src/lib.rs b/rog-anime/src/lib.rs index e92b0da1..f44a51b0 100644 --- a/rog-anime/src/lib.rs +++ b/rog-anime/src/lib.rs @@ -28,7 +28,7 @@ pub mod error; // packet data #[derive(Debug, Clone, Deserialize, Serialize)] -pub enum AniMeSequence { +pub enum AniMeBlock { /// Full gif sequence. Immutable. Animation(AniMeGif), /// Basic image, can have properties changed @@ -37,15 +37,15 @@ pub enum AniMeSequence { Pause(Duration), } -impl AniMeSequence { - pub fn gif(file: &Path, brightness: f32) -> Result { - let frames = AniMeGif::new(file, brightness)?; +impl AniMeBlock { + pub fn asus_gif(file: &Path, brightness: f32) -> Result { + let frames = AniMeGif::create_diagonal_gif(file, brightness)?; Ok(Self::Animation(frames)) } pub fn png( file: &Path, - scale: Vec2, + scale: f32, angle: f32, translation: Vec2, brightness: f32, @@ -55,16 +55,34 @@ impl AniMeSequence { Ok(Self::Image(Box::new(data))) } + pub fn image_gif( + file: &Path, + scale: f32, + angle: f32, + translation: Vec2, + brightness: f32, + ) -> Result { + let frames = AniMeGif::create_png_gif(file, scale, angle, translation, brightness)?; + Ok(Self::Animation(frames)) + } + pub fn get_animation(&self) -> Option<&AniMeGif> { match self { - AniMeSequence::Animation(anim) => Some(anim), + AniMeBlock::Animation(anim) => Some(anim), _ => None, } } pub fn get_image(&self) -> Option<&AniMeDataBuffer> { match self { - AniMeSequence::Image(image) => Some(image), + AniMeBlock::Image(image) => Some(image), + _ => None, + } + } + + pub fn get_pause(&self) -> Option { + match self { + AniMeBlock::Pause(pause) => Some(*pause), _ => None, } }