diff --git a/src/StreamDeckSharp/Hardware.cs b/src/StreamDeckSharp/Hardware.cs index 5530927..14ce3c4 100644 --- a/src/StreamDeckSharp/Hardware.cs +++ b/src/StreamDeckSharp/Hardware.cs @@ -92,6 +92,17 @@ static Hardware() ElgatoUsbId(0x0063), ElgatoUsbId(0x0090) ); + // .----------------------. + // | Stream Deck Module 6 | + // '----------------------' + + StreamDeckModule6 = + RegisterNewHardwareInternal( + "Stream Deck Module 6", + new GridKeyLayout(3, 2, 80, 25), + new HidComDriverStreamDeckModule6(), + ElgatoUsbId(0x00B8) + ); } /// @@ -118,6 +129,10 @@ static Hardware() /// Details about the Stream Deck Mini /// public static IUsbHidHardware StreamDeckMini { get; } + /// + /// Details about the Stream Deck Module 6 + /// + public static IUsbHidHardware StreamDeckModule6 { get; } /// /// This method registers a new (currently unknown to this library) hardware driver. @@ -196,3 +211,6 @@ internal static UsbHardwareIdAndDriver GetInternalHardwareInfos(UsbVendorProduct } } } + + + diff --git a/src/StreamDeckSharp/Internals/HidComDriverStreamDeckMini.cs b/src/StreamDeckSharp/Internals/HidComDriverStreamDeckMini.cs index bd185a3..eb56ed6 100644 --- a/src/StreamDeckSharp/Internals/HidComDriverStreamDeckMini.cs +++ b/src/StreamDeckSharp/Internals/HidComDriverStreamDeckMini.cs @@ -6,7 +6,7 @@ namespace StreamDeckSharp.Internals /// /// HID Stream Deck communication driver for the Stream Deck Mini. /// - public sealed class HidComDriverStreamDeckMini + public class HidComDriverStreamDeckMini : IStreamDeckHidComDriver { private const int ColorChannels = 3; @@ -46,22 +46,22 @@ public HidComDriverStreamDeckMini(int imgSize) public int ReportSize => 1024; /// - public int ExpectedFeatureReportLength => 17; + public virtual int ExpectedFeatureReportLength => 17; /// - public int ExpectedOutputReportLength => 1024; + public virtual int ExpectedOutputReportLength => 1024; /// - public int ExpectedInputReportLength => 17; + public virtual int ExpectedInputReportLength => 17; /// - public int KeyReportOffset => 1; + public virtual int KeyReportOffset => 1; /// - public byte FirmwareVersionFeatureId => 4; + public virtual byte FirmwareVersionFeatureId => 4; /// - public byte SerialNumberFeatureId => 3; + public virtual byte SerialNumberFeatureId => 3; /// public int FirmwareVersionReportSkip => 5; @@ -112,7 +112,7 @@ public int HardwareKeyIdToExtKeyId(int hardwareKeyId) } /// - public void PrepareDataForTransmission( + public virtual void PrepareDataForTransmission( byte[] data, int pageNumber, int payloadLength, @@ -128,7 +128,7 @@ bool isLast } /// - public byte[] GetBrightnessMessage(byte percent) + public virtual byte[] GetBrightnessMessage(byte percent) { if (percent > 100) { @@ -147,7 +147,7 @@ public byte[] GetBrightnessMessage(byte percent) } /// - public byte[] GetLogoMessage() + public virtual byte[] GetLogoMessage() { return new byte[] { 0x0B, 0x63 }; } diff --git a/src/StreamDeckSharp/Internals/HidComDriverStreamDeckModule6.cs b/src/StreamDeckSharp/Internals/HidComDriverStreamDeckModule6.cs new file mode 100644 index 0000000..fe181e8 --- /dev/null +++ b/src/StreamDeckSharp/Internals/HidComDriverStreamDeckModule6.cs @@ -0,0 +1,100 @@ +using System; + +namespace StreamDeckSharp.Internals +{ + /// + /// HID communication driver for Stream Deck Module 6 Keys + /// Based on official Elgato HID documentation: https://docs.elgato.com/streamdeck/hid/module-6 + /// Inherits shared image processing logic from . + /// + public sealed class HidComDriverStreamDeckModule6 : HidComDriverStreamDeckMini + { + private const int ImageSize = 80; // Module 6 uses 80�80 pixel keys per official specs + + /// + /// Initializes a new instance of the class. + /// + public HidComDriverStreamDeckModule6() + : base(ImageSize) + { + } + + // Module 6 specifications per official docs (override Mini's values where different) + + /// + public override int ExpectedFeatureReportLength => 32; // Feature reports are 32 bytes + + /// + public override int ExpectedInputReportLength => 65; // Input reports are 65 bytes + + /// + public override byte FirmwareVersionFeatureId => 0xA1; // AP2 (Primary firmware) + + /// + /// Prepares packet header for Module 6 image upload + /// Per official docs: https://docs.elgato.com/streamdeck/hid/module-6/#upload-data-to-image-memory-bank + /// Offset 0x00: Report ID (0x02) + /// Offset 0x01: Command (0x01) + /// Offset 0x02: Chunk Index + /// Offset 0x03: Reserved (0x00) + /// Offset 0x04: Show Image flag (0x01 to display immediately) + /// Offset 0x05: Key Index + /// Offset 0x06-0x0F: Reserved (10 bytes of 0x00) + /// Offset 0x10+: Chunk Data + /// + public override void PrepareDataForTransmission(byte[] data, int pageNumber, int payloadLength, int keyId, bool isLast) + { + data[0] = 0x02; // Report ID + data[1] = 0x01; // Command: Upload Data to Image Memory Bank + data[2] = (byte)pageNumber; // Chunk Index + data[3] = 0x00; // Reserved + data[4] = (byte)(isLast ? 0x01 : 0x00); // Show Image flag (show on last packet) + data[5] = (byte)(keyId + 1); // Key Index (0-5 for Module 6) + + // Reserved space (bytes 6-15, total 10 bytes) + for (int i = 6; i < 16; i++) + { + data[i] = 0x00; + } + + // Payload data starts at offset 0x10 (byte 16) + } + + /// + /// Creates brightness control message for Module 6 + /// Per official docs Report ID: 0x05, Command: 0x55 + /// + public override byte[] GetBrightnessMessage(byte percent) + { + if (percent > 100) + { + throw new ArgumentOutOfRangeException(nameof(percent)); + } + + // Feature Report format for Set Backlight Brightness + var buffer = new byte[32]; // Feature reports are 32 bytes, zero-padded + buffer[0] = 0x05; // Report ID + buffer[1] = 0x55; // Command + buffer[2] = 0xAA; + buffer[3] = 0xD1; + buffer[4] = 0x01; + buffer[5] = percent; // Brightness value (0-100) + + return buffer; + } + + /// + /// Creates show logo message for Module 6 + /// Per official docs Report ID: 0x0B, Command: 0x63, Payload: 0x00 + /// + public override byte[] GetLogoMessage() + { + var buffer = new byte[32]; // Feature reports are 32 bytes, zero-padded + buffer[0] = 0x0B; // Report ID + buffer[1] = 0x63; // Command + buffer[2] = 0x00; // Show Boot Logo + + return buffer; + } + } +} diff --git a/src/StreamDeckSharp/StreamDeckSharp.csproj b/src/StreamDeckSharp/StreamDeckSharp.csproj index b2a6bd5..bb3439c 100644 --- a/src/StreamDeckSharp/StreamDeckSharp.csproj +++ b/src/StreamDeckSharp/StreamDeckSharp.csproj @@ -1,4 +1,4 @@ - + netstandard2.0;net462;net8.0