mirror of
https://github.com/4yn/slidershim.git
synced 2024-11-12 00:40:49 +01:00
add 4k/6k layouts and reactive color customization
This commit is contained in:
parent
3a3e339aca
commit
2fb8995e68
@ -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<Self> {
|
||||
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<Self> {
|
||||
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()?,
|
||||
|
@ -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<bool> = 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<bool> = [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);
|
||||
|
||||
|
@ -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()?,
|
||||
},
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -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 @@
|
||||
<div class="serverlist">
|
||||
Brokenithm server running, access at one of:
|
||||
<pre>
|
||||
{ips.map((x) => `http://${x}:1606/`).join("\n")}
|
||||
{ips
|
||||
.map((x) => `http://${x}:1606/`)
|
||||
.join("\n")
|
||||
.trim()}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
@ -264,10 +273,10 @@
|
||||
<option value="kb-32-tasoller">Keyboard 32-zone, Tasoller Layout</option
|
||||
>
|
||||
<option value="kb-32-yuancon">Keyboard 32-zone, Yuancon Layout</option>
|
||||
<option value="kb-16-tasoller"
|
||||
>Keyboard 16-zone, Tasoller (Bottom Half) Layout</option
|
||||
>
|
||||
<option value="kb-8-deemo">Keyboard 8-zone, Deemo Layout</option>
|
||||
<option value="kb-16">Keyboard 16-zone, Linear</option>
|
||||
<option value="kb-8">Keyboard 8-zone, Linear</option>
|
||||
<option value="kb-6">Keyboard 6-zone, Linear</option>
|
||||
<option value="kb-4">Keyboard 4-zone, Linear</option>
|
||||
<option value="kb-voltex">Keyboard 10-zone, Voltex Layout</option>
|
||||
<option value="kb-neardayo">Keyboard 10-zone, Neardayo Layout</option>
|
||||
<option value="gamepad-voltex">XBOX 360 Gamepad, Voltex Layout</option>
|
||||
@ -350,9 +359,10 @@
|
||||
<div class="input">
|
||||
<select bind:value={ledMode} on:change={markDirty}>
|
||||
<option value="none">None</option>
|
||||
<option value="reactive-4">Reactive, 4-Zone</option>
|
||||
<option value="reactive-8">Reactive, 8-Zone</option>
|
||||
<option value="reactive-16">Reactive, 16-Zone</option>
|
||||
<option value="reactive-8">Reactive, 8-Zone</option>
|
||||
<option value="reactive-6">Reactive, 6-Zone</option>
|
||||
<option value="reactive-4">Reactive, 4-Zone</option>
|
||||
<option value="reactive-rainbow">Reactive, 16-Zone Rainbow</option>
|
||||
<option value="reactive-voltex">Reactive, Voltex Layout</option>
|
||||
<option value="attract">Rainbow Attract Mode</option>
|
||||
@ -378,6 +388,24 @@
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if ledMode.slice(0, 8) === "reactive" && ["16", "8", "6", "4"].includes(ledMode.slice(9))}
|
||||
<div class="row">
|
||||
<div class="label">Active Color</div>
|
||||
<div class="input">
|
||||
<input type="color" bind:value={ledColorActive} on:change={markDirty} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="label">Base Color</div>
|
||||
<div class="input">
|
||||
<input
|
||||
type="color"
|
||||
bind:value={ledColorInactive}
|
||||
on:change={markDirty}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if ledMode.slice(0, 8) === "reactive" && deviceMode.slice(0, 10) !== "brokenithm"}
|
||||
<div class="row">
|
||||
<div class="label" title="Larger means harder to trigger">
|
||||
|
Loading…
Reference in New Issue
Block a user