Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Julusian committed Jul 11, 2024
1 parent 4165aef commit 282427c
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 53 deletions.
70 changes: 39 additions & 31 deletions packages/core/src/imageWriter/headerGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { uint8ArrayToDataView } from '../util'
import type { StreamdeckImageHeaderGenerator, StreamdeckImageWriterProps } from './types'

export class StreamdeckGen1ImageHeaderGenerator implements StreamdeckImageHeaderGenerator {
Expand All @@ -6,18 +7,19 @@ export class StreamdeckGen1ImageHeaderGenerator implements StreamdeckImageHeader
}

writeFillImageCommandHeader(
buffer: Buffer,
buffer: Uint8Array,
props: StreamdeckImageWriterProps,
partIndex: number,
isLast: boolean,
_bodyLength: number
): void {
buffer.writeUInt8(0x02, 0)
buffer.writeUInt8(0x01, 1)
buffer.writeUInt16LE(partIndex, 2)
// 3 = 0x00
buffer.writeUInt8(isLast ? 1 : 0, 4)
buffer.writeUInt8(props.keyIndex + 1, 5)
const bufferView = uint8ArrayToDataView(buffer)

bufferView.setUint8(0, 0x02)
bufferView.setUint8(2, 0x01)
bufferView.setUint16(2, partIndex, true)
bufferView.setUint8(4, isLast ? 1 : 0)
bufferView.setUint8(5, props.keyIndex + 1)
}
}

Expand All @@ -27,18 +29,20 @@ export class StreamdeckGen2ImageHeaderGenerator implements StreamdeckImageHeader
}

writeFillImageCommandHeader(
buffer: Buffer,
buffer: Uint8Array,
props: StreamdeckImageWriterProps,
partIndex: number,
isLast: boolean,
bodyLength: number
): void {
buffer.writeUInt8(0x02, 0)
buffer.writeUInt8(0x07, 1)
buffer.writeUInt8(props.keyIndex, 2)
buffer.writeUInt8(isLast ? 1 : 0, 3)
buffer.writeUInt16LE(bodyLength, 4)
buffer.writeUInt16LE(partIndex++, 6)
const bufferView = uint8ArrayToDataView(buffer)

bufferView.setUint8(0, 0x02)
bufferView.setUint8(1, 0x07)
bufferView.setUint8(2, props.keyIndex)
bufferView.setUint8(3, isLast ? 1 : 0)
bufferView.setUint16(4, bodyLength, true)
bufferView.setUint16(4, partIndex++, true)
}
}

Expand All @@ -56,21 +60,23 @@ export class StreamdeckPlusLcdImageHeaderGenerator
}

writeFillImageCommandHeader(
buffer: Buffer,
buffer: Uint8Array,
props: StreamdeckPlusHeaderProps,
partIndex: number,
isLast: boolean,
bodyLength: number
): void {
buffer.writeUInt8(0x02, 0)
buffer.writeUInt8(0x0c, 1)
buffer.writeUInt16LE(props.x, 2)
buffer.writeUInt16LE(props.y, 4)
buffer.writeUInt16LE(props.width, 6)
buffer.writeUInt16LE(props.height, 8)
buffer.writeUInt8(isLast ? 1 : 0, 10) // Is last
buffer.writeUInt16LE(partIndex, 11)
buffer.writeUInt16LE(bodyLength, 13)
const bufferView = uint8ArrayToDataView(buffer)

bufferView.setUint8(0, 0x02)
bufferView.setUint8(1, 0x0c)
bufferView.setUint16(2, props.x, true)
bufferView.setUint16(4, props.y, true)
bufferView.setUint16(6, props.width, true)
bufferView.setUint16(8, props.height, true)
bufferView.setUint8(10, isLast ? 1 : 0)
bufferView.setUint16(11, partIndex, true)
bufferView.setUint16(13, bodyLength, true)
}
}

Expand All @@ -80,17 +86,19 @@ export class StreamdeckNeoLcdImageHeaderGenerator implements StreamdeckImageHead
}

writeFillImageCommandHeader(
buffer: Buffer,
buffer: Uint8Array,
_props: never,
partIndex: number,
isLast: boolean,
bodyLength: number
): void {
buffer.writeUInt8(0x02, 0)
buffer.writeUInt8(0x0b, 1)
buffer.writeUInt8(0, 2)
buffer.writeUInt8(isLast ? 1 : 0, 3)
buffer.writeUInt16LE(bodyLength, 4)
buffer.writeUInt16LE(partIndex++, 6)
const bufferView = uint8ArrayToDataView(buffer)

bufferView.setUint8(0, 0x02)
bufferView.setUint8(1, 0x0b)
bufferView.setUint8(2, 0)
bufferView.setUint8(3, isLast ? 1 : 0)
bufferView.setUint16(4, bodyLength, true)
bufferView.setUint16(6, partIndex, true)
}
}
12 changes: 6 additions & 6 deletions packages/core/src/imageWriter/imageWriter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ export class StreamdeckOriginalImageWriter implements StreamdeckImageWriter {

const packet1Bytes = byteBuffer.length / 2

const packet1 = Buffer.alloc(MAX_PACKET_SIZE)
const packet1 = new Uint8Array(MAX_PACKET_SIZE)
this.headerGenerator.writeFillImageCommandHeader(packet1, props, 0x01, false, packet1Bytes)
byteBuffer.copy(packet1, PACKET_HEADER_LENGTH, 0, packet1Bytes)
packet1.set(byteBuffer.subarray(0, packet1Bytes), PACKET_HEADER_LENGTH)

const packet2 = Buffer.alloc(MAX_PACKET_SIZE)
const packet2 = new Uint8Array(MAX_PACKET_SIZE)
this.headerGenerator.writeFillImageCommandHeader(packet2, props, 0x02, true, packet1Bytes)
byteBuffer.copy(packet2, PACKET_HEADER_LENGTH, packet1Bytes)
packet2.set(byteBuffer.subarray(packet1Bytes), PACKET_HEADER_LENGTH)

return [packet1, packet2]
}
Expand All @@ -42,7 +42,7 @@ export class StreamdeckDefaultImageWriter<TProps = StreamdeckImageWriterProps>

