Skip to content

Instantly share code, notes, and snippets.

@zombrodo
Created August 10, 2023 02:22
Show Gist options
  • Save zombrodo/e3fd9e987caeac67141e701cb49465c8 to your computer and use it in GitHub Desktop.
Save zombrodo/e3fd9e987caeac67141e701cb49465c8 to your computer and use it in GitHub Desktop.
HID controller for WoW
// -----------------------------------------------------------------------------
// Screenshot
// -----------------------------------------------------------------------------
const exec = require("child_process").exec;
const Jimp = require("jimp");
function tempPath() {
return "/tmp/healthbar-screenshot.png";
}
const dimensions = [1009, 893, 240, 1];
async function captureScreenshot() {
const filepath = tempPath();
const command = [
"screencapture", "-x", "-R", dimensions.join(), "-t", "png", filepath
].join(" ");
return new Promise((resolve, reject) => {
exec(command, (err => {
if (err) {
reject(err);
}
resolve();
}))
});
}
function kindaEquals(a, b) {
return Math.abs(a - b) < 5
}
function coloursEqual(a, b) {
return kindaEquals(a.r, b.r) && kindaEquals(a.g, b.g) && kindaEquals(a.b, b.b);
}
function findRatio(image, healthy) {
const length = image.getWidth();
let ratio = 0;
for(let x = 0; x < length; x++) {
if (coloursEqual(healthy, Jimp.intToRGBA(image.getPixelColor(x, 0)))) {
ratio++;
}
}
return ratio / length;
}
async function analysePicture() {
const filepath = tempPath();
const image = await Jimp.read(filepath);
const health = Jimp.intToRGBA(image.getPixelColor(0, 0));
return findRatio(image, health);
}
// -----------------------------------------------------------------------------
// Keyboard
// -----------------------------------------------------------------------------
const HID = require("node-hid");
const VENDOR_ID = 0x3434;
const PRODUCT_ID = 0x0311;
const COMMAND_START = 0x00;
const BACKLIGHT_CONFIG_SET_VALUE = 0x07;
const QMK_RGBLIGHT = 0x83;
function padArray(input) {
const result = new Array(33).fill(0);
input.forEach((b, i) => result[i] = b);
return result;
}
const green = 64
const red = 0;
function lerp(a, b, t) {
return a + (b - a) * t;
}
function connectDevice() {
const device = new HID.HID(VENDOR_ID, PRODUCT_ID);
return device
}
function setColour(device, ratio) {
const hue = lerp(red, green, ratio);
try {
const command = [COMMAND_START, BACKLIGHT_CONFIG_SET_VALUE, QMK_RGBLIGHT, hue, 0xff];
const padded = padArray(command);
device.write(padded.slice(0, padded.length - 1))
} catch(err) {
console.error(err);
}
}
// -----------------------------------------------------------------------------
// Entrypoint
// -----------------------------------------------------------------------------
async function iteration(device) {
await captureScreenshot();
const ratio = await analysePicture();
setColour(device, ratio)
}
function run() {
const device = connectDevice();
process.on("SIGINT", () => {
device.close();
process.exit();
});
setInterval(async () => {
await iteration(device);
}, 1000)
}
run();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment