Add Womier K87 SignalRGB plugin and LED mapping tools
Per-key RGB for the wired Womier K87 (EVision firmware, 320F:502A) using the EVision protocol, with the 87-key LED map found by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
ba56c6f8de
4 files changed
+254
No files matched your search
@@ -0,0 +1,65 @@
|
||||
# Sends an EVision per-key colour frame (same packets as SignalRGB's EVision plugin)
|
||||
# Usage: evision_led.ps1 -Leds "0=ff0000,21=00ff00" [-Fill 000000] [-Count 128] [-Seconds 0] [-SoftwareMode]
|
||||
param(
|
||||
[string]$Leds = '',
|
||||
[string]$Fill = '000000',
|
||||
[int]$Count = 128,
|
||||
[double]$Seconds = 0,
|
||||
[switch]$SoftwareMode,
|
||||
[string]$Match = 'VID_320F&PID_502A&MI_01&COL04'
|
||||
)
|
||||
Add-Type @"
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
public static class EV {
|
||||
[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Unicode)]
|
||||
public static extern IntPtr CreateFile(string n, uint a, uint s, IntPtr sa, uint c, uint f, IntPtr t);
|
||||
[DllImport("kernel32.dll", SetLastError=true)]
|
||||
public static extern bool WriteFile(IntPtr h, byte[] b, int n, out int w, IntPtr o);
|
||||
[DllImport("kernel32.dll")] public static extern bool CloseHandle(IntPtr h);
|
||||
}
|
||||
"@
|
||||
$dev = Get-PnpDevice -PresentOnly -Class HIDClass | Where-Object { $_.InstanceId -match [regex]::Escape($Match) } | Select-Object -First 1
|
||||
if (-not $dev) { throw "RGB endpoint $Match not found" }
|
||||
$path = '\\?\' + ($dev.InstanceId -replace '\\','#') + '#{4d1e55b2-f16f-11cf-88cb-001111000030}'
|
||||
$h = [EV]::CreateFile($path, [uint32]3221225472, 3, [IntPtr]::Zero, 3, 0, [IntPtr]::Zero)
|
||||
if ($h -eq [IntPtr]-1) { throw "open failed, error $([Runtime.InteropServices.Marshal]::GetLastWin32Error())" }
|
||||
|
||||
function Send([byte[]]$pkt) {
|
||||
$buf = New-Object byte[] 64; [Array]::Copy($pkt, $buf, [Math]::Min(64, $pkt.Length))
|
||||
$w = 0
|
||||
if (-not [EV]::WriteFile($h, $buf, 64, [ref]$w, [IntPtr]::Zero)) { throw "write failed, error $([Runtime.InteropServices.Marshal]::GetLastWin32Error())" }
|
||||
}
|
||||
function Rgb([string]$hex) { $hex = $hex.TrimStart('#'); ,([byte[]]@([Convert]::ToByte($hex.Substring(0,2),16), [Convert]::ToByte($hex.Substring(2,2),16), [Convert]::ToByte($hex.Substring(4,2),16))) }
|
||||
|
||||
# Build the colour buffer
|
||||
$data = New-Object byte[] ($Count * 3)
|
||||
$f = Rgb $Fill
|
||||
for ($i = 0; $i -lt $Count; $i++) { $data[$i*3] = $f[0]; $data[$i*3+1] = $f[1]; $data[$i*3+2] = $f[2] }
|
||||
foreach ($e in ($Leds -split ',' | Where-Object { $_ })) {
|
||||
$idx, $col = $e.Split('=')
|
||||
if ($idx -match '^(\d+)-(\d+)$') { $range = [int]$Matches[1]..[int]$Matches[2] } else { $range = @([int]$idx) }
|
||||
$c = Rgb $col
|
||||
foreach ($i in $range) { if ($i -lt $Count) { $data[$i*3] = $c[0]; $data[$i*3+1] = $c[1]; $data[$i*3+2] = $c[2] } }
|
||||
}
|
||||
|
||||
function SendFrame {
|
||||
$per = 56
|
||||
for ($off = 0; $off -lt $data.Length; $off += $per) {
|
||||
$chunk = New-Object byte[] $per
|
||||
[Array]::Copy($data, $off, $chunk, 0, [Math]::Min($per, $data.Length - $off))
|
||||
$pkt = [byte[]](@(0x04, 0, 0, 0x12, $per, ($off -band 0xFF), (($off -shr 8) -band 0xFF), 0) + $chunk)
|
||||
# checksum = 16-bit sum of bytes 3..63 (matches the plugin's formula)
|
||||
$sum = 0; for ($k = 3; $k -lt 64; $k++) { $sum += $pkt[$k] }
|
||||
$pkt[1] = $sum -band 0xFF; $pkt[2] = ($sum -shr 8) -band 0xFF
|
||||
Send $pkt
|
||||
Start-Sleep -Milliseconds 1
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if ($SoftwareMode) { Send ([byte[]]@(0x04, 0x8c, 0x00, 0x0b, 0x30, 0x50, 0x01)); Start-Sleep -Milliseconds 20 }
|
||||
$end = (Get-Date).AddSeconds($Seconds); $n = 0
|
||||
do { SendFrame; $n++; if ($Seconds -gt 0) { Start-Sleep -Milliseconds 100 } } while ((Get-Date) -lt $end)
|
||||
"sent $n frame(s), $([Math]::Ceiling($data.Length / 56)) packets each"
|
||||
} finally { [void][EV]::CloseHandle($h) }
|
||||
Reference in new issue
Block a user