mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-01-22 17:33:19 +01:00
Animatrix: simulators, add features
This commit is contained in:
@@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Pixel gifs
|
- Pixel gifs
|
||||||
- Power options
|
- Power options
|
||||||
- Builtin animations
|
- Builtin animations
|
||||||
- In-progress simulators for GA402, GU604 animatrix
|
- In-progress simulators for GA402, GU604 animatrix, optional build and takes a single arg
|
||||||
- Add `model_override` option to anime config, this is handy for forcing a model for "Unknown" anime, and for simulators
|
- Add `model_override` option to anime config, this is handy for forcing a model for "Unknown" anime, and for simulators
|
||||||
### Changed
|
### Changed
|
||||||
- Move FX506HC to FX506H in arua DB to catch full series of this range
|
- Move FX506HC to FX506H in arua DB to catch full series of this range
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
use gumdrop::Options;
|
use gumdrop::Options;
|
||||||
use rog_anime::usb::{AnimAwake, AnimBooting, AnimShutdown, AnimSleeping, Brightness};
|
use rog_anime::usb::{AnimAwake, AnimBooting, AnimShutdown, AnimSleeping, Brightness};
|
||||||
|
use rog_anime::AnimeType;
|
||||||
|
|
||||||
#[derive(Options)]
|
#[derive(Options)]
|
||||||
pub struct AnimeCommand {
|
pub struct AnimeCommand {
|
||||||
#[options(help = "print help message")]
|
#[options(help = "print help message")]
|
||||||
pub help: bool,
|
pub help: bool,
|
||||||
|
#[options(meta = "", help = "override the display type")]
|
||||||
|
pub override_type: Option<AnimeType>,
|
||||||
#[options(meta = "", help = "enable/disable the display")]
|
#[options(meta = "", help = "enable/disable the display")]
|
||||||
pub enable_display: Option<bool>,
|
pub enable_display: Option<bool>,
|
||||||
#[options(meta = "", help = "enable/disable the builtin run/powersave animation")]
|
#[options(meta = "", help = "enable/disable the builtin run/powersave animation")]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use aura_cli::{LedPowerCommand1, LedPowerCommand2};
|
|||||||
use gumdrop::{Opt, Options};
|
use gumdrop::{Opt, Options};
|
||||||
use profiles_cli::{FanCurveCommand, ProfileCommand};
|
use profiles_cli::{FanCurveCommand, ProfileCommand};
|
||||||
use rog_anime::usb::get_anime_type;
|
use rog_anime::usb::get_anime_type;
|
||||||
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, Vec2};
|
use rog_anime::{AnimTime, AnimeDataBuffer, AnimeDiagonal, AnimeGif, AnimeImage, AnimeType, Vec2};
|
||||||
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
use rog_aura::usb::{AuraDevRog1, AuraDevRog2, AuraDevTuf, AuraDevice, AuraPowerDev};
|
||||||
use rog_aura::{self, AuraEffect};
|
use rog_aura::{self, AuraEffect};
|
||||||
use rog_dbus::RogDbusClientBlocking;
|
use rog_dbus::RogDbusClientBlocking;
|
||||||
@@ -248,15 +248,21 @@ fn handle_anime(
|
|||||||
verify_brightness(bright);
|
verify_brightness(bright);
|
||||||
dbus.proxies().anime().set_image_brightness(bright)?;
|
dbus.proxies().anime().set_image_brightness(bright)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut anime_type = get_anime_type()?;
|
||||||
|
if let AnimeType::Unknown = anime_type {
|
||||||
|
if let Some(model) = cmd.override_type {
|
||||||
|
anime_type = model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if cmd.clear {
|
if cmd.clear {
|
||||||
let anime_type = get_anime_type()?;
|
|
||||||
let data = vec![255u8; anime_type.data_length()];
|
let data = vec![255u8; anime_type.data_length()];
|
||||||
let tmp = AnimeDataBuffer::from_vec(anime_type, data)?;
|
let tmp = AnimeDataBuffer::from_vec(anime_type, data)?;
|
||||||
dbus.proxies().anime().write(tmp)?;
|
dbus.proxies().anime().write(tmp)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
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() {
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ impl CtrlAnime {
|
|||||||
let mut anime_type = get_anime_type()?;
|
let mut anime_type = get_anime_type()?;
|
||||||
if let AnimeType::Unknown = anime_type {
|
if let AnimeType::Unknown = anime_type {
|
||||||
if let Some(model) = config.model_override {
|
if let Some(model) = config.model_override {
|
||||||
|
warn!("Overriding the Animatrix type as {model:?}");
|
||||||
anime_type = model;
|
anime_type = model;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
use std::str::FromStr;
|
||||||
use std::thread::sleep;
|
use std::thread::sleep;
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
@@ -53,6 +54,19 @@ pub enum AnimeType {
|
|||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for AnimeType {
|
||||||
|
type Err = AnimeError;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||||
|
Ok(match s {
|
||||||
|
"ga401" | "GA401" => Self::GA401,
|
||||||
|
"ga402" | "GA402" => Self::GA402,
|
||||||
|
"gu604" | "GU604" => Self::GU604,
|
||||||
|
_ => Self::Unknown,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AnimeType {
|
impl AnimeType {
|
||||||
/// The width of diagonal images
|
/// The width of diagonal images
|
||||||
pub fn width(&self) -> usize {
|
pub fn width(&self) -> usize {
|
||||||
|
|||||||
@@ -156,7 +156,7 @@ pub fn get_anime_type() -> Result<AnimeType, AnimeError> {
|
|||||||
return Ok(AnimeType::GU604);
|
return Ok(AnimeType::GU604);
|
||||||
}
|
}
|
||||||
log::warn!("AniMe Matrix device found but not yet supported, will default to a GA402 layout");
|
log::warn!("AniMe Matrix device found but not yet supported, will default to a GA402 layout");
|
||||||
Ok(AnimeType::GA402)
|
Ok(AnimeType::Unknown)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the two device initialization packets. These are required for device
|
/// Get the two device initialization packets. These are required for device
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
use rog_anime::AnimeType;
|
||||||
|
|
||||||
use self::map_ga401::GA401;
|
use self::map_ga401::GA401;
|
||||||
use self::map_ga402::GA402;
|
use self::map_ga402::GA402;
|
||||||
use self::map_gu604::GU604;
|
use self::map_gu604::GU604;
|
||||||
@@ -6,12 +8,6 @@ mod map_ga401;
|
|||||||
mod map_ga402;
|
mod map_ga402;
|
||||||
mod map_gu604;
|
mod map_gu604;
|
||||||
|
|
||||||
pub enum Model {
|
|
||||||
GA401,
|
|
||||||
GA402,
|
|
||||||
GU604,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Row(
|
pub struct Row(
|
||||||
/// The USB packet index, this is mapped to the 4th byte (idx = 3) and is
|
/// The USB packet index, this is mapped to the 4th byte (idx = 3) and is
|
||||||
@@ -41,17 +37,17 @@ pub struct AniMatrix {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl AniMatrix {
|
impl AniMatrix {
|
||||||
pub fn new(model: Model) -> Self {
|
pub fn new(model: AnimeType) -> Self {
|
||||||
let led_shape = match model {
|
let led_shape = match model {
|
||||||
Model::GA401 => LedShape {
|
AnimeType::GA401 => LedShape {
|
||||||
vertical: 2,
|
vertical: 2,
|
||||||
horizontal: 5,
|
horizontal: 5,
|
||||||
},
|
},
|
||||||
Model::GA402 => LedShape {
|
AnimeType::GA402 | AnimeType::Unknown => LedShape {
|
||||||
vertical: 2,
|
vertical: 2,
|
||||||
horizontal: 5,
|
horizontal: 5,
|
||||||
},
|
},
|
||||||
Model::GU604 => LedShape {
|
AnimeType::GU604 => LedShape {
|
||||||
vertical: 2,
|
vertical: 2,
|
||||||
horizontal: 5,
|
horizontal: 5,
|
||||||
},
|
},
|
||||||
@@ -59,9 +55,9 @@ impl AniMatrix {
|
|||||||
|
|
||||||
// Do a hard mapping of each (derived from wireshardk captures)
|
// Do a hard mapping of each (derived from wireshardk captures)
|
||||||
let rows = match model {
|
let rows = match model {
|
||||||
Model::GA401 => GA401.to_vec(),
|
AnimeType::GA401 => GA401.to_vec(),
|
||||||
Model::GA402 => GA402.to_vec(),
|
AnimeType::GA402 | AnimeType::Unknown => GA402.to_vec(),
|
||||||
Model::GU604 => GU604.to_vec(),
|
AnimeType::GU604 => GU604.to_vec(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Self { rows, led_shape }
|
Self { rows, led_shape }
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
|
use std::env;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
use log::error;
|
use log::error;
|
||||||
use rog_anime::usb::{PROD_ID, VENDOR_ID};
|
use rog_anime::usb::{PROD_ID, VENDOR_ID};
|
||||||
use rog_anime::USB_PREFIX2;
|
use rog_anime::{AnimeType, USB_PREFIX2};
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
use sdl2::keyboard::Keycode;
|
use sdl2::keyboard::Keycode;
|
||||||
use sdl2::pixels::Color;
|
use sdl2::pixels::Color;
|
||||||
@@ -19,7 +21,7 @@ pub struct VirtAnimeMatrix {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VirtAnimeMatrix {
|
impl VirtAnimeMatrix {
|
||||||
pub fn new(model: Model) -> Self {
|
pub fn new(model: AnimeType) -> Self {
|
||||||
VirtAnimeMatrix {
|
VirtAnimeMatrix {
|
||||||
buffer: [0; 640],
|
buffer: [0; 640],
|
||||||
animatrix: AniMatrix::new(model),
|
animatrix: AniMatrix::new(model),
|
||||||
@@ -110,6 +112,13 @@ impl VirtAnimeMatrix {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn Error>> {
|
fn main() -> Result<(), Box<dyn Error>> {
|
||||||
|
let args: Vec<String> = env::args().collect();
|
||||||
|
if args.len() <= 1 {
|
||||||
|
println!("Must supply arg, one of <GA401, GA402, GU604>");
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let anime_type = AnimeType::from_str(&args[1])?;
|
||||||
|
|
||||||
let sdl_context = sdl2::init().unwrap();
|
let sdl_context = sdl2::init().unwrap();
|
||||||
let video_subsystem = sdl_context.video().unwrap();
|
let video_subsystem = sdl_context.video().unwrap();
|
||||||
|
|
||||||
@@ -121,7 +130,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
|
|
||||||
let mut canvas = window.into_canvas().build().unwrap();
|
let mut canvas = window.into_canvas().build().unwrap();
|
||||||
|
|
||||||
let mut dev = VirtAnimeMatrix::new(Model::GU604);
|
let mut dev = VirtAnimeMatrix::new(anime_type);
|
||||||
|
|
||||||
canvas.set_draw_color(Color::RGB(0, 0, 0));
|
canvas.set_draw_color(Color::RGB(0, 0, 0));
|
||||||
canvas.clear();
|
canvas.clear();
|
||||||
@@ -130,7 +139,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
dev.read(); // it's blocking, and damned hard to sync with arc/mutex
|
dev.read(); // it's blocking, and damned hard to sync with arc/mutex
|
||||||
// let one = dev.buffer[0..7] != USB_PREFIX2;
|
// let one = dev.buffer[0..7] != USB_PREFIX2;
|
||||||
let index = dev.buffer[3];
|
let index = dev.buffer[3];
|
||||||
println!("{:02x}", index);
|
|
||||||
|
|
||||||
let w = dev.animatrix.led_shape().horizontal * 6;
|
let w = dev.animatrix.led_shape().horizontal * 6;
|
||||||
let h = dev.animatrix.led_shape().vertical * 6;
|
let h = dev.animatrix.led_shape().vertical * 6;
|
||||||
@@ -147,7 +155,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (x_count, b) in dev.buffer[start..=end].iter().enumerate() {
|
for (x_count, b) in dev.buffer[start..=end].iter().enumerate() {
|
||||||
// print!("{b},");
|
|
||||||
canvas.set_draw_color(Color::RGB(*b as u8, *b as u8, *b as u8));
|
canvas.set_draw_color(Color::RGB(*b as u8, *b as u8, *b as u8));
|
||||||
|
|
||||||
let x: i32 = w + x_count as i32 * w
|
let x: i32 = w + x_count as i32 * w
|
||||||
@@ -162,7 +169,6 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
.fill_rect(Rect::new(x, y, w as u32, h as u32))
|
.fill_rect(Rect::new(x, y, w as u32, h as u32))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
// println!();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user