mirror of
https://gitlab.com/asus-linux/asusctl.git
synced 2026-02-06 00:15:04 +01:00
rog-aura: add per-zone effects
This commit is contained in:
@@ -251,9 +251,10 @@ impl From<u8> for AuraModeNum {
|
||||
|
||||
/// Base effects have no zoning, while multizone is 1-4
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Deserialize, Serialize)]
|
||||
#[derive(Debug, Default, Copy, Clone, PartialEq, Deserialize, Serialize)]
|
||||
pub enum AuraZone {
|
||||
/// Used if keyboard has no zones, or if setting all
|
||||
#[default]
|
||||
None,
|
||||
/// Leftmost zone
|
||||
Key1,
|
||||
@@ -271,12 +272,6 @@ pub enum AuraZone {
|
||||
BarRight,
|
||||
}
|
||||
|
||||
impl Default for AuraZone {
|
||||
fn default() -> Self {
|
||||
AuraZone::None
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for AuraZone {
|
||||
type Err = Error;
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@ pub use builtin_modes::*;
|
||||
|
||||
mod per_key_rgb;
|
||||
pub use per_key_rgb::*;
|
||||
|
||||
mod per_zone;
|
||||
pub use per_zone::*;
|
||||
|
||||
pub mod error;
|
||||
pub mod key_to_str;
|
||||
pub mod keys;
|
||||
|
||||
124
rog-aura/src/per_zone.rs
Normal file
124
rog-aura/src/per_zone.rs
Normal file
@@ -0,0 +1,124 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
#[cfg(feature = "dbus")]
|
||||
use zvariant::Type;
|
||||
|
||||
/// Represents the zoned raw USB packets
|
||||
pub type ZonedRaw = Vec<u8>;
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, Serialize)]
|
||||
pub enum PerZone {
|
||||
None,
|
||||
KeyboardLeft,
|
||||
KeyboardCenterLeft,
|
||||
KeyboardCenterRight,
|
||||
KeyboardRight,
|
||||
LightbarRight,
|
||||
LightbarRightCorner,
|
||||
LightbarRightBottom,
|
||||
LightbarLeftBottom,
|
||||
LightbarLeftCorner,
|
||||
LightbarLeft,
|
||||
}
|
||||
|
||||
#[cfg_attr(feature = "dbus", derive(Type))]
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub struct ZonedColourArray(ZonedRaw);
|
||||
|
||||
impl Default for ZonedColourArray {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl ZonedColourArray {
|
||||
pub fn new() -> Self {
|
||||
let mut pkt = vec![0u8; 64];
|
||||
pkt[0] = 0x5d; // Report ID
|
||||
pkt[1] = 0xbc; // Mode = custom??, 0xb3 is builtin
|
||||
pkt[2] = 0x01;
|
||||
pkt[3] = 0x01; // ??
|
||||
pkt[4] = 0x04; // ??, 4,5,6 are normally RGB for builtin mode colours
|
||||
ZonedColourArray(pkt)
|
||||
}
|
||||
|
||||
pub fn rgb_for_zone(&mut self, zone: PerZone) -> &mut [u8] {
|
||||
match zone {
|
||||
PerZone::None => &mut self.0[9..=11],
|
||||
PerZone::KeyboardLeft => &mut self.0[9..=11],
|
||||
PerZone::KeyboardCenterLeft => &mut self.0[12..=14],
|
||||
PerZone::KeyboardCenterRight => &mut self.0[15..=17],
|
||||
PerZone::KeyboardRight => &mut self.0[18..=20],
|
||||
// Two sections missing here?
|
||||
PerZone::LightbarRight => &mut self.0[27..=29],
|
||||
PerZone::LightbarRightCorner => &mut self.0[30..=32],
|
||||
PerZone::LightbarRightBottom => &mut self.0[33..=35],
|
||||
PerZone::LightbarLeftBottom => &mut self.0[36..=38],
|
||||
PerZone::LightbarLeftCorner => &mut self.0[39..=41],
|
||||
PerZone::LightbarLeft => &mut self.0[42..=44],
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get(&self) -> ZonedRaw {
|
||||
self.0.clone()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_ref(&self) -> &ZonedRaw {
|
||||
&self.0
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn get_mut(&mut self) -> &mut ZonedRaw {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ZonedColourArray> for ZonedRaw {
|
||||
fn from(k: ZonedColourArray) -> Self {
|
||||
k.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{PerZone, ZonedColourArray, ZonedRaw};
|
||||
|
||||
macro_rules! colour_check {
|
||||
($zone:expr, $pkt_idx_start:expr) => {
|
||||
let mut zone = ZonedColourArray::new();
|
||||
let c = zone.rgb_for_zone($zone);
|
||||
c[0] = 255;
|
||||
c[1] = 255;
|
||||
c[2] = 255;
|
||||
|
||||
let pkt: ZonedRaw = zone.get();
|
||||
assert_eq!(pkt[$pkt_idx_start], 0xff);
|
||||
assert_eq!(pkt[$pkt_idx_start + 1], 0xff);
|
||||
assert_eq!(pkt[$pkt_idx_start + 2], 0xff);
|
||||
};
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zone_to_packet_check() {
|
||||
let zone = ZonedColourArray::new();
|
||||
let pkt: ZonedRaw = zone.into();
|
||||
assert_eq!(pkt[0], 0x5d);
|
||||
assert_eq!(pkt[1], 0xbc);
|
||||
assert_eq!(pkt[2], 0x01);
|
||||
assert_eq!(pkt[3], 0x01);
|
||||
assert_eq!(pkt[4], 0x04);
|
||||
|
||||
colour_check!(PerZone::KeyboardLeft, 9);
|
||||
colour_check!(PerZone::KeyboardCenterLeft, 12);
|
||||
colour_check!(PerZone::KeyboardCenterRight, 15);
|
||||
colour_check!(PerZone::KeyboardRight, 18);
|
||||
|
||||
colour_check!(PerZone::LightbarRight, 27);
|
||||
colour_check!(PerZone::LightbarRightCorner, 30);
|
||||
colour_check!(PerZone::LightbarRightBottom, 33);
|
||||
colour_check!(PerZone::LightbarLeftBottom, 36);
|
||||
colour_check!(PerZone::LightbarLeftCorner, 39);
|
||||
colour_check!(PerZone::LightbarLeft, 42);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,21 @@
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
|
||||
use crate::{keys::Key, layouts::KeyLayout, Colour, KeyColourArray, PerKeyRaw, Speed};
|
||||
use crate::{
|
||||
keys::Key, layouts::KeyLayout, Colour, KeyColourArray, PerKeyRaw, PerZone, Speed,
|
||||
ZonedColourArray,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub enum LedType {
|
||||
Key(Key),
|
||||
Zone(PerZone),
|
||||
}
|
||||
|
||||
impl Default for LedType {
|
||||
fn default() -> Self {
|
||||
Self::Zone(PerZone::None)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
pub(super) enum Action {
|
||||
@@ -30,7 +45,7 @@ impl Default for Action {
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
|
||||
pub struct ActionData {
|
||||
key: Key,
|
||||
led_type: LedType,
|
||||
action: Action,
|
||||
// TODO: time
|
||||
/// The end resulting colour after stepping through effect
|
||||
@@ -39,21 +54,21 @@ pub struct ActionData {
|
||||
}
|
||||
|
||||
impl ActionData {
|
||||
pub fn set_key(&mut self, key: Key) {
|
||||
self.key = key
|
||||
pub fn set_led_type(&mut self, led_type: LedType) {
|
||||
self.led_type = led_type
|
||||
}
|
||||
|
||||
pub fn new_static(key: Key, colour: Colour) -> Self {
|
||||
pub fn new_static(led_type: LedType, colour: Colour) -> Self {
|
||||
Self {
|
||||
key,
|
||||
led_type,
|
||||
action: Action::Static(colour),
|
||||
colour: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_breathe(key: Key, colour1: Colour, colour2: Colour, speed: Speed) -> Self {
|
||||
pub fn new_breathe(led_type: LedType, colour1: Colour, colour2: Colour, speed: Speed) -> Self {
|
||||
Self {
|
||||
key,
|
||||
led_type,
|
||||
action: Action::Breathe {
|
||||
colour1,
|
||||
colour2,
|
||||
@@ -153,27 +168,46 @@ impl Sequences {
|
||||
|
||||
pub fn create_packets(&self) -> PerKeyRaw {
|
||||
let mut keys = KeyColourArray::new();
|
||||
let mut zones = ZonedColourArray::new();
|
||||
let mut is_per_key = false;
|
||||
for effect in self.0.iter() {
|
||||
if let Some(rgb) = keys.rgb_for_key(effect.key) {
|
||||
rgb[0] = effect.colour.0;
|
||||
rgb[1] = effect.colour.1;
|
||||
rgb[2] = effect.colour.2;
|
||||
match effect.led_type {
|
||||
LedType::Key(key) => {
|
||||
is_per_key = true;
|
||||
if let Some(rgb) = keys.rgb_for_key(key) {
|
||||
rgb[0] = effect.colour.0;
|
||||
rgb[1] = effect.colour.1;
|
||||
rgb[2] = effect.colour.2;
|
||||
}
|
||||
}
|
||||
LedType::Zone(z) => {
|
||||
let rgb = zones.rgb_for_zone(z);
|
||||
rgb[0] = effect.colour.0;
|
||||
rgb[1] = effect.colour.1;
|
||||
rgb[2] = effect.colour.2;
|
||||
}
|
||||
}
|
||||
}
|
||||
keys.into()
|
||||
if is_per_key {
|
||||
keys.into()
|
||||
} else {
|
||||
vec![zones.into()]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{keys::Key, layouts::KeyLayout, Action, ActionData, Colour, Sequences, Speed};
|
||||
use crate::{
|
||||
keys::Key, layouts::KeyLayout, Action, ActionData, Colour, LedType, Sequences, Speed,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn single_key_next_state_then_create() {
|
||||
let layout = KeyLayout::gx502_layout();
|
||||
let mut seq = Sequences::new();
|
||||
seq.0.push(ActionData {
|
||||
key: Key::F,
|
||||
led_type: LedType::Key(Key::F),
|
||||
action: Action::Static(Colour(255, 127, 0)),
|
||||
colour: Default::default(),
|
||||
});
|
||||
@@ -192,7 +226,7 @@ mod tests {
|
||||
let layout = KeyLayout::gx502_layout();
|
||||
let mut seq = Sequences::new();
|
||||
seq.0.push(ActionData {
|
||||
key: Key::F,
|
||||
led_type: LedType::Key(Key::F),
|
||||
action: Action::Breathe {
|
||||
colour1: Colour(255, 127, 0),
|
||||
colour2: Colour(127, 0, 255),
|
||||
|
||||
Reference in New Issue
Block a user