Skip to content

Commit

Permalink
feat: Refactor & improve
Browse files Browse the repository at this point in the history
(Author: michaelhatPIengineering)
  • Loading branch information
nytamin committed Mar 1, 2021
1 parent c5c7427 commit 0ce375e
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 71 deletions.
109 changes: 73 additions & 36 deletions src/products.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,74 +37,92 @@ export interface ProductTbar extends ProductBase {
export type Product = ProductBase | ProductJog | ProductShuttle | ProductTbar

export const PRODUCTS: {[name: string]: Product} = {

// Note: The byte numbers are byte index (starts with 0) and will be offset from documentation by -2
// these byte index are used to access the exact byte in the data report.

XK24: {
identifier: 'XK-24',
productId: [1029,1028,1027,1249],
productId: [1029,1027],
columns: 4,
rows: 6,
hasPS: true,
banks: 2,
bankSize: 32
},
XK4: { // This has not been tested
XK4: {
identifier: 'XK-4',
productId: [1127,1128,1129,1253, 1049],
productId: [1127,1129],
columns: 4,
rows: 1,
hasPS: false, // unknown
hasPS: true, // slide switch on end
banks: 1, // only has blue light
bankSize: 32 // unknown
},
XK8: { // This has not been tested
XK8: {
identifier: 'XK-8',
productId: [1130,1131,1132,1252],
columns: 8,
rows: 1,
hasPS: false, // unknown
productId: [1130,1132],
columns: 4,
rows: 2, // row1 = 0,1,2,3 row2=4,5,6,7
hasPS: true, // slide switch on end
banks: 1, // only has blue light
bankSize: 32 // unknown
},
XK12JOG: { // This has not been tested
XK12JOG: {
identifier: 'XK-12 Jog',
productId: [1062,1064],
columns: 4,
rows: 3,
hasPS: true,
hasJog: true,
jogByte: 8,
hasShuttle: true,
shuttleByte: 9,
jogByte: 6,
hasShuttle: true,
shuttleByte: 7,
banks: 2,
bankSize: 32
},
XK12JOYSTICK: { // This has not been tested
XK12JOYSTICK: {
identifier: 'XK-12 Joystick',
productId: [1065,1067],
columns: 4,
rows: 3,
hasPS: true,
hasJoystick: true,
// joyXbyte: 7
// joyYbyte: 8
// joyZbyte: 9 // twist of stick

banks: 2,
bankSize: 32
},
XK16: { // This has not been tested
XK16: {
identifier: 'XK-16',
productId: [1269,1270,1050,1051,1251],
columns: 4,
rows: 4, // not really rows, but the data comes like that (it is physically one row)
hasPS: false, // unknown
productId: [1049,1051,1213,1216],
columns: 4, // 4 buttton data bytes
rows: 4, // not really rows, but the data comes like that (it is physically one row) row1= 0,1,2,3 row2=4,5,6,7 row3= 8,9,10,11 row4=12,13,14,15
hasPS: true, // slide switch on end
banks: 1, // only has blue light
bankSize: 32 // unknown
bankSize: 0, // only one set LEDs under keys
//btnLocation: ['r1c1','r1c5','r1c9','r1c13','r1c2','r1c6','r1c10','r1c14','r1c3','r1c7','r1c11','r1c15','r1c4','r1c8','r1c12','r1c16']
},
XR32: { // This has not been tested
XKR32: { // discontinued product, XKE 40 is viable replacement
identifier: 'XR-32',
productId: [1279,1280,1281,1282],
columns: 16,
rows: 2,
productId: [1279,1282],
columns: 4, // 4 buttton data bytes
rows: 8,
hasPS: false, // unknown
bankSize: 128
},
XK60: { // This has not been tested
XKE40: {
identifier: 'XKE-40',
productId: [1358,1359,1360,1361],
columns: 5, // 5 buttton data bytes
rows: 8, // row1=0,8,16,24,32 row2=1,9,17,25,33 row3=2,10,18,26,34 row4=3,11,19,27,35 row5=4,12,20,28,36 row6=5,13,21,29,37 row7=6,14,22,30,38 row8=7,15,23,31,39
hasPS: true, // behind small hole on left side.
bankSize: 40 // off set to control second led bank.
},

XK60: {
identifier: 'XK-60',
productId: [1239,1240,1121,1122,1123,1254],
columns: 10,
Expand All @@ -115,7 +133,7 @@ export const PRODUCTS: {[name: string]: Product} = {
},
XK80: {
identifier: 'XK-80',
productId: [1237,1238,1089,1090,1091,1250],
productId: [1237,1238,1089,1090,1091,1250],
columns: 10,
rows: 8,
hasPS: true,
Expand All @@ -124,18 +142,18 @@ export const PRODUCTS: {[name: string]: Product} = {
},
XKE124TBAR: {
identifier: 'XKE-124 T-bar',
productId: [1275,1276,1277,1278],
productId: [1275,1278],
columns: 16,
rows: 8,
hasPS: false,
hasTbar: true,
tbarByte: 30,
tbarByteRaw: 31,
tbarByte: 28, // should only use cal t-bar on byte index 28
tbarByteRaw: 29,
banks: 2,
bankSize: 128,
disableKeys: [108,109,110,111]
disableKeys: [108,109,110,111]
},
XKE128: { // This has not been tested
XKE128: {
identifier: 'XKE-128',
productId: [1227,1228,1229,1230],
columns: 16,
Expand All @@ -144,18 +162,37 @@ export const PRODUCTS: {[name: string]: Product} = {
banks: 2,
bankSize: 128
},
XK68JOGSHUTTLE: { // This has not been tested
XK68JOGSHUTTLE: {
identifier: 'XK-68 Jog-Shuttle',
productId: [1114, 1116],
productId: [1114, 1116],
columns: 10,
rows: 8,
hasPS: true,
hasJog: true,
jogByte: 16,
hasShuttle: true,
shuttleByte: 17,
banks: 2,
bankSize: 80,
disableKeys: [29,30,31, 37,38,39, 45,46,47, 53,54,55]

},
XK64JOGTBAR: {
identifier: 'XKE-64 Jog T-bar',
productId: [1325, 1326,1327,1328,1329,1330,1331],
columns: 10,
rows: 8,
hasPS: true,
hasJog: true,
jogByte: 18,
hasShuttle: true,
shuttleByte: 19,
hasShuttle: true,
shuttleByte: 19,
hasTbar: true,
tbarByte: 17, // should only use cal t-bar on byte index 17
tbarByteRaw: 15,
banks: 2,
bankSize: 80,
disableKeys: [29,30,31, 37,38,39, 45,46,47, 53,54,55]
disableKeys: [5,6,7,13,14,15,21,22,23,29,30,31,72,73,74,75] // These bits are messy, better to ignore them

}
}
87 changes: 52 additions & 35 deletions src/xkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,61 +125,79 @@ export class XKeys extends EventEmitter {
)
}

this.device.on('data', data => {
this.device.on('data', (data: Buffer) => {

// Note: first column is on word 2
if (!deviceInfo) return

const buttonStates: ButtonStates = {}
const buttonStates2: ButtonStates2 = { PS: false }
const analogStates: AnalogStates = {}

// UID, unit id, is used to uniquely identify a ceratin panel, from factory it's set to 0. It can be set by a user to be able to find a reconnected panel.
var UID = data.readUInt8(0) // the unit ID is the first byte, index 0, used to tell between 2 identical X-keys, UID is set by user
// @ts-ignore
var PID = deviceInfo.productId // from USB hardware ID
var productName = this.deviceType.identifier // name from products file

// var keyCol = 1 // use a 1 based system for Rows and Columns
// var keyRow = 1

var dd = data.readUInt8(1)
// The genData bit is set when the message is a reply to the Generate Data message
var genData = dd & (1 << 1) ? true : false
if (genData ) {
this.emit('unitID', UID, PID, productName)
}


// Note: first button data (column) is on byte index 2

for (let x: number = 0; x < this.deviceType.columns; x++) {
for (let y: number = 0; y < this.deviceType.rows; y++) {

const keyIndex: number = x * 8 + y
var keyIndex = x * this.deviceType.rows + y

const d = data.readUInt32LE(2 + x)
var d = data.readUInt8(2 + x)

const bit = d & (1 << y) ? true : false

buttonStates[keyIndex] = bit
}
}
if (this.deviceType.hasPS) {
// program switch-button is on word 1
const d = data.readUInt32LE(1)
// program switch-button is on byte index 1
var d = data.readUInt8(1)
const bit = d & (1 << 0) ? true : false
buttonStates2.PS = bit
}
if (this.deviceType.hasJog) {
if (this.deviceType.hasJog && this.deviceType.jogByte !== undefined ) {

const d = data[(this.deviceType.jogByte || 0) - 2] // Jog
var d = data[(this.deviceType.jogByte ) ] // Jog
analogStates.jog = (d < 128 ? d : d - 256)
}
if (this.deviceType.hasShuttle) {
const d = data[(this.deviceType.shuttleByte || 0) - 2] // Shuttle
if (this.deviceType.hasShuttle && this.deviceType.shuttleByte !== undefined) {
var d = data[(this.deviceType.shuttleByte ) ] // Shuttle
analogStates.shuttle = (d < 128 ? d : d - 256)
}
if (this.deviceType.hasJoystick) {
let d = data.readUInt32LE(7) // Joystick X
analogStates.joystick_x = (d < 128 ? d : d - 256)

d = data.readUInt32LE(8) // Joystick Y
analogStates.joystick_y = (d < 128 ? d : d - 256)

d = data.readUInt32LE(9) // Joystick Z (twist of joystick)
analogStates.joystick_z = (d < 128 ? d : d - 256)
var d = data.readUInt8(6); // Joystick X
analogStates.joystick_x = (d < 128 ? d : d - 256);
d = data.readUInt8(7); // Joystick Y
analogStates.joystick_y = (d < 128 ? -d : -(d - 256));
d = data.readUInt8(8); // Joystick Z (twist of joystick)
analogStates.joystick_z = (d); // joystick z is a continuous value that rolls over to 0 after 255

}
if (this.deviceType.hasTbar) {
let d = data[(this.deviceType.tbarByte || 0) - 2] // T-bar (calibrated)
if (this.deviceType.hasTbar && this.deviceType.tbarByte !== undefined) {
var d = data.readUInt8(this.deviceType.tbarByte ) // T-bar (calibrated)
analogStates.tbar = d

d = data.readUInt16BE((this.deviceType.tbarByteRaw || 0) - 2) // T-bar (uncalibrated)
analogStates.tbar_raw = d
// Note: The uncalibrated shouldn't be used at all, it's only used by manufacturer
// d = data.readUInt16BE((this.deviceType.tbarByteRaw || 0) - 2) // T-bar (uncalibrated)
// analogStates.tbar_raw = d
}

// Disabled/nonexisting keys:
// Disabled/nonexisting keys: // important as some keys in the jog & shuttle devices are used to shuttle events.
if (this.deviceType.disableKeys) {
this.deviceType.disableKeys.forEach((keyIndex) => {
buttonStates[keyIndex] = false
Expand All @@ -190,23 +208,23 @@ export class XKeys extends EventEmitter {
// compare with previous button states:
if ((this._buttonStates[buttonStateKey] || false) !== buttonStates[buttonStateKey]) {
if (buttonStates[buttonStateKey]) { // key is pressed
this.emit('down', buttonStateKey)
this.emit('downKey', buttonStateKey)
this.emit('down', buttonStateKey, UID, PID, productName);
this.emit('downKey', buttonStateKey, UID, PID, productName);
} else {
this.emit('up', buttonStateKey)
this.emit('upKey', buttonStateKey)
this.emit('up', buttonStateKey,UID, PID, productName);
this.emit('upKey', buttonStateKey, UID, PID, productName);
}
}
}
for (const buttonStates2Key in buttonStates2) {
// compare with previous button states:
if ((this._buttonStates2[buttonStates2Key] || false) !== buttonStates2[buttonStates2Key]) {
if (buttonStates2[buttonStates2Key]) { // key is pressed
this.emit('down', buttonStates2Key)
this.emit('downAlt', buttonStates2Key)
this.emit('down', buttonStates2Key, UID, PID, productName);
this.emit('downAlt', buttonStates2Key, UID, PID, productName);
} else {
this.emit('up', buttonStates2Key)
this.emit('upAlt', buttonStates2Key)
this.emit('up', buttonStates2Key, UID, PID, productName);
this.emit('upAlt', buttonStates2Key, UID, PID, productName);
}
}
}
Expand All @@ -220,10 +238,9 @@ export class XKeys extends EventEmitter {
analogStateKey === 'shuttle'
) {
this.emit(analogStateKey , analogStates[analogStateKey])
} else if (
analogStateKey === 'tbar_raw'
) {
this.emit('tbar', analogStates.tbar, analogStates.tbar_raw)
} else if (analogStateKey === 'tbar') {
this.emit('tbar', analogStates.tbar)

} else if (
analogStateKey === 'joystick_x' ||
analogStateKey === 'joystick_y' ||
Expand Down

0 comments on commit 0ce375e

Please sign in to comment.