From 2fb8995e681dc6f9ff6e2afa8054d8b31fc477c5 Mon Sep 17 00:00:00 2001 From: 4yn <4yn@users.noreply.github.com> Date: Wed, 23 Mar 2022 01:06:16 +0800 Subject: [PATCH] add 4k/6k layouts and reactive color customization --- src-slider_io/src/lighting/config.rs | 60 ++++++++++++++++++++++++-- src-slider_io/src/lighting/lighting.rs | 46 +++++++++++++++++--- src-slider_io/src/output/config.rs | 20 +++++++-- src-slider_io/src/output/keyboard.rs | 28 +++++++++++- src/App.svelte | 42 +++++++++++++++--- 5 files changed, 172 insertions(+), 24 deletions(-) diff --git a/src-slider_io/src/lighting/config.rs b/src-slider_io/src/lighting/config.rs index aaeb220..2893c89 100644 --- a/src-slider_io/src/lighting/config.rs +++ b/src-slider_io/src/lighting/config.rs @@ -3,10 +3,50 @@ use serde_json::Value; #[derive(Debug, Clone, Copy)] pub enum ReactiveLayout { Even { splits: usize }, + Six, Voltex, Rainbow, } +#[derive(Debug, Clone)] +pub struct ColorScheme { + pub active: [u8; 3], + pub inactive: [u8; 3], +} + +impl ColorScheme { + pub fn from_serde_value(v: &Value) -> Option { + Some(Self { + active: [ + u8::from_str_radix(&v["ledColorActive"].as_str()?[1..3], 16).ok()?, + u8::from_str_radix(&v["ledColorActive"].as_str()?[3..5], 16).ok()?, + u8::from_str_radix(&v["ledColorActive"].as_str()?[5..7], 16).ok()?, + ], + inactive: [ + u8::from_str_radix(&v["ledColorInactive"].as_str()?[1..3], 16).ok()?, + u8::from_str_radix(&v["ledColorInactive"].as_str()?[3..5], 16).ok()?, + u8::from_str_radix(&v["ledColorInactive"].as_str()?[5..7], 16).ok()?, + ], + }) + } + + pub fn default() -> Self { + Self { + active: [255, 0, 255], + inactive: [255, 255, 0], + } + } + + pub fn from_serde_value_or_default(v: &Value) -> Self { + Self::from_serde_value(v) + .or(Some(Self { + active: [255, 0, 255], + inactive: [255, 255, 0], + })) + .unwrap() + } +} + #[derive(Debug, Clone)] pub enum LightsMode { None, @@ -14,6 +54,7 @@ pub enum LightsMode { faster: bool, layout: ReactiveLayout, sensitivity: u8, + color: ColorScheme, }, Attract { faster: bool, @@ -32,30 +73,41 @@ impl LightsMode { pub fn from_serde_value(v: &Value) -> Option { Some(match v["ledMode"].as_str()? { "none" => LightsMode::None, - "reactive-4" => LightsMode::Reactive { + "reactive-16" => LightsMode::Reactive { faster: v["ledFaster"].as_bool()?, - layout: ReactiveLayout::Even { splits: 4 }, + layout: ReactiveLayout::Even { splits: 16 }, sensitivity: u8::try_from(v["ledSensitivity"].as_i64()?).ok()?, + color: ColorScheme::from_serde_value_or_default(v), }, "reactive-8" => LightsMode::Reactive { faster: v["ledFaster"].as_bool()?, layout: ReactiveLayout::Even { splits: 8 }, sensitivity: u8::try_from(v["ledSensitivity"].as_i64()?).ok()?, + color: ColorScheme::from_serde_value_or_default(v), }, - "reactive-16" => LightsMode::Reactive { + "reactive-6" => LightsMode::Reactive { faster: v["ledFaster"].as_bool()?, - layout: ReactiveLayout::Even { splits: 16 }, + layout: ReactiveLayout::Six, sensitivity: u8::try_from(v["ledSensitivity"].as_i64()?).ok()?, + color: ColorScheme::from_serde_value_or_default(v), + }, + "reactive-4" => LightsMode::Reactive { + faster: v["ledFaster"].as_bool()?, + layout: ReactiveLayout::Even { splits: 4 }, + sensitivity: u8::try_from(v["ledSensitivity"].as_i64()?).ok()?, + color: ColorScheme::from_serde_value_or_default(v), }, "reactive-rainbow" => LightsMode::Reactive { faster: v["ledFaster"].as_bool()?, layout: ReactiveLayout::Rainbow, sensitivity: u8::try_from(v["ledSensitivity"].as_i64()?).ok()?, + color: ColorScheme::default(), }, "reactive-voltex" => LightsMode::Reactive { faster: v["ledFaster"].as_bool()?, layout: ReactiveLayout::Voltex, sensitivity: u8::try_from(v["ledSensitivity"].as_i64()?).ok()?, + color: ColorScheme::default(), }, "attract" => LightsMode::Attract { faster: v["ledFaster"].as_bool()?, diff --git a/src-slider_io/src/lighting/lighting.rs b/src-slider_io/src/lighting/lighting.rs index 1ee79c1..330a389 100644 --- a/src-slider_io/src/lighting/lighting.rs +++ b/src-slider_io/src/lighting/lighting.rs @@ -48,8 +48,8 @@ impl LightsJob { serial_buffer: Option<&Buffer>, lights: &mut SliderLights, ) { - match self.mode { - LightsMode::Reactive { layout, .. } => { + match &self.mode { + LightsMode::Reactive { layout, color, .. } => { let flat_input = flat_input.unwrap(); match layout { @@ -58,23 +58,55 @@ impl LightsJob { let banks: Vec = flat_input .chunks(32 / splits) - .take(splits) + .take(*splits) .map(|x| x.contains(&true)) .collect(); for idx in 0..31 { lights.paint( idx, - match (idx + 1) % buttons_per_split { - 0 => &[255, 0, 255], + match ((idx + 1) % buttons_per_split, (idx + 1) % 2) { + (0, _) => &color.active, + (_, 0) => &color.inactive, _ => match banks[idx / buttons_per_split] { - true => &[255, 0, 255], - false => &[255, 255, 0], + true => &color.active, + false => &color.inactive, }, }, ); } } + ReactiveLayout::Six => { + let banks: Vec = [0..6, 6..10, 10..16, 16..22, 22..26, 26..32] + .into_iter() + .map(|x| flat_input[x].contains(&true)) + .collect(); + + for idx in (1..31).step_by(2) { + lights.paint( + idx, + match idx { + 5 | 9 | 15 | 21 | 25 => &color.active, + _ => &color.inactive, + }, + ); + } + + for (bank_idxs, bank_val) in [0..6, 6..10, 10..16, 16..22, 22..26, 26..32] + .into_iter() + .zip(banks) + { + for idx in bank_idxs.step_by(2) { + lights.paint( + idx, + match bank_val { + true => &color.active, + false => &color.inactive, + }, + ) + } + } + } ReactiveLayout::Voltex => { lights.ground.fill(0); diff --git a/src-slider_io/src/output/config.rs b/src-slider_io/src/output/config.rs index 460c289..0aa53a7 100644 --- a/src-slider_io/src/output/config.rs +++ b/src-slider_io/src/output/config.rs @@ -14,7 +14,9 @@ pub enum KeyboardLayout { Tasoller, Yuancon, TasollerHalf, - Deemo, + EightK, + SixK, + FourK, Voltex, Neardayo, } @@ -81,13 +83,23 @@ impl OutputMode { polling: PollingRate::from_str(v["outputPolling"].as_str()?)?, sensitivity: u8::try_from(v["keyboardSensitivity"].as_i64()?).ok()?, }, - "kb-16-tasoller" => OutputMode::Keyboard { + "kb-16" => OutputMode::Keyboard { layout: KeyboardLayout::TasollerHalf, polling: PollingRate::from_str(v["outputPolling"].as_str()?)?, sensitivity: u8::try_from(v["keyboardSensitivity"].as_i64()?).ok()?, }, - "kb-8-deemo" => OutputMode::Keyboard { - layout: KeyboardLayout::Deemo, + "kb-8" => OutputMode::Keyboard { + layout: KeyboardLayout::EightK, + polling: PollingRate::from_str(v["outputPolling"].as_str()?)?, + sensitivity: u8::try_from(v["keyboardSensitivity"].as_i64()?).ok()?, + }, + "kb-6" => OutputMode::Keyboard { + layout: KeyboardLayout::SixK, + polling: PollingRate::from_str(v["outputPolling"].as_str()?)?, + sensitivity: u8::try_from(v["keyboardSensitivity"].as_i64()?).ok()?, + }, + "kb-4" => OutputMode::Keyboard { + layout: KeyboardLayout::FourK, polling: PollingRate::from_str(v["outputPolling"].as_str()?)?, sensitivity: u8::try_from(v["keyboardSensitivity"].as_i64()?).ok()?, }, diff --git a/src-slider_io/src/output/keyboard.rs b/src-slider_io/src/output/keyboard.rs index 3bba847..97b4b4c 100644 --- a/src-slider_io/src/output/keyboard.rs +++ b/src-slider_io/src/output/keyboard.rs @@ -43,7 +43,7 @@ const TASOLLER_HALF_KB_MAP: [usize; 41] = [ ]; #[rustfmt::skip] -const DEEMO_KB_MAP: [usize; 41] = [ +const EIGHT_K_MAP: [usize; 41] = [ 0x41, 0x41, 0x41, 0x41, // A 0x53, 0x53, 0x53, 0x53, // S 0x44, 0x44, 0x44, 0x44, // D @@ -56,6 +56,28 @@ const DEEMO_KB_MAP: [usize; 41] = [ 0x00, 0x00, 0x00, // Disabled ]; +#[rustfmt::skip] +const SIX_K_MAP: [usize; 41] = [ + 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, // S + 0x44, 0x44, 0x44, 0x44, // D + 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, // F + 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, // J + 0x4b, 0x4b, 0x4b, 0x4b, // K + 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, // L + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // VK_SPACE + 0x00, 0x00, 0x00, // Disabled +]; + +#[rustfmt::skip] +const FOUR_K_MAP: [usize; 41] = [ + 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, // D + 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, // F + 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, // J + 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, // K + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, // VK_SPACE + 0x00, 0x00, 0x00, // Disabled +]; + #[rustfmt::skip] const VOLTEX_KB_MAP: [usize; 41] = [ 0x57, 0x57, 0x57, 0x57, // W @@ -109,7 +131,9 @@ impl KeyboardOutput { KeyboardLayout::Tasoller => &TASOLLER_KB_MAP, KeyboardLayout::Yuancon => &YUANCON_KB_MAP, KeyboardLayout::TasollerHalf => &TASOLLER_HALF_KB_MAP, - KeyboardLayout::Deemo => &DEEMO_KB_MAP, + KeyboardLayout::EightK => &EIGHT_K_MAP, + KeyboardLayout::SixK => &SIX_K_MAP, + KeyboardLayout::FourK => &FOUR_K_MAP, KeyboardLayout::Voltex => &VOLTEX_KB_MAP, KeyboardLayout::Neardayo => &VOLTEX_KB_MAP_NEARDAYO, }; diff --git a/src/App.svelte b/src/App.svelte index 1b988a4..a0d2d95 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -17,6 +17,8 @@ let outputPolling = "100"; let outputWebsocketUrl = "http://localhost:3000"; let ledFaster = false; + let ledColorActive = "#ff00ff"; + let ledColorInactive = "#ffff00"; let ledSensitivity = 20; let ledWebsocketUrl = "http://localhost:3001"; let ledSerialPort = "COM5"; @@ -68,6 +70,8 @@ outputWebsocketUrl = payload.outputWebsocketUrl || "http://localhost:3000/"; ledFaster = payload.ledFaster || false; + ledColorActive = payload.ledColorActive || "#ff00ff"; + ledColorInactive = payload.ledColorInactive || "#ffff00"; ledSensitivity = payload.ledSensitivity || 20; ledWebsocketUrl = payload.ledWebsocketUrl || "http://localhost:3001"; ledSerialPort = payload.ledSerialPort || "COM5"; @@ -119,6 +123,8 @@ outputPolling, outputWebsocketUrl, ledFaster, + ledColorActive, + ledColorInactive, ledSensitivity, ledWebsocketUrl, ledSerialPort, @@ -205,7 +211,10 @@
Brokenithm server running, access at one of:
-            {ips.map((x) => `http://${x}:1606/`).join("\n")}
+            {ips
+              .map((x) => `http://${x}:1606/`)
+              .join("\n")
+              .trim()}
           
@@ -264,10 +273,10 @@ - - + + + + @@ -350,9 +359,10 @@
+
+ +
+
Base Color
+
+ +
+
+ {/if} {#if ledMode.slice(0, 8) === "reactive" && deviceMode.slice(0, 10) !== "brokenithm"}