Skip to content

Commit

Permalink
feat: prototype loupedeck live-s support
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Oct 9, 2022
1 parent 20950fc commit f370e6e
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/node/src/info.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum LoupedeckModelId {
LoupedeckLive = 'loupedeck-live',
LoupedeckLiveS = 'loupedeck-live-s',
RazerStreamController = 'razer-stream-controller',
}

Expand Down
7 changes: 7 additions & 0 deletions packages/node/src/models/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { LoupedeckLiveDevice } from './live'
import { LoupedeckSerialConnection } from '../serial'
import { RazerStreamControllerDevice } from './razer-stream-controller'
import { LoupedeckDevice } from './interface'
import { LoupedeckLiveSDevice } from './live-s'

export interface DeviceModelSpec {
id: LoupedeckModelId
Expand All @@ -21,6 +22,12 @@ export const DEVICE_MODELS: DeviceModelSpec[] = [
productId: 0x0004,
class: LoupedeckLiveDevice,
},
{
id: LoupedeckModelId.LoupedeckLiveS,
vendorId: VendorIdLoupedeck,
productId: 0x0006,
class: LoupedeckLiveSDevice,
},
{
id: LoupedeckModelId.RazerStreamController,
vendorId: VendorIdRazer,
Expand Down
75 changes: 75 additions & 0 deletions packages/node/src/models/live-s.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { LoupedeckTouchObject } from '../events'
import { LoupedeckControlType, LoupedeckDisplayId } from '../constants'
import { LoupedeckSerialConnection } from '../serial'
import {
LoupedeckControlDefinition,
LoupedeckDisplayDefinition,
LoupedeckDeviceBase,
LoupedeckDeviceOptions,
} from './base'
import { LoupedeckModelId } from '..'

const DisplayCenter: LoupedeckDisplayDefinition = {
id: LoupedeckDisplayId.Center,
width: 480,
height: 270,
encoded: Buffer.from([0x00, 0x4d]),
}

const Controls: LoupedeckControlDefinition[] = []
for (let i = 0; i < 2; i++) {
Controls.push({
type: LoupedeckControlType.Rotary,
index: i,
encoded: 0x01 + i,
})
}
for (let i = 0; i < 4; i++) {
Controls.push({
type: LoupedeckControlType.Button,
index: i,
encoded: 0x03 + i,
})
}

export class LoupedeckLiveSDevice extends LoupedeckDeviceBase {
private readonly touches: Record<number, LoupedeckTouchObject> = {}

constructor(connection: LoupedeckSerialConnection, options: LoupedeckDeviceOptions) {
super(connection, options, [DisplayCenter], Controls)
}

public get modelName(): string {
return 'Loupedeck Live S'
}
public get modelId(): LoupedeckModelId {
return LoupedeckModelId.LoupedeckLiveS
}

protected onTouch(event: 'touchmove' | 'touchend' | 'touchstart', buff: Buffer): void {
const x = buff.readUInt16BE(1)
const y = buff.readUInt16BE(3)
const id = buff.readUInt8(5)
// Determine target

const screen = DisplayCenter.id

const column = Math.floor((x - 15) / 90)
const row = Math.floor(y / 90)
const key = row * 5 + column

// Create touch
const touch: LoupedeckTouchObject = { x, y, id, target: { screen, key } }

// End touch, remove from local cache
if (event === 'touchend') {
delete this.touches[touch.id]
} else {
// First time seeing this touch, emit touchstart instead of touchmove
if (!this.touches[touch.id]) event = 'touchstart'
this.touches[touch.id] = touch
}

this.emit(event, { touches: Object.values(this.touches), changedTouches: [touch] })
}
}

0 comments on commit f370e6e

Please sign in to comment.