let remainingBytes = byteBuffer.length
for (let part = 0; remainingBytes > 0; part++) {
const packet = Buffer.alloc(MAX_PACKET_SIZE)
const packet = new Uint8Array(MAX_PACKET_SIZE)

const byteCount = Math.min(remainingBytes, MAX_PAYLOAD_SIZE)
this.headerGenerator.writeFillImageCommandHeader(
Expand All @@ -55,7 +55,7 @@ export class StreamdeckDefaultImageWriter<TProps = StreamdeckImageWriterProps>

const byteOffset = byteBuffer.length - remainingBytes
remainingBytes -= byteCount
byteBuffer.copy(packet, PACKET_HEADER_LENGTH, byteOffset, byteOffset + byteCount)
packet.set(byteBuffer.subarray(byteOffset, byteOffset + byteCount), PACKET_HEADER_LENGTH)

result.push(packet)
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/models/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export abstract class StreamDeckInputBase extends EventEmitter<StreamDeckEvents>
): Promise<void>
public abstract fillPanelBuffer(imageBuffer: Uint8Array, options?: FillPanelOptions): Promise<void>

public async fillLcd(_imageBuffer: Buffer, _sourceOptions: FillImageOptions): Promise<void> {
public async fillLcd(_imageBuffer: Uint8Array, _sourceOptions: FillImageOptions): Promise<void> {
throw new Error('Not supported for this model')
}
public async fillEncoderLcd(
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/models/neo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class StreamDeckNeo extends StreamDeckGen2Base {
}
}

public override async fillLcd(imageBuffer: Buffer, sourceOptions: FillImageOptions): Promise<void> {
public override async fillLcd(imageBuffer: Uint8Array, sourceOptions: FillImageOptions): Promise<void> {
const size = this.LCD_STRIP_SIZE
if (!size) throw new Error(`There is no lcd to fill`)

Expand All @@ -51,10 +51,10 @@ export class StreamDeckNeo extends StreamDeckGen2Base {
}

private async convertFillLcdBuffer(
sourceBuffer: Buffer,
sourceBuffer: Uint8Array,
size: LcdSegmentSize,
sourceOptions: FillImageOptions
): Promise<Buffer> {
): Promise<Uint8Array> {
const sourceOptions2: InternalFillImageOptions = {
format: sourceOptions.format,
offset: 0,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/models/plus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class StreamDeckPlus extends StreamDeckGen2Base {
}
}

public override async fillLcd(buffer: Buffer, sourceOptions: FillImageOptions): Promise<void> {
public override async fillLcd(buffer: Uint8Array, sourceOptions: FillImageOptions): Promise<void> {
const size = this.LCD_STRIP_SIZE
if (!size) throw new Error(`There is no lcd to fill`)

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export class StreamDeckProxy implements StreamDeck {
return this.device.getSerialNumber()
}

public async fillLcd(imageBuffer: Buffer, sourceOptions: FillImageOptions): Promise<void> {
public async fillLcd(imageBuffer: Uint8Array, sourceOptions: FillImageOptions): Promise<void> {
return this.device.fillLcd(imageBuffer, sourceOptions)
}

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export interface StreamDeck extends EventEmitter<StreamDeckEvents> {
* @param {Buffer} imageBuffer The image to write
* @param {Object} sourceOptions Options to control the write
*/
fillLcd(imageBuffer: Buffer, sourceOptions: FillImageOptions): Promise<void>
fillLcd(imageBuffer: Uint8Array, sourceOptions: FillImageOptions): Promise<void>

/**
* Fills the lcd strip above an encoder
Expand Down
11 changes: 8 additions & 3 deletions packages/core/src/util.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { uint8ArrayToDataView } from './util'

Check failure on line 1 in packages/core/src/util.ts

View workflow job for this annotation

GitHub Actions / lint

Import declaration conflicts with local declaration of 'uint8ArrayToDataView'.
import { InternalFillImageOptions } from './models/base'

export interface FillImageTargetOptions {
Expand All @@ -17,10 +18,10 @@ export function transformImageBuffer(
): Uint8Array {
if (!imageHeight) imageHeight = imageWidth

const imageBufferView = new DataView(imageBuffer)
const imageBufferView = uint8ArrayToDataView(imageBuffer)

const byteBuffer = new Uint8Array(destPadding + imageWidth * imageHeight * targetOptions.colorMode.length)
const byteBufferView = new DataView(byteBuffer)
const byteBufferView = uint8ArrayToDataView(byteBuffer)

const flipColours = sourceOptions.format.substring(0, 3) !== targetOptions.colorMode.substring(0, 3)

Expand Down Expand Up @@ -65,7 +66,7 @@ export function transformImageBuffer(

export const BMP_HEADER_LENGTH = 54
export function writeBMPHeader(buf: Uint8Array, iconSize: number, iconBytes: number, imagePPM: number): void {
const bufView = new DataView(buf)
const bufView = uint8ArrayToDataView(buf)
// Uses header format BITMAPINFOHEADER https://en.wikipedia.org/wiki/BMP_file_format

// Bitmap file header
Expand All @@ -89,3 +90,7 @@ export function writeBMPHeader(buf: Uint8Array, iconSize: number, iconBytes: num
bufView.setInt32(46, 0, true) // Colour pallette size
bufView.setInt32(50, 0, true) // 'Important' Colour count
}

export function uint8ArrayToDataView(buffer: Uint8Array): DataView {
return new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength)
}
4 changes: 2 additions & 2 deletions packages/node/src/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ export class NodeHIDSyncDevice extends EventEmitter implements HIDDevice {
}

public async sendFeatureReport(data: Uint8Array): Promise<void> {
this.device.sendFeatureReport(data)
this.device.sendFeatureReport(Buffer.from(data))
}
public async getFeatureReport(reportId: number, reportLength: number): Promise<Uint8Array> {
return Buffer.from(this.device.getFeatureReport(reportId, reportLength))
}
public async sendReports(buffers: Uint8Array[]): Promise<void> {
for (const data of buffers) {
this.device.write(data)
this.device.write(Buffer.from(data))
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/webhid-demo/src/demo/chase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class ChaseDemo implements Demo {
ctx.fillText(n.toString(), 8, canvas.height * 0.9, canvas.width * 0.8)

const id = ctx.getImageData(0, 0, canvas.width, canvas.height)
ps.push(device.fillKeyBuffer(i, Buffer.from(id.data), { format: 'rgba' }))
ps.push(device.fillKeyBuffer(i, id.data, { format: 'rgba' }))
ctx.restore()
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/webhid/src/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ export class WebHIDDevice extends EventEmitter implements CoreHIDDevice {
return this.device.forget()
}

public async sendFeatureReport(data: Buffer): Promise<void> {
return this.device.sendFeatureReport(data[0], new Uint8Array(data.subarray(1)))
public async sendFeatureReport(data: Uint8Array): Promise<void> {
return this.device.sendFeatureReport(data[0], data.subarray(1))
}
public async getFeatureReport(reportId: number, _reportLength: number): Promise<Uint8Array> {
const view = await this.device.receiveFeatureReport(reportId)
Expand All @@ -44,7 +44,7 @@ export class WebHIDDevice extends EventEmitter implements CoreHIDDevice {
public async sendReports(buffers: Uint8Array[]): Promise<void> {
return this.reportQueue.add(async () => {
for (const data of buffers) {
await this.device.sendReport(data[0], new Uint8Array(data.subarray(1)))
await this.device.sendReport(data[0], data.subarray(1))
}
})
}
Expand Down

0 comments on commit 282427c

Please sign in to comment.