Speed up frames and add key test sweeps
Drop the per-packet device.pause(1), which rounds up to the Windows timer tick and capped the keyboard at roughly 10 fps; keep a pause in low frame-rate mode. Add a "Key test" option with column and row sweeps to verify the LED map. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ba56c6f8de
commit
c38d8de942
2 files changed
+15
-3
No files matched your search
@@ -8,6 +8,9 @@ product ID or have a K87 layout, so the keyboard is ignored without this plugin.
|
|||||||
|
|
||||||
Copy `Womier_K87_EVision.js` to `%USERPROFILE%\Documents\WhirlwindFX\Plugins\` and restart SignalRGB.
|
Copy `Womier_K87_EVision.js` to `%USERPROFILE%\Documents\WhirlwindFX\Plugins\` and restart SignalRGB.
|
||||||
|
|
||||||
|
The device settings have a "Key test" option (column or row sweep) to check the LED map,
|
||||||
|
and "Low frame-rate mode" in case the keyboard drops frames at full speed.
|
||||||
|
|
||||||
## Protocol
|
## Protocol
|
||||||
|
|
||||||
- HID interface 1, usage page `0xFF1C`, usage `0x92` (collection 4), 64-byte output reports.
|
- HID interface 1, usage page `0xFF1C`, usage `0x92` (collection 4), 64-byte output reports.
|
||||||
|
|||||||
+12
-3
@@ -16,13 +16,15 @@ shutdownColor:readonly
|
|||||||
LightingMode:readonly
|
LightingMode:readonly
|
||||||
forcedColor:readonly
|
forcedColor:readonly
|
||||||
lowFPS:readonly
|
lowFPS:readonly
|
||||||
|
keyTest:readonly
|
||||||
*/
|
*/
|
||||||
export function ControllableParameters() {
|
export function ControllableParameters() {
|
||||||
return [
|
return [
|
||||||
{property:"shutdownColor", group:"lighting", label:"Shutdown Color", description: "This color is applied to the device when the System, or SignalRGB is shutting down", min:"0", max:"360", type:"color", default:"#000000"},
|
{property:"shutdownColor", group:"lighting", label:"Shutdown Color", description: "This color is applied to the device when the System, or SignalRGB is shutting down", min:"0", max:"360", type:"color", default:"#000000"},
|
||||||
{property:"LightingMode", group:"lighting", label:"Lighting Mode", description: "Determines where the device's RGB comes from. Canvas will pull from the active Effect, while Forced will override it to a specific color", type:"combobox", values:["Canvas", "Forced"], default:"Canvas"},
|
{property:"LightingMode", group:"lighting", label:"Lighting Mode", description: "Determines where the device's RGB comes from. Canvas will pull from the active Effect, while Forced will override it to a specific color", type:"combobox", values:["Canvas", "Forced"], default:"Canvas"},
|
||||||
{property:"forcedColor", group:"lighting", label:"Forced Color", description: "The color used when 'Forced' Lighting Mode is enabled", min:"0", max:"360", type:"color", default:"#009bde"},
|
{property:"forcedColor", group:"lighting", label:"Forced Color", description: "The color used when 'Forced' Lighting Mode is enabled", min:"0", max:"360", type:"color", default:"#009bde"},
|
||||||
{property:"lowFPS", group:"lighting", label:"Low frame-rate mode", description: "Sends smaller packets with longer pauses, can improve stability", type:"boolean", default:false},
|
{property:"lowFPS", group:"lighting", label:"Low frame-rate mode", description: "Sends smaller packets with pauses in between, can improve stability", type:"boolean", default:false},
|
||||||
|
{property:"keyTest", group:"lighting", label:"Key test", description: "Sweeps a white line across the keys to check the LED map", type:"combobox", values:["Off", "Column sweep", "Row sweep"], default:"Off"},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,6 +77,8 @@ export function Shutdown(SystemSuspending) {
|
|||||||
|
|
||||||
function sendColors(overrideColor) {
|
function sendColors(overrideColor) {
|
||||||
const RGBData = new Array(LED_SLOTS * 3).fill(0);
|
const RGBData = new Array(LED_SLOTS * 3).fill(0);
|
||||||
|
const [width, height] = Size();
|
||||||
|
const step = Math.floor(Date.now() / 500);
|
||||||
|
|
||||||
for (let iIdx = 0; iIdx < vLeds.length; iIdx++) {
|
for (let iIdx = 0; iIdx < vLeds.length; iIdx++) {
|
||||||
const [iPxX, iPxY] = vLedPositions[iIdx];
|
const [iPxX, iPxY] = vLedPositions[iIdx];
|
||||||
@@ -82,6 +86,10 @@ function sendColors(overrideColor) {
|
|||||||
|
|
||||||
if (overrideColor) {
|
if (overrideColor) {
|
||||||
color = hexToRgb(overrideColor);
|
color = hexToRgb(overrideColor);
|
||||||
|
} else if (keyTest === "Column sweep") {
|
||||||
|
color = iPxX === step % width ? [255, 255, 255] : [0, 0, 0];
|
||||||
|
} else if (keyTest === "Row sweep") {
|
||||||
|
color = iPxY === step % height ? [255, 255, 255] : [0, 0, 0];
|
||||||
} else if (LightingMode === "Forced") {
|
} else if (LightingMode === "Forced") {
|
||||||
color = hexToRgb(forcedColor);
|
color = hexToRgb(forcedColor);
|
||||||
} else {
|
} else {
|
||||||
@@ -98,7 +106,6 @@ function sendColors(overrideColor) {
|
|||||||
|
|
||||||
function writeRGBPackage(RGBData) {
|
function writeRGBPackage(RGBData) {
|
||||||
const bytesToSend = lowFPS ? 48 : 56;
|
const bytesToSend = lowFPS ? 48 : 56;
|
||||||
const pauseDuration = lowFPS ? 3 : 1;
|
|
||||||
|
|
||||||
for (let offset = 0; offset < RGBData.length; offset += bytesToSend) {
|
for (let offset = 0; offset < RGBData.length; offset += bytesToSend) {
|
||||||
const data = RGBData.slice(offset, offset + bytesToSend);
|
const data = RGBData.slice(offset, offset + bytesToSend);
|
||||||
@@ -116,7 +123,9 @@ function writeRGBPackage(RGBData) {
|
|||||||
packet[2] = (sum >> 8) & 0xFF;
|
packet[2] = (sum >> 8) & 0xFF;
|
||||||
|
|
||||||
device.write(packet, 64);
|
device.write(packet, 64);
|
||||||
device.pause(pauseDuration);
|
|
||||||
|
// device.pause() rounds up to the Windows timer tick (up to ~15 ms), so only pause when asked
|
||||||
|
if (lowFPS) { device.pause(3); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user