diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..dd005ceb --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,61 @@ +name: RGB.NET-CI + +on: + push: + branches: [ Development ] + paths: + - '**.cs' + - '**.csproj' + - '**.yml' + +jobs: + build: + + runs-on: windows-2022 + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 7.0.x + - name: Git Semantic Version + id: versioning + uses: PaulHatch/semantic-version@v4.0.3 + with: + short_tags: false + format: "${major}.${minor}.${patch}-prerelease.${increment}" + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore --configuration Release /p:Version=${{ steps.versioning.outputs.version }} + - name: Test + run: dotnet test --no-build --verbosity normal --configuration Release + - name: Upload a Build Artifact NET5 + uses: actions/upload-artifact@v2.2.4 + with: + name: RGB.NET-NET5 + path: bin/net5.0/RGB.NET.*.dll + if-no-files-found: error + - name: Upload a Build Artifact NET6 + uses: actions/upload-artifact@v2.2.4 + with: + name: RGB.NET-NET6 + path: bin/net6.0/RGB.NET.*.dll + if-no-files-found: error + - name: Upload a Build Artifact NET7 + uses: actions/upload-artifact@v2.2.4 + with: + name: RGB.NET-NET7 + path: bin/net7.0/RGB.NET.*.dll + if-no-files-found: error + - name: Upload Nuget Build Artifact + uses: actions/upload-artifact@v2.2.4 + with: + name: RGB.NET-Nugets + path: bin/*nupkg + if-no-files-found: error + - name: Nuget Push + run: dotnet nuget push **\*.nupkg --skip-duplicate --api-key ${{ secrets.NUGET_TOKEN }} --source https://api.nuget.org/v3/index.json diff --git a/.github/workflows/pr_verify.yml b/.github/workflows/pr_verify.yml new file mode 100644 index 00000000..b47d33ee --- /dev/null +++ b/.github/workflows/pr_verify.yml @@ -0,0 +1,24 @@ +name: PR-Verify + +on: + pull_request: + branches: [ master, Development ] + +jobs: + build: + + runs-on: windows-2022 + + steps: + - uses: actions/checkout@v2 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 7.0.x + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore --configuration Release /p:Version=0.0.0 + - name: Test + run: dotnet test --no-build --verbosity normal --configuration Release + diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..f5e9cce6 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,66 @@ +name: RGB.NET-Release + +on: + push: + branches: [ master ] + paths: + - '**.cs' + - '**.csproj' + - '**.yml' + +jobs: + build: + runs-on: windows-2022 + + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 7.0.x + - name: Git Semantic Version + id: versioning + uses: PaulHatch/semantic-version@v4.0.3 + with: + short_tags: false + format: "${major}.${minor}.${patch}" + - name: Restore dependencies + run: dotnet restore + - name: Build + run: dotnet build --no-restore --configuration Release /p:Version=${{ steps.versioning.outputs.version }} + - name: Test + run: dotnet test --no-build --verbosity normal --configuration Release + - name: Upload a Build Artifact NET5 + uses: actions/upload-artifact@v2.2.4 + with: + name: RGB.NET-NET5 + path: bin/net5.0/RGB.NET.*.dll + if-no-files-found: error + - name: Upload a Build Artifact NET6 + uses: actions/upload-artifact@v2.2.4 + with: + name: RGB.NET-NET6 + path: bin/net6.0/RGB.NET.*.dll + if-no-files-found: error + - name: Upload a Build Artifact NET7 + uses: actions/upload-artifact@v2.2.4 + with: + name: RGB.NET-NET7 + path: bin/net7.0/RGB.NET.*.dll + if-no-files-found: error + - name: Upload Nuget Build Artifact + uses: actions/upload-artifact@v2.2.4 + with: + name: RGB.NET-Nugets + path: bin/*nupkg + if-no-files-found: error + - name: Release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ steps.versioning.outputs.version_tag }} + generate_release_notes: true + files: bin/net7.0/RGB.NET.*.dll + - name: Nuget Push + run: dotnet nuget push **\*.nupkg --skip-duplicate --api-key ${{ secrets.NUGET_TOKEN }} --source https://api.nuget.org/v3/index.json diff --git a/Documentation/DeviceLayout.xsd b/Documentation/DeviceLayout.xsd index 91ced394..8624cf4a 100644 --- a/Documentation/DeviceLayout.xsd +++ b/Documentation/DeviceLayout.xsd @@ -7,17 +7,22 @@ - - - - + + + + + + + + + @@ -28,39 +33,21 @@ - - - - - - - - - - - - - - + - - - - - - - + + - + - + \ No newline at end of file diff --git a/README.md b/README.md index 7d7098dd..7261a9a1 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,87 @@ # RGB.NET +[![GitHub release (latest by date)](https://img.shields.io/github/v/release/DarthAffe/RGB.NET?style=for-the-badge)](https://github.com/DarthAffe/RGB.NET/releases) +[![Nuget](https://img.shields.io/nuget/v/RGB.NET.Core?style=for-the-badge)](https://www.nuget.org/packages?q=rgb.net) +[![GitHub](https://img.shields.io/github/license/DarthAffe/RGB.NET?style=for-the-badge)](https://github.com/DarthAffe/RGB.NET/blob/master/LICENSE) +[![GitHub Repo stars](https://img.shields.io/github/stars/DarthAffe/RGB.NET?style=for-the-badge)](https://github.com/DarthAffe/RGB.NET/stargazers) +[![Discord](https://img.shields.io/discord/366163308941934592?logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/9kytURv) -This project aims to unify the use of various RGB-devices. -**It is currently under heavy development and will have breaking changes in the future!** Right now a lot of devices aren't working as expected and there are bugs/unfinished features. Please think about that when you consider using the library in this early stage. - -If you want to help with layouting/testing devices or if you need support using the library feel free to join the [RGB.NET discord-channel](https://discord.gg/9kytURv). +> **IMPORTANT NOTE** +This is a library to integrate RGB-devices into your own application. It does not contain any executables! +If you're looking for a full blown software solution to manage your RGB-devices, take a look at [Artemis](https://artemis-rgb.com/). +## Getting Started +### Setup +1. Add the [RGB.NET.Core](https://www.nuget.org/packages/RGB.NET.Core) and [Devices](https://www.nuget.org/packages?q=rgb.net.Devices)-Nugets for all devices you want to use. +2. For some of the vendors SDK-libraries are needed. Check the contained Readmes for more information in that case. +3. Create a new `RGBSurface`. +```csharp +RGBSurface surface = new RGBSurface(); +``` -## Adding prerelease packages using NuGet ## -This is the easiest and therefore preferred way to include RGB.NET in your project. +4. Initialize the providers for all devices you want to use and add the devices to the surface. For example: +```csharp +CorsairDeviceProvider.Instance.Initialize(throwExceptions: true); +surface.Attach(CorsairDeviceProvider.Instance.Devices); +``` +The `Initialize`-method allows to load only devices of specific types by setting a filter and for debugging purposes allows to enable exception throwing. (By default they are catched and provided through the `Exception`-event.) +You can also use the `Load`-Extension on the surface. +```csharp +surface.Load(CorsairDeviceProvider.Instance); +``` +> While most device-providers are implemented in a way that supports fast loading like this some may have a different loading procedures. (For example the `WS281XDeviceProvider` requires device-definitions before loading.) -Since there aren't any release-packages right now you'll have to use the CI-feed from [http://nuget.arge.be](http://nuget.arge.be). -You can include it either by adding ```http://nuget.arge.be/v3/index.json``` to your Visual Studio package sources or by adding this [NuGet.Config](https://github.com/DarthAffe/RGB.NET/tree/master/Documentation/NuGet.Config) to your project (at the same level as your solution). +5. Add an update-trigger. In most cases the TimerUpdateTrigger is preferable, but you can also implement your own to fit your needs. +```csharp +surface.RegisterUpdateTrigger(new TimerUpdateTrigger()); +``` +> If you want to trigger updates manually the `ManualUpdateTrigger` should be used. -### .NET 4.5 Support ### -At the end of the year with the release of .NET 5 the support for old .NET-Framwork versions will be droppped! -It's not recommended to use RGB.NET in projects targeting .NET 4.x that aren't planned to be moved to Core/.NET 5 in the future. +6. *This step is optional but recommended.* For rendering the location of each LED on the surface can be important. Since not all SDKs provide useful layout-information you might want to add Layouts to your devices. (TODO: add wiki article for this) +Same goes for the location of the device on the surface. If you don't care about the exact location of the devices you can use: +```csharp +surface.AlignDevices(); +``` +The basic setup is now complete and you can start setting up your rendering. -### Device-Layouts -To be able to have devices with correct LED-locations and sizes they need to be layouted. Pre-created layouts can be found at https://github.com/DarthAffe/RGB.NET-Resources. +### Basic Rendering +As an example we'll add a moving rainbow over all devices on the surface. +1. Create a led-group containing all leds on the surface (all devices) +```csharp +ILedGroup allLeds = new ListLedGroup(surface, surface.Leds); +``` -If you plan to create layouts for your own devices check out https://github.com/DarthAffe/RGB.NET/wiki/Creating-Layouts first. There's also a layout-editor which strongly simplifies most of the work: https://github.com/SpoinkyNL/RGB.NET-Layout-Editor +2. Create a rainbow-gradient. +```csharp +RainbowGradient rainbow = new RainbowGradient(); +``` -### Example usage of RGB.NET -[![Example video](https://img.youtube.com/vi/JLRa0Wv4qso/0.jpg)](http://www.youtube.com/watch?v=JLRa0Wv4qso) +3. Add a decorator to the gradient to make it move. (Decorators are +```csharp +rainbow.AddDecorator(new MoveGradientDecorator(surface)); +``` -#### Example Projects -[https://github.com/DarthAffe/KeyboardAudioVisualizer](https://github.com/DarthAffe/KeyboardAudioVisualizer) -[https://github.com/DarthAffe/RGBSyncPlus](https://github.com/DarthAffe/RGBSyncPlus) +4. Create a texture (the size - in this example 10, 10 - is not important here since the gradient shoukd be stretched anyway) +```csharp +ITexture texture = new ConicalGradientTexture(new Size(10, 10), rainbow); +``` + +5. Add a brush rendering the texture to the led-group +```csharp +allLeds.Brush = new TextureBrush(texture); +``` + +### Full example +```csharp +RGBSurface surface = new RGBSurface(); +surface.Load(CorsairDeviceProvider.Instance); +surface.AlignDevices(); + +surface.RegisterUpdateTrigger(new TimerUpdateTrigger()); + +ILedGroup allLeds = new ListLedGroup(surface, surface.Leds); +RainbowGradient rainbow = new RainbowGradient(); +rainbow.AddDecorator(new MoveGradientDecorator(surface)); +ITexture texture = new ConicalGradientTexture(new Size(10, 10), rainbow); +allLeds.Brush = new TextureBrush(texture); +``` \ No newline at end of file diff --git a/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs b/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs deleted file mode 100644 index 9c251098..00000000 --- a/RGB.NET.Brushes/Brushes/ConicalGradientBrush.cs +++ /dev/null @@ -1,119 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable MemberCanBeProtected.Global -// ReSharper disable ReturnTypeCanBeEnumerable.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -// ReSharper disable UnusedMember.Global - -using System; -using RGB.NET.Brushes.Gradients; -using RGB.NET.Core; - -namespace RGB.NET.Brushes -{ - /// - /// - /// - /// Represents a brush drawing a conical gradient. - /// - public class ConicalGradientBrush : AbstractBrush, IGradientBrush - { - #region Properties & Fields - - private float _origin = (float)Math.Atan2(-1, 0); - /// - /// Gets or sets the origin (radian-angle) this is drawn to. (default: -π/2) - /// - public float Origin - { - get => _origin; - set => SetProperty(ref _origin, value); - } - - private Point _center = new Point(0.5, 0.5); - /// - /// Gets or sets the center (as percentage in the range [0..1]) of the drawn by this . (default: 0.5, 0.5) - /// - public Point Center - { - get => _center; - set => SetProperty(ref _center, value); - } - - private IGradient _gradient; - /// - /// - /// Gets or sets the gradient drawn by the brush. If null it will default to full transparent. - /// - public IGradient Gradient - { - get => _gradient; - set => SetProperty(ref _gradient, value); - } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - public ConicalGradientBrush() - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The drawn by this . - public ConicalGradientBrush(IGradient gradient) - { - this.Gradient = gradient; - } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The center (as percentage in the range [0..1]). - /// The drawn by this . - public ConicalGradientBrush(Point center, IGradient gradient) - { - this.Center = center; - this.Gradient = gradient; - } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The center (as percentage in the range [0..1]). - /// The origin (radian-angle) the is drawn to. - /// The drawn by this . - public ConicalGradientBrush(Point center, float origin, IGradient gradient) - { - this.Center = center; - this.Origin = origin; - this.Gradient = gradient; - } - - #endregion - - #region Methods - - /// - protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget) - { - double centerX = rectangle.Size.Width * Center.X; - double centerY = rectangle.Size.Height * Center.Y; - - double angle = Math.Atan2(renderTarget.Point.Y - centerY, renderTarget.Point.X - centerX) - Origin; - if (angle < 0) angle += Math.PI * 2; - double offset = angle / (Math.PI * 2); - - return Gradient.GetColor(offset); - } - - #endregion - } -} diff --git a/RGB.NET.Brushes/Brushes/IGradientBrush.cs b/RGB.NET.Brushes/Brushes/IGradientBrush.cs deleted file mode 100644 index 5677154c..00000000 --- a/RGB.NET.Brushes/Brushes/IGradientBrush.cs +++ /dev/null @@ -1,17 +0,0 @@ -using RGB.NET.Brushes.Gradients; -using RGB.NET.Core; - -namespace RGB.NET.Brushes -{ - /// - /// - /// Represents a basic gradient-brush. - /// - public interface IGradientBrush : IBrush - { - /// - /// Gets the used by this . - /// - IGradient Gradient { get; } - } -} diff --git a/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs b/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs deleted file mode 100644 index 0880e4c4..00000000 --- a/RGB.NET.Brushes/Brushes/LinearGradientBrush.cs +++ /dev/null @@ -1,109 +0,0 @@ -// ReSharper disable CollectionNeverUpdated.Global -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable MemberCanBeProtected.Global -// ReSharper disable ReturnTypeCanBeEnumerable.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -// ReSharper disable UnusedMember.Global - -using RGB.NET.Brushes.Gradients; -using RGB.NET.Brushes.Helper; -using RGB.NET.Core; - -namespace RGB.NET.Brushes -{ - /// - /// - /// - /// Represents a brush drawing a linear gradient. - /// - public class LinearGradientBrush : AbstractBrush, IGradientBrush - { - #region Properties & Fields - - private Point _startPoint = new Point(0, 0.5); - /// - /// Gets or sets the start (as percentage in the range [0..1]) of the drawn by this . (default: 0.0, 0.5) - /// - public Point StartPoint - { - get => _startPoint; - set => SetProperty(ref _startPoint, value); - } - - private Point _endPoint = new Point(1, 0.5); - /// - /// Gets or sets the end (as percentage in the range [0..1]) of the drawn by this . (default: 1.0, 0.5) - /// - public Point EndPoint - { - get => _endPoint; - set => SetProperty(ref _endPoint, value); - } - - private IGradient _gradient; - /// - public IGradient Gradient - { - get => _gradient; - set => SetProperty(ref _gradient, value); - } - - #endregion - - #region Constructor - - /// - /// - /// Initializes a new instance of the class. - /// - public LinearGradientBrush() - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The drawn by this . - public LinearGradientBrush(IGradient gradient) - { - this.Gradient = gradient; - } - /// - /// - /// Initializes a new instance of the class. - /// - /// The start (as percentage in the range [0..1]). - /// The end (as percentage in the range [0..1]). - /// The drawn by this . - public LinearGradientBrush(Point startPoint, Point endPoint, IGradient gradient) - { - this.StartPoint = startPoint; - this.EndPoint = endPoint; - this.Gradient = gradient; - } - - #endregion - - #region Methods - - /// - /// - /// Gets the color at an specific point assuming the brush is drawn into the given rectangle. - /// - /// The rectangle in which the brush should be drawn. - /// The target (key/point) from which the color should be taken. - /// The color at the specified point. - protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget) - { - if (Gradient == null) return Color.Transparent; - - Point startPoint = new Point(StartPoint.X * rectangle.Size.Width, StartPoint.Y * rectangle.Size.Height); - Point endPoint = new Point(EndPoint.X * rectangle.Size.Width, EndPoint.Y * rectangle.Size.Height); - - double offset = GradientHelper.CalculateLinearGradientOffset(startPoint, endPoint, renderTarget.Point); - return Gradient.GetColor(offset); - } - - #endregion - } -} diff --git a/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs b/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs deleted file mode 100644 index 58df28e7..00000000 --- a/RGB.NET.Brushes/Brushes/RadialGradientBrush.cs +++ /dev/null @@ -1,97 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -// ReSharper disable UnusedMember.Global - -using System; -using RGB.NET.Brushes.Gradients; -using RGB.NET.Brushes.Helper; -using RGB.NET.Core; - -namespace RGB.NET.Brushes -{ - /// - /// - /// - /// Represents a brush drawing a radial gradient around a center point. - /// - public class RadialGradientBrush : AbstractBrush, IGradientBrush - { - #region Properties & Fields - - private Point _center = new Point(0.5, 0.5); - /// - /// Gets or sets the center (as percentage in the range [0..1]) around which the should be drawn. (default: 0.5, 0.5) - /// - public Point Center - { - get => _center; - set => SetProperty(ref _center, value); - } - - private IGradient _gradient; - /// - public IGradient Gradient - { - get => _gradient; - set => SetProperty(ref _gradient, value); - } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - public RadialGradientBrush() - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The gradient drawn by the brush. - public RadialGradientBrush(IGradient gradient) - { - this.Gradient = gradient; - } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The center point (as percentage in the range [0..1]). - /// The gradient drawn by the brush. - public RadialGradientBrush(Point center, IGradient gradient) - { - this.Center = center; - this.Gradient = gradient; - } - - #endregion - - #region Methods - - /// - protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget) - { - if (Gradient == null) return Color.Transparent; - - Point centerPoint = new Point(rectangle.Location.X + (rectangle.Size.Width * Center.X), rectangle.Location.Y + (rectangle.Size.Height * Center.Y)); - - // Calculate the distance to the farthest point from the center as reference (this has to be a corner) - // ReSharper disable once RedundantCast - never trust this ... - double refDistance = Math.Max(Math.Max(Math.Max(GradientHelper.CalculateDistance(rectangle.Location, centerPoint), - GradientHelper.CalculateDistance(new Point(rectangle.Location.X + rectangle.Size.Width, rectangle.Location.Y), centerPoint)), - GradientHelper.CalculateDistance(new Point(rectangle.Location.X, rectangle.Location.Y + rectangle.Size.Height), centerPoint)), - GradientHelper.CalculateDistance(new Point(rectangle.Location.X + rectangle.Size.Width, rectangle.Location.Y + rectangle.Size.Height), centerPoint)); - - double distance = GradientHelper.CalculateDistance(renderTarget.Point, centerPoint); - double offset = distance / refDistance; - return Gradient.GetColor(offset); - } - - #endregion - } -} diff --git a/RGB.NET.Brushes/Brushes/SolidColorBrush.cs b/RGB.NET.Brushes/Brushes/SolidColorBrush.cs deleted file mode 100644 index 3620ea5e..00000000 --- a/RGB.NET.Brushes/Brushes/SolidColorBrush.cs +++ /dev/null @@ -1,65 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global - -using RGB.NET.Core; - -namespace RGB.NET.Brushes -{ - /// - /// - /// Represents a brush drawing only a single color. - /// - public class SolidColorBrush : AbstractBrush - { - #region Properties & Fields - - private Color _color; - /// - /// Gets or sets the drawn by this . - /// - public Color Color - { - get => _color; - set => SetProperty(ref _color, value); - } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The drawn by this . - public SolidColorBrush(Color color) - { - this.Color = color; - } - - #endregion - - #region Methods - - /// - protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget) => Color; - - #endregion - - #region Operators - - /// - /// Converts a to a . - /// - /// The to convert. - public static explicit operator SolidColorBrush(Color color) => new SolidColorBrush(color); - - /// - /// Converts a to a . - /// - /// The to convert. - public static implicit operator Color(SolidColorBrush brush) => brush.Color; - - #endregion - } -} \ No newline at end of file diff --git a/RGB.NET.Brushes/Decorators/IGradientDecorator.cs b/RGB.NET.Brushes/Decorators/IGradientDecorator.cs deleted file mode 100644 index 86c07de8..00000000 --- a/RGB.NET.Brushes/Decorators/IGradientDecorator.cs +++ /dev/null @@ -1,11 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Brushes -{ - /// - /// - /// Represents a basic decorator decorating a . - /// - public interface IGradientDecorator : IDecorator - { } -} diff --git a/RGB.NET.Brushes/Gradients/AbstractGradient.cs b/RGB.NET.Brushes/Gradients/AbstractGradient.cs deleted file mode 100644 index c32a0dab..00000000 --- a/RGB.NET.Brushes/Gradients/AbstractGradient.cs +++ /dev/null @@ -1,150 +0,0 @@ -// ReSharper disable MemberCanBeProtected.Global -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global - -using System; -using System.Collections.ObjectModel; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Linq; -using RGB.NET.Core; - -namespace RGB.NET.Brushes.Gradients -{ - /// - /// - /// - /// Represents a basic gradient. - /// - public abstract class AbstractGradient : AbstractDecoratable, IGradient - { - #region Properties & Fields - - /// - /// Gets a list of the stops used by this . - /// - public ObservableCollection GradientStops { get; } = new ObservableCollection(); - - private bool _wrapGradient; - /// - /// Gets or sets if the Gradient wraps around if there isn't a second stop to take. - /// Example: There is a stop at offset 0.0, 0.5 and 0.75. - /// Without wrapping offset 1.0 will be calculated the same as 0.75; with wrapping it would be the same as 0.0. - /// - public bool WrapGradient - { - get => _wrapGradient; - set => SetProperty(ref _wrapGradient, value); - } - - #endregion - - #region Events - - /// - public event EventHandler GradientChanged; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - protected AbstractGradient() - { - GradientStops.CollectionChanged += GradientCollectionChanged; - PropertyChanged += (sender, args) => OnGradientChanged(); - } - - /// - /// Initializes a new instance of the class. - /// - /// The stops with which the gradient should be initialized. - protected AbstractGradient(params GradientStop[] gradientStops) - { - GradientStops.CollectionChanged += GradientCollectionChanged; - PropertyChanged += (sender, args) => OnGradientChanged(); - - foreach (GradientStop gradientStop in gradientStops) - GradientStops.Add(gradientStop); - } - - /// - /// Initializes a new instance of the class. - /// - /// Specifies whether the gradient should wrapp or not (see for an example of what this means). - /// The stops with which the gradient should be initialized. - protected AbstractGradient(bool wrapGradient, params GradientStop[] gradientStops) - { - this.WrapGradient = wrapGradient; - - GradientStops.CollectionChanged += GradientCollectionChanged; - PropertyChanged += (sender, args) => OnGradientChanged(); - - foreach (GradientStop gradientStop in gradientStops) - GradientStops.Add(gradientStop); - } - - #endregion - - #region Methods - - /// - /// Clips the offset and ensures, that it is inside the bounds of the stop list. - /// - /// - /// - protected double ClipOffset(double offset) - { - double max = GradientStops.Max(n => n.Offset); - if (offset > max) - return max; - - double min = GradientStops.Min(n => n.Offset); - return offset < min ? min : offset; - } - - /// - public abstract Color GetColor(double offset); - - /// - public virtual void Move(double offset) - { - offset /= 360.0; - - foreach (GradientStop gradientStop in GradientStops) - gradientStop.Offset += offset; - - while (GradientStops.All(x => x.Offset > 1)) - foreach (GradientStop gradientStop in GradientStops) - gradientStop.Offset -= 1; - - while (GradientStops.All(x => x.Offset < 0)) - foreach (GradientStop gradientStop in GradientStops) - gradientStop.Offset += 1; - } - - /// - /// Should be called to indicate that the gradient was changed. - /// - protected void OnGradientChanged() => GradientChanged?.Invoke(this, null); - - private void GradientCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - if (e.OldItems != null) - foreach (GradientStop gradientStop in e.OldItems) - gradientStop.PropertyChanged -= GradientStopChanged; - - if (e.NewItems != null) - foreach (GradientStop gradientStop in e.NewItems) - gradientStop.PropertyChanged += GradientStopChanged; - - OnGradientChanged(); - } - - private void GradientStopChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) => OnGradientChanged(); - - #endregion - } -} diff --git a/RGB.NET.Brushes/Gradients/GradientStop.cs b/RGB.NET.Brushes/Gradients/GradientStop.cs deleted file mode 100644 index 3cb4597a..00000000 --- a/RGB.NET.Brushes/Gradients/GradientStop.cs +++ /dev/null @@ -1,52 +0,0 @@ -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -// ReSharper disable MemberCanBePrivate.Global - -using RGB.NET.Core; - -namespace RGB.NET.Brushes.Gradients -{ - /// - /// Represents a stop on a gradient. - /// - public class GradientStop : AbstractBindable - { - #region Properties & Fields - - private double _offset; - /// - /// Gets or sets the percentage offset to place this . This should be inside the range of [0..1] but it's not necessary. - /// - public double Offset - { - get => _offset; - set => SetProperty(ref _offset, value); - } - - private Color _color; - /// - /// Gets or sets the of this . - /// - public Color Color - { - get => _color; - set => SetProperty(ref _color, value); - } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The percentage offset to place this . - /// The of the . - public GradientStop(double offset, Color color) - { - this.Offset = offset; - this.Color = color; - } - - #endregion - } -} diff --git a/RGB.NET.Brushes/Gradients/IGradient.cs b/RGB.NET.Brushes/Gradients/IGradient.cs deleted file mode 100644 index 590ba4cd..00000000 --- a/RGB.NET.Brushes/Gradients/IGradient.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Brushes.Gradients -{ - /// - /// - /// Represents a basic gradient. - /// - public interface IGradient : IDecoratable - { - /// - /// Occurs if the is changed. - /// - event EventHandler GradientChanged; - - /// - /// Gets the of the on the specified offset. - /// - /// The percentage offset to take the from. - /// The at the specific offset. - Color GetColor(double offset); - - /// - /// Moves the by the provided offset. - /// - /// The offset the should be moved. - void Move(double offset); - } -} diff --git a/RGB.NET.Brushes/Gradients/LinearGradient.cs b/RGB.NET.Brushes/Gradients/LinearGradient.cs deleted file mode 100644 index 535fe5de..00000000 --- a/RGB.NET.Brushes/Gradients/LinearGradient.cs +++ /dev/null @@ -1,152 +0,0 @@ -// ReSharper disable UnusedMember.Global - -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using RGB.NET.Core; - -namespace RGB.NET.Brushes.Gradients -{ - /// - /// - /// Represents a linear interpolated gradient with n stops. - /// - public class LinearGradient : AbstractGradient - { - #region Properties & Fields - - private bool _isOrderedGradientListDirty = true; - private LinkedList _orderedGradientStops; - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - public LinearGradient() - { - Initialize(); - } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The stops with which the gradient should be initialized. - public LinearGradient(params GradientStop[] gradientStops) - : base(gradientStops) - { - Initialize(); - } - - /// - /// - /// Initializes a new instance of the class. - /// - /// Specifies whether the gradient should wrapp or not (see for an example of what this means). - /// The stops with which the gradient should be initialized. - public LinearGradient(bool wrapGradient, params GradientStop[] gradientStops) - : base(wrapGradient, gradientStops) - { - Initialize(); - } - - #endregion - - #region Methods - - private void Initialize() - { - void OnGradientStopOnPropertyChanged(object sender, PropertyChangedEventArgs args) => _isOrderedGradientListDirty = true; - - foreach (GradientStop gradientStop in GradientStops) - gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged; - - GradientStops.CollectionChanged += (sender, args) => - { - if (args.OldItems != null) - foreach (GradientStop gradientStop in args.OldItems) - gradientStop.PropertyChanged -= OnGradientStopOnPropertyChanged; - - if (args.NewItems != null) - foreach (GradientStop gradientStop in args.NewItems) - gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged; - }; - } - - /// - /// - /// Gets the linear interpolated at the given offset. - /// - /// The percentage offset to take the color from. - /// The at the specific offset. - public override Color GetColor(double offset) - { - if (GradientStops.Count == 0) return Color.Transparent; - if (GradientStops.Count == 1) return GradientStops[0].Color; - - if (_isOrderedGradientListDirty) - _orderedGradientStops = new LinkedList(GradientStops.OrderBy(x => x.Offset)); - - (GradientStop gsBefore, GradientStop gsAfter) = GetEnclosingGradientStops(offset, _orderedGradientStops, WrapGradient); - - double blendFactor = 0; - if (!gsBefore.Offset.Equals(gsAfter.Offset)) - blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset)); - - double colA = ((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A; - double colR = ((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R; - double colG = ((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G; - double colB = ((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B; - - return new Color(colA, colR, colG, colB); - } - - /// - /// Get the two s encapsulating the given offset. - /// - /// The reference offset. - /// The ordered list of to choose from. - /// Bool indicating if the gradient should be wrapped or not. - /// - protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(double offset, LinkedList orderedStops, bool wrap) - { - LinkedList gradientStops = new LinkedList(orderedStops); - - if (wrap) - { - GradientStop gsBefore, gsAfter; - - do - { - gsBefore = gradientStops.LastOrDefault(n => n.Offset <= offset); - if (gsBefore == null) - { - GradientStop lastStop = gradientStops.Last.Value; - gradientStops.AddFirst(new GradientStop(lastStop.Offset - 1, lastStop.Color)); - gradientStops.RemoveLast(); - } - - gsAfter = gradientStops.FirstOrDefault(n => n.Offset >= offset); - if (gsAfter == null) - { - GradientStop firstStop = gradientStops.First.Value; - gradientStops.AddLast(new GradientStop(firstStop.Offset + 1, firstStop.Color)); - gradientStops.RemoveFirst(); - } - - } while ((gsBefore == null) || (gsAfter == null)); - - return (gsBefore, gsAfter); - } - - offset = ClipOffset(offset); - return (gradientStops.Last(n => n.Offset <= offset), gradientStops.First(n => n.Offset >= offset)); - } - - #endregion - } -} diff --git a/RGB.NET.Brushes/Gradients/RainbowGradient.cs b/RGB.NET.Brushes/Gradients/RainbowGradient.cs deleted file mode 100644 index 01946d02..00000000 --- a/RGB.NET.Brushes/Gradients/RainbowGradient.cs +++ /dev/null @@ -1,108 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global - -using System; -using RGB.NET.Core; - -namespace RGB.NET.Brushes.Gradients -{ - /// - /// - /// - /// Represents a rainbow gradient which circles through all colors of the HUE-color-space.
- /// See as reference. - ///
- public class RainbowGradient : AbstractDecoratable, IGradient - { - #region Properties & Fields - - private double _startHue; - /// - /// Gets or sets the hue (in degrees) to start from. - /// - public double StartHue - { - get => _startHue; - set => SetProperty(ref _startHue, value); - } - - private double _endHue; - /// - /// Gets or sets the hue (in degrees) to end the with. - /// - public double EndHue - { - get => _endHue; - set => SetProperty(ref _endHue, value); - } - - #endregion - - #region Events - - /// - public event EventHandler GradientChanged; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The hue (in degrees) to start from (default: 0) - /// The hue (in degrees) to end with (default: 360) - public RainbowGradient(double startHue = 0, double endHue = 360) - { - this.StartHue = startHue; - this.EndHue = endHue; - - PropertyChanged += (sender, args) => OnGradientChanged(); - } - - #endregion - - #region Methods - - /// - /// - /// Gets the color on the rainbow at the given offset. - /// - /// The percentage offset to take the color from. - /// The color at the specific offset. - public Color GetColor(double offset) - { - double range = EndHue - StartHue; - double hue = StartHue + (range * offset); - return HSVColor.Create(hue, 1, 1); - } - - /// - public void Move(double offset) - { - // RainbowGradient is calculated inverse - offset *= -1; - - StartHue += offset; - EndHue += offset; - - while ((StartHue > 360) && (EndHue > 360)) - { - StartHue -= 360; - EndHue -= 360; - } - while ((StartHue < -360) && (EndHue < -360)) - { - StartHue += 360; - EndHue += 360; - } - } - - /// - /// Should be called to indicate that the gradient was changed. - /// - protected void OnGradientChanged() => GradientChanged?.Invoke(this, null); - - #endregion - } -} diff --git a/RGB.NET.Brushes/Helper/GradientHelper.cs b/RGB.NET.Brushes/Helper/GradientHelper.cs deleted file mode 100644 index b350af4b..00000000 --- a/RGB.NET.Brushes/Helper/GradientHelper.cs +++ /dev/null @@ -1,81 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global - -using System; -using RGB.NET.Core; - -namespace RGB.NET.Brushes.Helper -{ - /// - /// Offers some extensions and helper-methods for gradient related things. - /// - public static class GradientHelper - { - #region Methods - - // Based on https://web.archive.org/web/20170125201230/https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/ - /// - /// Calculates the offset of an given on an gradient. - /// - /// The start of the gradient. - /// The end of the gradient. - /// The on the gradient to which the offset is calculated. - /// The offset of the on the gradient. - public static double CalculateLinearGradientOffset(Point startPoint, Point endPoint, Point point) - { - Point intersectingPoint; - if (startPoint.Y.Equals(endPoint.Y)) // Horizontal case - intersectingPoint = new Point(point.X, startPoint.Y); - - else if (startPoint.X.Equals(endPoint.X)) // Vertical case - intersectingPoint = new Point(startPoint.X, point.Y); - - else // Diagonal case - { - double slope = (endPoint.Y - startPoint.Y) / (endPoint.X - startPoint.X); - double orthogonalSlope = -1 / slope; - - double startYIntercept = startPoint.Y - (slope * startPoint.X); - double pointYIntercept = point.Y - (orthogonalSlope * point.X); - - double intersectingPointX = (pointYIntercept - startYIntercept) / (slope - orthogonalSlope); - double intersectingPointY = (slope * intersectingPointX) + startYIntercept; - intersectingPoint = new Point(intersectingPointX, intersectingPointY); - } - - // Calculate distances relative to the vector start - double intersectDistance = CalculateDistance(intersectingPoint, startPoint, endPoint); - double gradientLength = CalculateDistance(endPoint, startPoint, endPoint); - - return intersectDistance / gradientLength; - } - - // Based on https://web.archive.org/web/20170125201230/https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/ - /// - /// Returns the signed magnitude of a on a vector. - /// - /// The on the vector of which the magnitude should be calculated. - /// The origin of the vector. - /// The direction of the vector. - /// The signed magnitude of a on a vector. - public static double CalculateDistance(Point point, Point origin, Point direction) - { - double distance = CalculateDistance(point, origin); - - return (((point.Y < origin.Y) && (direction.Y > origin.Y)) || - ((point.Y > origin.Y) && (direction.Y < origin.Y)) || - ((point.Y.Equals(origin.Y)) && (point.X < origin.X) && (direction.X > origin.X)) || - ((point.Y.Equals(origin.Y)) && (point.X > origin.X) && (direction.X < origin.X))) - ? -distance : distance; - } - - /// - /// Calculated the distance between two . - /// - /// The first . - /// The second . - /// The distance between the two . - public static double CalculateDistance(Point point1, Point point2) => Math.Sqrt(((point1.Y - point2.Y) * (point1.Y - point2.Y)) + ((point1.X - point2.X) * (point1.X - point2.X))); - - #endregion - } -} diff --git a/RGB.NET.Core/Brushes/AbstractBrush.cs b/RGB.NET.Core/Brushes/AbstractBrush.cs deleted file mode 100644 index 7521bf2c..00000000 --- a/RGB.NET.Core/Brushes/AbstractBrush.cs +++ /dev/null @@ -1,131 +0,0 @@ -// ReSharper disable VirtualMemberNeverOverriden.Global -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable VirtualMemberNeverOverridden.Global - -using System.Collections.Generic; -using System.Linq; - -namespace RGB.NET.Core -{ - /// - /// - /// - /// Represents a basic brush. - /// - public abstract class AbstractBrush : AbstractDecoratable, IBrush - { - #region Properties & Fields - - /// - public bool IsEnabled { get; set; } = true; - - /// - public BrushCalculationMode BrushCalculationMode { get; set; } = BrushCalculationMode.Relative; - - /// - public double Brightness { get; set; } - - /// - public double Opacity { get; set; } - - /// - public IList ColorCorrections { get; } = new List(); - - /// - public Rectangle RenderedRectangle { get; protected set; } - - /// - public Dictionary RenderedTargets { get; } = new Dictionary(); - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The overall percentage brightness of the brush. (default: 1.0) - /// The overall percentage opacity of the brush. (default: 1.0) - protected AbstractBrush(double brightness = 1, double opacity = 1) - { - this.Brightness = brightness; - this.Opacity = opacity; - } - - #endregion - - #region Methods - - /// - public virtual void PerformRender(Rectangle rectangle, IEnumerable renderTargets) - { - RenderedRectangle = rectangle; - RenderedTargets.Clear(); - - foreach (BrushRenderTarget renderTarget in renderTargets) - { - Color color = GetColorAtPoint(rectangle, renderTarget); - color = ApplyDecorators(rectangle, renderTarget, color); - RenderedTargets[renderTarget] = color; - } - } - - /// - /// Applies all attached and enabled decorators to the brush. - /// - /// The rectangle in which the brush should be drawn. - /// The target (key/point) from which the color should be taken. - /// The to be modified. - protected virtual Color ApplyDecorators(Rectangle rectangle, BrushRenderTarget renderTarget, Color color) - { - lock (Decorators) - foreach (IBrushDecorator decorator in Decorators) - if (decorator.IsEnabled) - color = decorator.ManipulateColor(rectangle, renderTarget, color); - - return color; - } - - /// - public virtual void PerformFinalize() - { - List renderTargets = RenderedTargets.Keys.ToList(); - foreach (BrushRenderTarget renderTarget in renderTargets) - RenderedTargets[renderTarget] = FinalizeColor(RenderedTargets[renderTarget]); - } - - /// - /// Gets the color at an specific point assuming the brush is drawn into the given rectangle. - /// - /// The rectangle in which the brush should be drawn. - /// The target (key/point) from which the color should be taken. - /// The color at the specified point. - protected abstract Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget); - - /// - /// Finalizes the color by appliing the overall brightness and opacity.
- /// This method should always be the last call of a implementation. - ///
- /// The color to finalize. - /// The finalized color. - protected virtual Color FinalizeColor(Color color) - { - if (ColorCorrections.Count > 0) - foreach (IColorCorrection colorCorrection in ColorCorrections) - color = colorCorrection.ApplyTo(color); - - // Since we use HSV to calculate there is no way to make a color 'brighter' than 100% - // Be carefull with the naming: Since we use HSV the correct term is 'value' but outside we call it 'brightness' - // THIS IS NOT A HSB CALCULATION!!! - if (Brightness < 1) - color = color.MultiplyHSV(value: Brightness.Clamp(0, 1)); - - if (Opacity < 1) - color = color.MultiplyA(Opacity.Clamp(0, 1)); - - return color; - } - - #endregion - } -} diff --git a/RGB.NET.Core/Brushes/BrushCalculationMode.cs b/RGB.NET.Core/Brushes/BrushCalculationMode.cs deleted file mode 100644 index 310f5635..00000000 --- a/RGB.NET.Core/Brushes/BrushCalculationMode.cs +++ /dev/null @@ -1,20 +0,0 @@ -// ReSharper disable UnusedMember.Global - -namespace RGB.NET.Core -{ - /// - /// Contains a list of all brush calculation modes. - /// - public enum BrushCalculationMode - { - /// - /// The calculation for will be the rectangle around the the is applied to. - /// - Relative, - - /// - /// The calculation for will always be the rectangle completly containing all affected . - /// - Absolute - } -} diff --git a/RGB.NET.Core/Brushes/BrushRenderTarget.cs b/RGB.NET.Core/Brushes/BrushRenderTarget.cs deleted file mode 100644 index e4934e8b..00000000 --- a/RGB.NET.Core/Brushes/BrushRenderTarget.cs +++ /dev/null @@ -1,47 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedAutoPropertyAccessor.Global - -namespace RGB.NET.Core -{ - /// - /// Represents a single target of a brush render. - /// - public class BrushRenderTarget - { - #region Properties & Fields - - /// - /// Gets the target-. - /// - public Led Led { get; } - - /// - /// Gets the representing the area to render the target-. - /// - public Rectangle Rectangle { get; } - - /// - /// Gets the representing the position to render the target-. - /// - public Point Point { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The target-. - /// The representing the area to render the target-. - public BrushRenderTarget(Led led, Rectangle rectangle) - { - this.Led = led; - this.Rectangle = rectangle; - - this.Point = rectangle.Center; - } - - #endregion - } -} diff --git a/RGB.NET.Core/Brushes/IBrush.cs b/RGB.NET.Core/Brushes/IBrush.cs deleted file mode 100644 index 7d7f2c03..00000000 --- a/RGB.NET.Core/Brushes/IBrush.cs +++ /dev/null @@ -1,61 +0,0 @@ -// ReSharper disable UnusedMemberInSuper.Global -// ReSharper disable UnusedMember.Global -// ReSharper disable ReturnTypeCanBeEnumerable.Global - -using System.Collections.Generic; - -namespace RGB.NET.Core -{ - /// - /// Represents a basic brush. - /// - public interface IBrush : IDecoratable - { - /// - /// Gets or sets if the is enabled and will be drawn on an update. - /// - bool IsEnabled { get; set; } - - /// - /// Gets or sets the calculation mode used for the rectangle/points used for color-selection in brushes. - /// - BrushCalculationMode BrushCalculationMode { get; set; } - - /// - /// Gets or sets the overall percentage brightness of the . - /// - double Brightness { get; set; } - - /// - /// Gets or sets the overall percentage opacity of the . - /// - double Opacity { get; set; } - - /// - /// Gets a list of used to correct the colors of the . - /// - IList ColorCorrections { get; } - - /// - /// Gets the used in the last render pass. - /// - Rectangle RenderedRectangle { get; } - - /// - /// Gets a dictionary containing all for calculated in the last render pass. - /// - Dictionary RenderedTargets { get; } - - /// - /// Performs the render pass of the and calculates the raw for all requested . - /// - /// The in which the brush should be drawn. - /// The (keys/points) of which the color should be calculated. - void PerformRender(Rectangle rectangle, IEnumerable renderTargets); - - /// - /// Performs the finalize pass of the and calculates the final for all previously calculated . - /// - void PerformFinalize(); - } -} \ No newline at end of file diff --git a/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs index e666f6f7..69423253 100644 --- a/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs +++ b/RGB.NET.Core/Color/Behaviors/DefaultColorBehavior.cs @@ -1,80 +1,62 @@ -namespace RGB.NET.Core -{ - public class DefaultColorBehavior : IColorBehavior - { - #region Properties & Fields - - private static DefaultColorBehavior _instance = new DefaultColorBehavior(); - /// - /// Gets the singleton instance of . - /// - public static DefaultColorBehavior Instance { get; } = _instance; - - #endregion - - #region Constructors - - private DefaultColorBehavior() - { } - - #endregion - - #region Methods +using System; - /// - /// Converts the individual byte values of this to a human-readable string. - /// - /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]". - public virtual string ToString(Color color) => $"[A: {color.GetA()}, R: {color.GetR()}, G: {color.GetG()}, B: {color.GetB()}]"; +namespace RGB.NET.Core; - /// - /// Tests whether the specified object is a and is equivalent to this . - /// - /// The object to test. - /// true if is a equivalent to this ; otherwise, false. - public virtual bool Equals(Color color, object obj) - { - if (!(obj is Color)) return false; - - (double a, double r, double g, double b) = ((Color)obj).GetRGB(); - return color.A.EqualsInTolerance(a) && color.R.EqualsInTolerance(r) && color.G.EqualsInTolerance(g) && color.B.EqualsInTolerance(b); - } - - /// - /// Returns a hash code for this . - /// - /// An integer value that specifies the hash code for this . - public virtual int GetHashCode(Color color) - { - unchecked - { - int hashCode = color.A.GetHashCode(); - hashCode = (hashCode * 397) ^ color.R.GetHashCode(); - hashCode = (hashCode * 397) ^ color.G.GetHashCode(); - hashCode = (hashCode * 397) ^ color.B.GetHashCode(); - return hashCode; - } - } - - /// - /// Blends a over this color. - /// - /// The to blend. - public virtual Color Blend(Color baseColor, Color blendColor) - { - if (blendColor.A.EqualsInTolerance(0)) return baseColor; +/// +/// +/// Represents the default-behavior for the work with colors. +/// +public class DefaultColorBehavior : IColorBehavior +{ + #region Methods + + /// + /// Converts the individual byte values of this to a human-readable string. + /// + /// A string that contains the individual byte values of this . For example "[A: 255, R: 255, G: 0, B: 0]". + public virtual string ToString(in Color color) => $"[A: {color.GetA()}, R: {color.GetR()}, G: {color.GetG()}, B: {color.GetB()}]"; + + /// + /// Tests whether the specified object is a and is equivalent to this . + /// + /// The color to test. + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + public virtual bool Equals(in Color color, object? obj) + { + if (obj is not Color color2) return false; + + return color.A.EqualsInTolerance(color2.A) + && color.R.EqualsInTolerance(color2.R) + && color.G.EqualsInTolerance(color2.G) + && color.B.EqualsInTolerance(color2.B); + } - if (blendColor.A.EqualsInTolerance(1)) - return blendColor; + /// + /// Returns a hash code for this . + /// + /// An integer value that specifies the hash code for this . + public virtual int GetHashCode(in Color color) => HashCode.Combine(color.A, color.R, color.G, color.B); + + /// + /// Blends a over this color. + /// + /// The to to blend over. + /// The to blend. + public virtual Color Blend(in Color baseColor, in Color blendColor) + { + if (blendColor.A.EqualsInTolerance(0)) return baseColor; - double resultA = (1.0 - ((1.0 - blendColor.A) * (1.0 - baseColor.A))); - double resultR = (((blendColor.R * blendColor.A) / resultA) + ((baseColor.R * baseColor.A * (1.0 - blendColor.A)) / resultA)); - double resultG = (((blendColor.G * blendColor.A) / resultA) + ((baseColor.G * baseColor.A * (1.0 - blendColor.A)) / resultA)); - double resultB = (((blendColor.B * blendColor.A) / resultA) + ((baseColor.B * baseColor.A * (1.0 - blendColor.A)) / resultA)); + if (blendColor.A.EqualsInTolerance(1)) + return blendColor; - return new Color(resultA, resultR, resultG, resultB); - } + float resultA = (1.0f - ((1.0f - blendColor.A) * (1.0f - baseColor.A))); + float resultR = (((blendColor.R * blendColor.A) / resultA) + ((baseColor.R * baseColor.A * (1.0f - blendColor.A)) / resultA)); + float resultG = (((blendColor.G * blendColor.A) / resultA) + ((baseColor.G * baseColor.A * (1.0f - blendColor.A)) / resultA)); + float resultB = (((blendColor.B * blendColor.A) / resultA) + ((baseColor.B * baseColor.A * (1.0f - blendColor.A)) / resultA)); - #endregion + return new Color(resultA, resultR, resultG, resultB); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs index 630aca5b..29b66147 100644 --- a/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs +++ b/RGB.NET.Core/Color/Behaviors/IColorBehavior.cs @@ -1,13 +1,35 @@ -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a behavior of a color for base operations. +/// +public interface IColorBehavior { - public interface IColorBehavior - { - string ToString(Color color); + /// + /// Converts the specified to a string representation. + /// + /// The color to convert. + /// The string representation of the specified color. + string ToString(in Color color); - bool Equals(Color color, object obj); + /// + /// Tests whether the specified object is a and is equivalent to this . + /// + /// The color to test. + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + bool Equals(in Color color, object? obj); - int GetHashCode(Color color); + /// + /// Returns a hash code for this . + /// + /// An integer value that specifies the hash code for this . + int GetHashCode(in Color color); - Color Blend(Color baseColor, Color blendColor); - } -} + /// + /// Blends a over this color. + /// + /// The to to blend over. + /// The to blend. + Color Blend(in Color baseColor, in Color blendColor); +} \ No newline at end of file diff --git a/RGB.NET.Core/Color/Color.cs b/RGB.NET.Core/Color/Color.cs index 81a3a33a..ae775d37 100644 --- a/RGB.NET.Core/Color/Color.cs +++ b/RGB.NET.Core/Color/Color.cs @@ -5,284 +5,279 @@ using System; using System.Diagnostics; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents an ARGB (alpha, red, green, blue) color. +/// +[DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] +public readonly struct Color { + #region Constants + + private static readonly Color TRANSPARENT = new(0, 0, 0, 0); + /// + /// Gets an transparent color [A: 0, R: 0, G: 0, B: 0] + /// + public static ref readonly Color Transparent => ref TRANSPARENT; + + #endregion + + #region Properties & Fields + + /// + /// Gets or sets the used to perform operations on colors. + /// + public static IColorBehavior Behavior { get; set; } = new DefaultColorBehavior(); + + /// + /// Gets the alpha component value of this as percentage in the range [0..1]. + /// + public readonly float A; + + /// + /// Gets the red component value of this as percentage in the range [0..1]. + /// + public readonly float R; + + /// + /// Gets the green component value of this as percentage in the range [0..1]. + /// + public readonly float G; + + /// + /// Gets the blue component value of this as percentage in the range [0..1]. + /// + public readonly float B; + + #endregion + + #region Constructors + + /// + /// + /// Initializes a new instance of the struct using RGB-Values. + /// Alpha defaults to 255. + /// + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(byte r, byte g, byte b) + : this(byte.MaxValue, r, g, b) + { } + /// /// - /// Represents an ARGB (alpha, red, green, blue) color. + /// Initializes a new instance of the struct using RGB-Values. + /// Alpha defaults to 255. + /// + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(int r, int g, int b) + : this((byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) + { } + + /// + /// Initializes a new instance of the struct using ARGB values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(byte a, byte r, byte g, byte b) + : this(a.GetPercentageFromByteValue(), r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) + { } + + /// + /// Initializes a new instance of the struct using ARGB values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(int a, int r, int g, int b) + : this((byte)a.Clamp(0, byte.MaxValue), (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) + { } + + /// + /// Initializes a new instance of the struct using RGB-percent values. + /// Alpha defaults to 1.0. + /// + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(float r, float g, float b) + : this(1.0f, r, g, b) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(float a, byte r, byte g, byte b) + : this(a, r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(float a, int r, int g, int b) + : this(a, (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(int a, float r, float g, float b) + : this((byte)a.Clamp(0, byte.MaxValue), r, g, b) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. + /// + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(byte a, float r, float g, float b) + : this(a.GetPercentageFromByteValue(), r, g, b) + { } + + /// + /// Initializes a new instance of the struct using ARGB-percent values. /// - [DebuggerDisplay("[A: {A}, R: {R}, G: {G}, B: {B}]")] - public struct Color + /// The alpha component value of this . + /// The red component value of this . + /// The green component value of this . + /// The blue component value of this . + public Color(float a, float r, float g, float b) { - #region Constants - - /// - /// Gets an transparent color [A: 0, R: 0, G: 0, B: 0] - /// - public static Color Transparent => new Color(0, 0, 0, 0); - - #endregion - - #region Properties & Fields - - private static IColorBehavior _behavior = DefaultColorBehavior.Instance; - /// - /// Gets or sets the used to perform operations on colors. - /// - public static IColorBehavior Behavior - { - get => _behavior; - set => _behavior = value ?? DefaultColorBehavior.Instance; - } - - /// - /// Gets the alpha component value of this as percentage in the range [0..1]. - /// - public double A { get; } - - /// - /// Gets the red component value of this as percentage in the range [0..1]. - /// - public double R { get; } - - /// - /// Gets the green component value of this as percentage in the range [0..1]. - /// - public double G { get; } - - /// - /// Gets the blue component value of this as percentage in the range [0..1]. - /// - public double B { get; } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the struct using RGB-Values. - /// Alpha defaults to 255. - /// - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(byte r, byte g, byte b) - : this(byte.MaxValue, r, g, b) - { } - - /// - /// - /// Initializes a new instance of the struct using RGB-Values. - /// Alpha defaults to 255. - /// - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(int r, int g, int b) - : this((byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) - { } - - /// - /// Initializes a new instance of the struct using ARGB values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(byte a, byte r, byte g, byte b) - : this(a.GetPercentageFromByteValue(), r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) - { } - - /// - /// Initializes a new instance of the struct using ARGB values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(int a, int r, int g, int b) - : this((byte)a.Clamp(0, byte.MaxValue), (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) - { } - - /// - /// Initializes a new instance of the struct using RGB-percent values. - /// Alpha defaults to 1.0. - /// - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(double r, double g, double b) - : this(1.0, r, g, b) - { } - - /// - /// Initializes a new instance of the struct using ARGB-percent values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(double a, byte r, byte g, byte b) - : this(a, r.GetPercentageFromByteValue(), g.GetPercentageFromByteValue(), b.GetPercentageFromByteValue()) - { } - - /// - /// Initializes a new instance of the struct using ARGB-percent values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(double a, int r, int g, int b) - : this(a, (byte)r.Clamp(0, byte.MaxValue), (byte)g.Clamp(0, byte.MaxValue), (byte)b.Clamp(0, byte.MaxValue)) - { } - - /// - /// Initializes a new instance of the struct using ARGB-percent values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(int a, double r, double g, double b) - : this((byte)a.Clamp(0, byte.MaxValue), r, g, b) - { } - - /// - /// Initializes a new instance of the struct using ARGB-percent values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(byte a, double r, double g, double b) - : this(a.GetPercentageFromByteValue(), r, g, b) - { } - - /// - /// Initializes a new instance of the struct using ARGB-percent values. - /// - /// The alpha component value of this . - /// The red component value of this . - /// The green component value of this . - /// The blue component value of this . - public Color(double a, double r, double g, double b) - { - A = a.Clamp(0, 1); - R = r.Clamp(0, 1); - G = g.Clamp(0, 1); - B = b.Clamp(0, 1); - } - - /// - /// - /// Initializes a new instance of the struct by cloning a existing . - /// - /// The the values are copied from. - public Color(Color color) - : this(color.A, color.R, color.G, color.B) - { } - - #endregion - - #region Methods - - /// - /// Gets a human-readable string, as defined by the current . - /// - /// A string that contains the individual byte values of this . Default format: "[A: 255, R: 255, G: 0, B: 0]". - public override string ToString() => Behavior.ToString(this); - - /// - /// Tests whether the specified object is a and is equivalent to this , as defined by the current . - /// - /// The object to test. - /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) => Behavior.Equals(this, obj); - - /// - /// Returns a hash code for this , as defined by the current . - /// - /// An integer value that specifies the hash code for this . - public override int GetHashCode() => Behavior.GetHashCode(this); - - /// - /// Blends a over this color, as defined by the current . - /// - /// The to blend. - public Color Blend(Color color) => Behavior.Blend(this, color); - - #endregion - - #region Operators - - /// - /// Blends the provided colors as if would've been called on . - /// - /// The base color. - /// The color to blend. - /// The blended color. - public static Color operator +(Color color1, Color color2) => color1.Blend(color2); - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are equal; otherwise, false. - public static bool operator ==(Color color1, Color color2) => color1.Equals(color2); - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are not equal; otherwise, false. - public static bool operator !=(Color color1, Color color2) => !(color1 == color2); - - /// - /// Converts a of ARGB-components to a . - /// - /// The containing the components. - /// The color. - public static implicit operator Color((byte r, byte g, byte b) components) => new Color(components.r, components.g, components.b); - - /// - /// Converts a of ARGB-components to a . - /// - /// The containing the components. - /// The color. - public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new Color(components.a, components.r, components.g, components.b); - - /// - /// Converts a of ARGB-components to a . - /// - /// The containing the components. - /// The color. - public static implicit operator Color((int r, int g, int b) components) => new Color(components.r, components.g, components.b); - - /// - /// Converts a of ARGB-components to a . - /// - /// The containing the components. - /// The color. - public static implicit operator Color((int a, int r, int g, int b) components) => new Color(components.a, components.r, components.g, components.b); - - /// - /// Converts a of ARGB-components to a . - /// - /// The containing the components. - /// The color. - public static implicit operator Color((double r, double g, double b) components) => new Color(components.r, components.g, components.b); - - /// - /// Converts a of ARGB-components to a . - /// - /// The containing the components. - /// The color. - public static implicit operator Color((double a, double r, double g, double b) components) => new Color(components.a, components.r, components.g, components.b); - - #endregion + A = a.Clamp(0, 1); + R = r.Clamp(0, 1); + G = g.Clamp(0, 1); + B = b.Clamp(0, 1); } -} + + /// + /// + /// Initializes a new instance of the struct by cloning a existing . + /// + /// The the values are copied from. + public Color(in Color color) + : this(color.A, color.R, color.G, color.B) + { } + + #endregion + + #region Methods + + /// + /// Gets a human-readable string, as defined by the current . + /// + /// A string that contains the individual byte values of this . Default format: "[A: 255, R: 255, G: 0, B: 0]". + public override string ToString() => Behavior.ToString(this); + + /// + /// Tests whether the specified object is a and is equivalent to this , as defined by the current . + /// + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + public override bool Equals(object? obj) => Behavior.Equals(this, obj); + + /// + /// Returns a hash code for this , as defined by the current . + /// + /// An integer value that specifies the hash code for this . + // ReSharper disable once NonReadonlyMemberInGetHashCode + public override int GetHashCode() => Behavior.GetHashCode(this); + + /// + /// Blends a over this color, as defined by the current . + /// + /// The to blend. + public Color Blend(in Color color) => Behavior.Blend(this, color); + + #endregion + + #region Operators + + /// + /// Blends the provided colors as if would've been called on . + /// + /// The base color. + /// The color to blend. + /// The blended color. + public static Color operator +(in Color color1, in Color color2) => color1.Blend(color2); + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are equal; otherwise, false. + public static bool operator ==(in Color color1, in Color color2) => color1.Equals(color2); + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are not equal; otherwise, false. + public static bool operator !=(in Color color1, in Color color2) => !(color1 == color2); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((byte r, byte g, byte b) components) => new(components.r, components.g, components.b); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((byte a, byte r, byte g, byte b) components) => new(components.a, components.r, components.g, components.b); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((int r, int g, int b) components) => new(components.r, components.g, components.b); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((int a, int r, int g, int b) components) => new(components.a, components.r, components.g, components.b); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((float r, float g, float b) components) => new(components.r, components.g, components.b); + + /// + /// Converts a of ARGB-components to a . + /// + /// The containing the components. + /// The color. + public static implicit operator Color((float a, float r, float g, float b) components) => new(components.a, components.r, components.g, components.b); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Color/HSVColor.cs b/RGB.NET.Core/Color/HSVColor.cs index f99581c7..35af63fe 100644 --- a/RGB.NET.Core/Color/HSVColor.cs +++ b/RGB.NET.Core/Color/HSVColor.cs @@ -2,226 +2,227 @@ // ReSharper disable UnusedMember.Global using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Contains helper-methods and extension for the -type to work in the HSV color space. +/// +public static class HSVColor { - public static class HSVColor + #region Getter + + /// + /// Gets the hue component value (HSV-color space) of this as degree in the range [0..360]. + /// + /// The color to get the value from. + /// The hue component value of the color. + public static float GetHue(this in Color color) => color.GetHSV().hue; + + /// + /// Gets the saturation component value (HSV-color space) of this in the range [0..1]. + /// + /// The color to get the value from. + /// The saturation component value of the color. + public static float GetSaturation(this in Color color) => color.GetHSV().saturation; + + /// + /// Gets the value component value (HSV-color space) of this in the range [0..1]. + /// + /// The color to get the value from. + /// The value component value of the color. + public static float GetValue(this in Color color) => color.GetHSV().value; + + /// + /// Gets the hue, saturation and value component values (HSV-color space) of this . + /// Hue as degree in the range [0..1]. + /// Saturation in the range [0..1]. + /// Value in the range [0..1]. + /// + /// The color to get the value from. + /// A tuple containing the hue, saturation and value component value of the color. + public static (float hue, float saturation, float value) GetHSV(this in Color color) + => CaclulateHSVFromRGB(color.R, color.G, color.B); + + #endregion + + #region Manipulation + + /// + /// Adds the specified HSV values to this color. + /// + /// The color to modify. + /// The hue value to add. + /// The saturation value to add. + /// The value value to add. + /// The new color after the modification. + public static Color AddHSV(this in Color color, float hue = 0, float saturation = 0, float value = 0) { - #region Getter - - /// - /// Gets the hue component value (HSV-color space) of this as degree in the range [0..360]. - /// - /// - /// - public static double GetHue(this Color color) => color.GetHSV().hue; - - /// - /// Gets the saturation component value (HSV-color space) of this in the range [0..1]. - /// - /// - /// - public static double GetSaturation(this Color color) => color.GetHSV().saturation; - - /// - /// Gets the value component value (HSV-color space) of this in the range [0..1]. - /// - /// - /// - public static double GetValue(this Color color) => color.GetHSV().value; - - /// - /// Gets the hue, saturation and value component values (HSV-color space) of this . - /// Hue as degree in the range [0..1]. - /// Saturation in the range [0..1]. - /// Value in the range [0..1]. - /// - /// - /// - public static (double hue, double saturation, double value) GetHSV(this Color color) - => CaclulateHSVFromRGB(color.R, color.G, color.B); - - #endregion - - #region Manipulation - - /// - /// Adds the given HSV values to this color. - /// - /// The hue value to add. - /// The saturation value to add. - /// The value value to add. - /// The new color after the modification. - public static Color AddHSV(this Color color, double hue = 0, double saturation = 0, double value = 0) - { - (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.A, cHue + hue, cSaturation + saturation, cValue + value); - } - - /// - /// Subtracts the given HSV values to this color. - /// - /// The hue value to subtract. - /// The saturation value to subtract. - /// The value value to subtract. - /// The new color after the modification. - public static Color SubtractHSV(this Color color, double hue = 0, double saturation = 0, double value = 0) - { - (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.A, cHue - hue, cSaturation - saturation, cValue - value); - } - - /// - /// Multiplies the given HSV values to this color. - /// - /// The hue value to multiply. - /// The saturation value to multiply. - /// The value value to multiply. - /// The new color after the modification. - public static Color MultiplyHSV(this Color color, double hue = 1, double saturation = 1, double value = 1) - { - (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.A, cHue * hue, cSaturation * saturation, cValue * value); - } - - /// - /// Divides the given HSV values to this color. - /// - /// The hue value to divide. - /// The saturation value to divide. - /// The value value to divide. - /// The new color after the modification. - public static Color DivideHSV(this Color color, double hue = 1, double saturation = 1, double value = 1) - { - (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.A, cHue / hue, cSaturation / saturation, cValue / value); - } - - /// - /// Sets the given hue value of this color. - /// - /// The hue value to set. - /// The saturation value to set. - /// The value value to set. - /// The new color after the modification. - public static Color SetHSV(this Color color, double? hue = null, double? saturation = null, double? value = null) - { - (double cHue, double cSaturation, double cValue) = color.GetHSV(); - return Create(color.A, hue ?? cHue, saturation ?? cSaturation, value ?? cValue); - } - - #endregion - - #region Factory - - /// - /// Creates a new instance of the struct using HSV-Values. - /// - /// The hue component value of this . - /// The saturation component value of this . - /// The value component value of this . - /// The color created from the values. - public static Color Create(double hue, double saturation, double value) - => Create(1.0, hue, saturation, value); - - /// - /// Creates a new instance of the struct using AHSV-Values. - /// - /// The alpha component value of this . - /// The hue component value of this . - /// The saturation component value of this . - /// The value component value of this . - /// The color created from the values. - public static Color Create(byte a, double hue, double saturation, double value) - => Create((double)a / byte.MaxValue, hue, saturation, value); - - /// - /// Creates a new instance of the struct using AHSV-Values. - /// - /// The alpha component value of this . - /// The hue component value of this . - /// The saturation component value of this . - /// The value component value of this . - /// The color created from the values. - public static Color Create(int a, double hue, double saturation, double value) - => Create((double)a / byte.MaxValue, hue, saturation, value); - - /// - /// Creates a new instance of the struct using AHSV-Values. - /// - /// The alpha component value of this . - /// The hue component value of this . - /// The saturation component value of this . - /// The value component value of this . - /// The color created from the values. - public static Color Create(double a, double hue, double saturation, double value) - { - (double r, double g, double b) = CalculateRGBFromHSV(hue, saturation, value); - return new Color(a, r, g, b); - } + (float cHue, float cSaturation, float cValue) = color.GetHSV(); + return Create(color.A, cHue + hue, cSaturation + saturation, cValue + value); + } - #endregion + /// + /// Subtracts the specified HSV values to this color. + /// + /// The color to modify. + /// The hue value to subtract. + /// The saturation value to subtract. + /// The value value to subtract. + /// The new color after the modification. + public static Color SubtractHSV(this in Color color, float hue = 0, float saturation = 0, float value = 0) + { + (float cHue, float cSaturation, float cValue) = color.GetHSV(); + return Create(color.A, cHue - hue, cSaturation - saturation, cValue - value); + } - #region Helper + /// + /// Multiplies the specified HSV values to this color. + /// + /// The color to modify. + /// The hue value to multiply. + /// The saturation value to multiply. + /// The value value to multiply. + /// The new color after the modification. + public static Color MultiplyHSV(this in Color color, float hue = 1, float saturation = 1, float value = 1) + { + (float cHue, float cSaturation, float cValue) = color.GetHSV(); + return Create(color.A, cHue * hue, cSaturation * saturation, cValue * value); + } - private static (double h, double s, double v) CaclulateHSVFromRGB(double r, double g, double b) - { - if (r.EqualsInTolerance(g) && g.EqualsInTolerance(b)) return (0, 0, r); + /// + /// Divides the specified HSV values to this color. + /// + /// The color to modify. + /// The hue value to divide. + /// The saturation value to divide. + /// The value value to divide. + /// The new color after the modification. + public static Color DivideHSV(this in Color color, float hue = 1, float saturation = 1, float value = 1) + { + (float cHue, float cSaturation, float cValue) = color.GetHSV(); + return Create(color.A, cHue / hue, cSaturation / saturation, cValue / value); + } - double min = Math.Min(Math.Min(r, g), b); - double max = Math.Max(Math.Max(r, g), b); + /// + /// Sets the specified hue value of this color. + /// + /// The color to modify. + /// The hue value to set. + /// The saturation value to set. + /// The value value to set. + /// The new color after the modification. + public static Color SetHSV(this in Color color, float? hue = null, float? saturation = null, float? value = null) + { + (float cHue, float cSaturation, float cValue) = color.GetHSV(); + return Create(color.A, hue ?? cHue, saturation ?? cSaturation, value ?? cValue); + } + + #endregion + + #region Factory + + /// + /// Creates a new instance of the struct using HSV-Values. + /// + /// The hue component value of this . + /// The saturation component value of this . + /// The value component value of this . + /// The color created from the values. + public static Color Create(float hue, float saturation, float value) + => Create(1.0f, hue, saturation, value); + + /// + /// Creates a new instance of the struct using AHSV-Values. + /// + /// The alpha component value of this . + /// The hue component value of this . + /// The saturation component value of this . + /// The value component value of this . + /// The color created from the values. + public static Color Create(byte a, float hue, float saturation, float value) + => Create((float)a / byte.MaxValue, hue, saturation, value); + + /// + /// Creates a new instance of the struct using AHSV-Values. + /// + /// The alpha component value of this . + /// The hue component value of this . + /// The saturation component value of this . + /// The value component value of this . + /// The color created from the values. + public static Color Create(int a, float hue, float saturation, float value) + => Create((float)a / byte.MaxValue, hue, saturation, value); + + /// + /// Creates a new instance of the struct using AHSV-Values. + /// + /// The alpha component value of this . + /// The hue component value of this . + /// The saturation component value of this . + /// The value component value of this . + /// The color created from the values. + public static Color Create(float a, float hue, float saturation, float value) + { + (float r, float g, float b) = CalculateRGBFromHSV(hue, saturation, value); + return new Color(a, r, g, b); + } + + #endregion + + #region Helper + + private static (float h, float s, float v) CaclulateHSVFromRGB(float r, float g, float b) + { + if (r.EqualsInTolerance(g) && g.EqualsInTolerance(b)) return (0, 0, r); - double hue; - if (max.EqualsInTolerance(min)) - hue = 0; - else if (max.EqualsInTolerance(r)) // r is max - hue = (g - b) / (max - min); - else if (max.EqualsInTolerance(g)) // g is max - hue = 2.0 + ((b - r) / (max - min)); - else // b is max - hue = 4.0 + ((r - g) / (max - min)); + float min = Math.Min(Math.Min(r, g), b); + float max = Math.Max(Math.Max(r, g), b); - hue = hue * 60.0; - hue = hue.Wrap(0, 360); + float hue; + if (max.EqualsInTolerance(min)) + hue = 0; + else if (max.EqualsInTolerance(r)) // r is max + hue = (g - b) / (max - min); + else if (max.EqualsInTolerance(g)) // g is max + hue = 2.0f + ((b - r) / (max - min)); + else // b is max + hue = 4.0f + ((r - g) / (max - min)); - double saturation = max.EqualsInTolerance(0) ? 0 : 1.0 - (min / max); - double value = Math.Max(r, Math.Max(g, b)); + hue *= 60.0f; + hue = hue.Wrap(0, 360); - return (hue, saturation, value); - } + float saturation = max.EqualsInTolerance(0) ? 0 : 1.0f - (min / max); + float value = Math.Max(r, Math.Max(g, b)); - private static (double r, double g, double b) CalculateRGBFromHSV(double h, double s, double v) + return (hue, saturation, value); + } + + private static (float r, float g, float b) CalculateRGBFromHSV(float h, float s, float v) + { + h = h.Wrap(0, 360); + s = s.Clamp(0, 1); + v = v.Clamp(0, 1); + + if (s <= 0.0) + return (v, v, v); + + float hh = h / 60.0f; + int i = (int)hh; + float ff = hh - i; + float p = v * (1.0f - s); + float q = v * (1.0f - (s * ff)); + float t = v * (1.0f - (s * (1.0f - ff))); + + return i switch { - h = h.Wrap(0, 360); - s = s.Clamp(0, 1); - v = v.Clamp(0, 1); - - if (s <= 0.0) - return (v, v, v); - - double hh = h / 60.0; - int i = (int)hh; - double ff = hh - i; - double p = v * (1.0 - s); - double q = v * (1.0 - (s * ff)); - double t = v * (1.0 - (s * (1.0 - ff))); - - switch (i) - { - case 0: - return (v, t, p); - case 1: - return (q, v, p); - case 2: - return (p, v, t); - case 3: - return (p, q, v); - case 4: - return (t, p, v); - default: - return (v, p, q); - } - } - - #endregion + 0 => (v, t, p), + 1 => (q, v, p), + 2 => (p, v, t), + 3 => (p, q, v), + 4 => (t, p, v), + _ => (v, p, q) + }; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Color/HclColor.cs b/RGB.NET.Core/Color/HclColor.cs new file mode 100644 index 00000000..4133c582 --- /dev/null +++ b/RGB.NET.Core/Color/HclColor.cs @@ -0,0 +1,211 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global +using System; + +namespace RGB.NET.Core; + +/// +/// Contains helper-methods and extension for the -type to work in the Hcl color space. +/// +public static class HclColor +{ + #region Getter + + /// + /// Gets the H component value (Hcl-color space) of this in the range [0..360]. + /// + /// The color to get the value from. + /// The H component value of the color. + public static float GetHclH(this in Color color) => color.GetHcl().h; + + /// + /// Gets the c component value (Hcl-color space) of this in the range [0..1]. + /// + /// The color to get the value from. + /// The c component value of the color. + public static float GetHclC(this in Color color) => color.GetHcl().c; + + /// + /// Gets the l component value (Hcl-color space) of this in the range [0..1]. + /// + /// The color to get the value from. + /// The l component value of the color. + public static float GetHclL(this in Color color) => color.GetHcl().l; + + /// + /// Gets the H, c and l component values (Hcl-color space) of this . + /// H in the range [0..360]. + /// c in the range [0..1]. + /// l in the range [0..1]. + /// + /// The color to get the value from. + /// A tuple containing the H, c and l component value of the color. + public static (float h, float c, float l) GetHcl(this in Color color) + => CalculateHclFromRGB(color.R, color.G, color.B); + + #endregion + + #region Manipulation + + /// + /// Adds the specified Hcl values to this color. + /// + /// The color to modify. + /// The H value to add. + /// The c value to add. + /// The l value to add. + /// The new color after the modification. + public static Color AddHcl(this in Color color, float h = 0, float c = 0, float l = 0) + { + (float cH, float cC, float cL) = color.GetHcl(); + return Create(color.A, cH + h, cC + c, cL + l); + } + + /// + /// Subtracts the specified Hcl values to this color. + /// + /// The color to modify. + /// The H value to subtract. + /// The c value to subtract. + /// The l value to subtract. + /// The new color after the modification. + public static Color SubtractHcl(this in Color color, float h = 0, float c = 0, float l = 0) + { + (float cH, float cC, float cL) = color.GetHcl(); + return Create(color.A, cH - h, cC - c, cL - l); + } + + /// + /// Multiplies the specified Hcl values to this color. + /// + /// The color to modify. + /// The H value to multiply. + /// The c value to multiply. + /// The l value to multiply. + /// The new color after the modification. + public static Color MultiplyHcl(this in Color color, float h = 1, float c = 1, float l = 1) + { + (float cH, float cC, float cL) = color.GetHcl(); + return Create(color.A, cH * h, cC * c, cL * l); + } + + /// + /// Divides the specified Hcl values to this color. + /// + /// The color to modify. + /// The H value to divide. + /// The c value to divide. + /// The l value to divide. + /// The new color after the modification. + public static Color DivideHcl(this in Color color, float h = 1, float c = 1, float l = 1) + { + (float cH, float cC, float cL) = color.GetHcl(); + return Create(color.A, cH / h, cC / c, cL / l); + } + + /// + /// Sets the specified X value of this color. + /// + /// The color to modify. + /// The H value to set. + /// The c value to set. + /// The l value to set. + /// The new color after the modification. + public static Color SetHcl(this in Color color, float? h = null, float? c = null, float? l = null) + { + (float cH, float cC, float cL) = color.GetHcl(); + return Create(color.A, h ?? cH, c ?? cC, l ?? cL); + } + + #endregion + + #region Factory + + /// + /// Creates a new instance of the struct using Hcl-Values. + /// + /// The H component value of this . + /// The c component value of this . + /// The l component value of this . + /// The color created from the values. + public static Color Create(float h, float c, float l) + => Create(1.0f, h, c, l); + + /// + /// Creates a new instance of the struct using alpha and Hcl-Values. + /// + /// The alphc component value of this . + /// The H component value of this . + /// The c component value of this . + /// The l component value of this . + /// The color created from the values. + public static Color Create(byte alpha, float h, float c, float l) + => Create((float)alpha / byte.MaxValue, h, c, l); + + /// + /// Creates a new instance of the struct using alpha and Hcl-Values. + /// + /// The alphc component value of this . + /// The H component value of this . + /// The c component value of this . + /// The l component value of this . + /// The color created from the values. + public static Color Create(int alpha, float h, float c, float l) + => Create((float)alpha / byte.MaxValue, h, c, l); + + /// + /// Creates a new instance of the struct using alpha and Hcl-Values. + /// + /// The alphc component value of this . + /// The H component value of this . + /// The c component value of this . + /// The l component value of this . + /// The color created from the values. + public static Color Create(float alpha, float h, float c, float l) + { + (float r, float g, float b) = CalculateRGBFromHcl(h, c, l); + return new Color(alpha, r, g, b); + } + + #endregion + + #region Helper + + private static (float h, float c, float l) CalculateHclFromRGB(float r, float g, float b) + { + const float RADIANS_DEGREES_CONVERSION = 180.0f / MathF.PI; + + // ReSharper disable once InconsistentNaming - b is used above + (float l, float a, float _b) = LabColor.CalculateLabFromRGB(r, g, b); + + float h, c; + if (r.EqualsInTolerance(g) && r.EqualsInTolerance(b)) //DarthAffe 26.02.2021: The cumulated rounding errors are big enough to cause problems in that case + { + h = 0; + c = 0; + } + else + { + h = MathF.Atan2(_b, a); + if (h >= 0) h *= RADIANS_DEGREES_CONVERSION; + else h = 360 - (-h * RADIANS_DEGREES_CONVERSION); + + c = MathF.Sqrt((a * a) + (_b * _b)); + } + + return (h, c, l); + } + + private static (float r, float g, float b) CalculateRGBFromHcl(float h, float c, float l) + { + const float DEGREES_RADIANS_CONVERSION = MathF.PI / 180.0f; + + h *= DEGREES_RADIANS_CONVERSION; + float a = c * MathF.Cos(h); + float b = c * MathF.Sin(h); + + return LabColor.CalculateRGBFromLab(l, a, b); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Color/LabColor.cs b/RGB.NET.Core/Color/LabColor.cs new file mode 100644 index 00000000..7be06502 --- /dev/null +++ b/RGB.NET.Core/Color/LabColor.cs @@ -0,0 +1,227 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global +using System; + +namespace RGB.NET.Core; + +/// +/// Contains helper-methods and extension for the -type to work in the Lab color space. +/// +public static class LabColor +{ + #region Getter + + /// + /// Gets the L component value (Lab-color space) of this in the range [0..100]. + /// + /// The color to get the value from. + /// The L component value of the color. + public static float GetLabL(this in Color color) => color.GetLab().l; + + /// + /// Gets the a component value (Lab-color space) of this in the range [0..1]. + /// + /// The color to get the value from. + /// The a component value of the color. + public static float GetLabA(this in Color color) => color.GetLab().a; + + /// + /// Gets the b component value (Lab-color space) of this in the range [0..1]. + /// + /// The color to get the value from. + /// The b component value of the color. + public static float GetLabB(this in Color color) => color.GetLab().b; + + /// + /// Gets the L, a and b component values (Lab-color space) of this . + /// L in the range [0..100]. + /// a in the range [0..1]. + /// b in the range [0..1]. + /// + /// The color to get the value from. + /// A tuple containing the L, a and b component value of the color. + public static (float l, float a, float b) GetLab(this in Color color) + => CalculateLabFromRGB(color.R, color.G, color.B); + + #endregion + + #region Manipulation + + /// + /// Adds the specified Lab values to this color. + /// + /// The color to modify. + /// The L value to add. + /// The a value to add. + /// The b value to add. + /// The new color after the modification. + public static Color AddLab(this in Color color, float l = 0, float a = 0, float b = 0) + { + (float cL, float cA, float cB) = color.GetLab(); + return Create(color.A, cL + l, cA + a, cB + b); + } + + /// + /// Subtracts the specified Lab values to this color. + /// + /// The color to modify. + /// The L value to subtract. + /// The a value to subtract. + /// The b value to subtract. + /// The new color after the modification. + public static Color SubtractLab(this in Color color, float l = 0, float a = 0, float b = 0) + { + (float cL, float cA, float cB) = color.GetLab(); + return Create(color.A, cL - l, cA - a, cB - b); + } + + /// + /// Multiplies the specified Lab values to this color. + /// + /// The color to modify. + /// The L value to multiply. + /// The a value to multiply. + /// The b value to multiply. + /// The new color after the modification. + public static Color MultiplyLab(this in Color color, float l = 1, float a = 1, float b = 1) + { + (float cL, float cA, float cB) = color.GetLab(); + return Create(color.A, cL * l, cA * a, cB * b); + } + + /// + /// Divides the specified Lab values to this color. + /// + /// The color to modify. + /// The L value to divide. + /// The a value to divide. + /// The b value to divide. + /// The new color after the modification. + public static Color DivideLab(this in Color color, float l = 1, float a = 1, float b = 1) + { + (float cL, float cA, float cB) = color.GetLab(); + return Create(color.A, cL / l, cA / a, cB / b); + } + + /// + /// Sets the specified X valueof this color. + /// + /// The color to modify. + /// The L value to set. + /// The a value to set. + /// The b value to set. + /// The new color after the modification. + public static Color SetLab(this in Color color, float? l = null, float? a = null, float? b = null) + { + (float cL, float cA, float cB) = color.GetLab(); + return Create(color.A, l ?? cL, a ?? cA, b ?? cB); + } + + #endregion + + #region Factory + + /// + /// Creates a new instance of the struct using Lab-Values. + /// + /// The L component value of this . + /// The a component value of this . + /// The b component value of this . + /// The color created from the values. + public static Color Create(float l, float a, float b) + => Create(1.0f, l, a, b); + + /// + /// Creates a new instance of the struct using alpha and Lab-Values. + /// + /// The alpha component value of this . + /// The L component value of this . + /// The a component value of this . + /// The b component value of this . + /// The color created from the values. + public static Color Create(byte alpha, float l, float a, float b) + => Create((float)alpha / byte.MaxValue, l, a, b); + + /// + /// Creates a new instance of the struct using alpha and Lab-Values. + /// + /// The alpha component value of this . + /// The L component value of this . + /// The a component value of this . + /// The b component value of this . + /// The color created from the values. + public static Color Create(int alpha, float l, float a, float b) + => Create((float)alpha / byte.MaxValue, l, a, b); + + /// + /// Creates a new instance of the struct using alpha and Lab-Values. + /// + /// The alpha component value of this . + /// The L component value of this . + /// The a component value of this . + /// The b component value of this . + /// The color created from the values. + public static Color Create(float alpha, float l, float a, float b) + { + // ReSharper disable once InconsistentNaming - b is used above + (float r, float g, float _b) = CalculateRGBFromLab(l, a, b); + return new Color(alpha, r, g, _b); + } + + #endregion + + #region Helper + + internal static (float l, float a, float b) CalculateLabFromRGB(float r, float g, float b) + { + (float x, float y, float z) = XYZColor.CaclulateXYZFromRGB(r, g, b); + return CaclulateLabFromXYZ(x, y, z); + } + + internal static (float r, float g, float b) CalculateRGBFromLab(float l, float a, float b) + { + (float x, float y, float z) = CalculateXYZFromLab(l, a, b); + return XYZColor.CalculateRGBFromXYZ(x, y, z); + } + + private static (float l, float a, float b) CaclulateLabFromXYZ(float x, float y, float z) + { + const float ONETHRID = 1.0f / 3.0f; + const float FACTOR2 = 16.0f / 116.0f; + + x /= 95.047f; + y /= 100.0f; + z /= 108.883f; + + x = ((x > 0.008856f) ? (MathF.Pow(x, ONETHRID)) : ((7.787f * x) + FACTOR2)); + y = ((y > 0.008856f) ? (MathF.Pow(y, ONETHRID)) : ((7.787f * y) + FACTOR2)); + z = ((z > 0.008856f) ? (MathF.Pow(z, ONETHRID)) : ((7.787f * z) + FACTOR2)); + + float l = (116.0f * y) - 16.0f; + float a = 500.0f * (x - y); + float b = 200.0f * (y - z); + + return (l, a, b); + } + + private static (float x, float y, float z) CalculateXYZFromLab(float l, float a, float b) + { + const float FACTOR2 = 16.0f / 116.0f; + + float y = (l + 16.0f) / 116.0f; + float x = (a / 500.0f) + y; + float z = y - (b / 200.0f); + + float powX = MathF.Pow(x, 3.0f); + float powY = MathF.Pow(y, 3.0f); + float powZ = MathF.Pow(z, 3.0f); + + x = ((powX > 0.008856f) ? (powX) : ((x - FACTOR2) / 7.787f)); + y = ((powY > 0.008856f) ? (powY) : ((y - FACTOR2) / 7.787f)); + z = ((powZ > 0.008856f) ? (powZ) : ((z - FACTOR2) / 7.787f)); + + return (x * 95.047f, y * 100.0f, z * 108.883f); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Color/RGBColor.cs b/RGB.NET.Core/Color/RGBColor.cs index b1960767..9ffa528d 100644 --- a/RGB.NET.Core/Color/RGBColor.cs +++ b/RGB.NET.Core/Color/RGBColor.cs @@ -2,274 +2,294 @@ // ReSharper disable UnusedMember.Global using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Contains helper-methods and extension for the -type to work in the RGB color space. +/// +public static class RGBColor { - public static class RGBColor + #region Getter + + /// + /// Gets the A component value of this as byte in the range [0..255]. + /// + /// The color to get the value from. + /// The A component value of the color. + public static byte GetA(this in Color color) => color.A.GetByteValueFromPercentage(); + + /// + /// Gets the R component value of this as byte in the range [0..255]. + /// + /// The color to get the value from. + /// The R component value of the color. + public static byte GetR(this in Color color) => color.R.GetByteValueFromPercentage(); + + /// + /// Gets the G component value of this as byte in the range [0..255]. + /// + /// The color to get the value from. + /// The G component value of the color. + public static byte GetG(this in Color color) => color.G.GetByteValueFromPercentage(); + + /// + /// Gets the B component value of this as byte in the range [0..255]. + /// + /// The color to get the value from. + /// The B component value of the color. + public static byte GetB(this in Color color) => color.B.GetByteValueFromPercentage(); + + /// + /// Gets the A, R, G and B component value of this as byte in the range [0..255]. + /// + /// The color to get the value from. + /// A tuple containing the A, R, G and B component value of the color. + public static (byte a, byte r, byte g, byte b) GetRGBBytes(this in Color color) + => (color.GetA(), color.GetR(), color.GetG(), color.GetB()); + + /// + /// Gets the A, R, G and B component value of this as percentage in the range [0..1]. + /// + /// The color to get the value from. + /// A tuple containing the A, R, G and B component value of the color. + public static (float a, float r, float g, float b) GetRGB(this in Color color) + => (color.A, color.R, color.G, color.B); + + #endregion + + #region Manipulation + + #region Add + + /// + /// Adds the specified RGB values to this color. + /// + /// The color to modify. + /// The red value to add. + /// The green value to add. + /// The blue value to add. + /// The new color after the modification. + public static Color AddRGB(this in Color color, int r = 0, int g = 0, int b = 0) + => new(color.A, color.GetR() + r, color.GetG() + g, color.GetB() + b); + + /// + /// Adds the specified RGB-percent values to this color. + /// + /// The color to modify. + /// The red value to add. + /// The green value to add. + /// The blue value to add. + /// The new color after the modification. + public static Color AddRGB(this in Color color, float r = 0, float g = 0, float b = 0) + => new(color.A, color.R + r, color.G + g, color.B + b); + + /// + /// Adds the specified alpha value to this color. + /// + /// The color to modify. + /// The alpha value to add. + /// The new color after the modification. + public static Color AddA(this in Color color, int a) + => new(color.GetA() + a, color.R, color.G, color.B); + + /// + /// Adds the specified alpha-percent value to this color. + /// + /// The color to modify. + /// The alpha value to add. + /// The new color after the modification. + public static Color AddA(this in Color color, float a) + => new(color.A + a, color.R, color.G, color.B); + + #endregion + + #region Subtract + + /// + /// Subtracts the specified RGB values to this color. + /// + /// The color to modify. + /// The red value to subtract. + /// The green value to subtract. + /// The blue value to subtract. + /// The new color after the modification. + public static Color SubtractRGB(this in Color color, int r = 0, int g = 0, int b = 0) + => new(color.A, color.GetR() - r, color.GetG() - g, color.GetB() - b); + + /// + /// Subtracts the specified RGB values to this color. + /// + /// The color to modify. + /// The red value to subtract. + /// The green value to subtract. + /// The blue value to subtract. + /// The new color after the modification. + public static Color SubtractRGB(this in Color color, float r = 0, float g = 0, float b = 0) + => new(color.A, color.R - r, color.G - g, color.B - b); + + /// + /// Subtracts the specified alpha value to this color. + /// + /// The color to modify. + /// The alpha value to subtract. + /// The new color after the modification. + public static Color SubtractA(this in Color color, int a) + => new(color.GetA() - a, color.R, color.G, color.B); + + /// + /// Subtracts the specified alpha-percent value to this color. + /// + /// The color to modify. + /// The alpha value to subtract. + /// The new color after the modification. + public static Color SubtractA(this in Color color, float aPercent) + => new(color.A - aPercent, color.R, color.G, color.B); + + #endregion + + #region Multiply + + /// + /// Multiplies the specified RGB values to this color. + /// + /// The color to modify. + /// The red value to multiply. + /// The green value to multiply. + /// The blue value to multiply. + /// The new color after the modification. + public static Color MultiplyRGB(this in Color color, float r = 1, float g = 1, float b = 1) + => new(color.A, color.R * r, color.G * g, color.B * b); + + /// + /// Multiplies the specified alpha value to this color. + /// + /// The color to modify. + /// The alpha value to multiply. + /// The new color after the modification. + public static Color MultiplyA(this in Color color, float a) + => new(color.A * a, color.R, color.G, color.B); + + #endregion + + #region Divide + + /// + /// Divides the specified RGB values to this color. + /// + /// The color to modify. + /// The red value to divide. + /// The green value to divide. + /// The blue value to divide. + /// The new color after the modification. + public static Color DivideRGB(this in Color color, float r = 1, float g = 1, float b = 1) + => new(color.A, color.R / r, color.G / g, color.B / b); + + /// + /// Divides the specified alpha value to this color. + /// + /// The color to modify. + /// The alpha value to divide. + /// The new color after the modification. + public static Color DivideA(this in Color color, float a) + => new(color.A / a, color.R, color.G, color.B); + + #endregion + + #region Set + + /// + /// Sets the specified RGB value of this color. + /// + /// The color to modify. + /// The red value to set. + /// The green value to set. + /// The blue value to set. + /// The new color after the modification. + public static Color SetRGB(this in Color color, byte? r = null, byte? g = null, byte? b = null) + => new(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); + + /// + /// Sets the specified RGB value of this color. + /// + /// The color to modify. + /// The red value to set. + /// The green value to set. + /// The blue value to set. + /// The new color after the modification. + public static Color SetRGB(this in Color color, int? r = null, int? g = null, int? b = null) + => new(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); + + /// + /// Sets the specified RGB value of this color. + /// + /// The color to modify. + /// The red value to set. + /// The green value to set. + /// The blue value to set. + /// The new color after the modification. + public static Color SetRGB(this in Color color, float? r = null, float? g = null, float? b = null) + => new(color.A, r ?? color.R, g ?? color.G, b ?? color.B); + + /// + /// Sets the specified alpha value of this color. + /// + /// The color to modify. + /// The alpha value to set. + /// The new color after the modification. + public static Color SetA(this in Color color, int a) => new(a, color.R, color.G, color.B); + + /// + /// Sets the specified alpha value of this color. + /// + /// The color to modify. + /// The alpha value to set. + /// The new color after the modification. + public static Color SetA(this in Color color, float a) => new(a, color.R, color.G, color.B); + + #endregion + + #endregion + + #region Conversion + + /// + /// Gets the current color as a RGB-HEX-string. + /// + /// The RGB-HEX-string. + public static string AsRGBHexString(this in Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetR(), color.GetG(), color.GetB()); + + /// + /// Gets the current color as a ARGB-HEX-string. + /// + /// The ARGB-HEX-string. + public static string AsARGBHexString(this in Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetA(), color.GetR(), color.GetG(), color.GetB()); + + #endregion + + #region Factory + + /// + /// Creates a new instance of the struct using a HEX-string. + /// + /// The HEX-representation of the color. + /// The color created from the HEX-string. + public static Color FromHexString(string hexString) { - #region Getter - - /// - /// Gets the A component value of this as byte in the range [0..255]. - /// - /// - /// - public static byte GetA(this Color color) => color.A.GetByteValueFromPercentage(); - - /// - /// Gets the R component value of this as byte in the range [0..255]. - /// - /// - /// - public static byte GetR(this Color color) => color.R.GetByteValueFromPercentage(); - - /// - /// Gets the G component value of this as byte in the range [0..255]. - /// - /// - /// - public static byte GetG(this Color color) => color.G.GetByteValueFromPercentage(); - - /// - /// Gets the B component value of this as byte in the range [0..255]. - /// - /// - /// - public static byte GetB(this Color color) => color.B.GetByteValueFromPercentage(); - - /// - /// Gets the A, R, G and B component value of this as byte in the range [0..255]. - /// - /// - /// - public static (byte a, byte r, byte g, byte b) GetRGBBytes(this Color color) - => (color.GetA(), color.GetR(), color.GetG(), color.GetB()); - - /// - /// Gets the A, R, G and B component value of this as percentage in the range [0..1]. - /// - /// - /// - public static (double a, double r, double g, double b) GetRGB(this Color color) - => (color.A, color.R, color.G, color.B); - - #endregion - - #region Manipulation - - #region Add - - /// - /// Adds the given RGB values to this color. - /// - /// The red value to add. - /// The green value to add. - /// The blue value to add. - /// The new color after the modification. - public static Color AddRGB(this Color color, int r = 0, int g = 0, int b = 0) - => new Color(color.A, color.GetR() + r, color.GetG() + g, color.GetB() + b); - - /// - /// Adds the given RGB-percent values to this color. - /// - /// The red value to add. - /// The green value to add. - /// The blue value to add. - /// The new color after the modification. - public static Color AddRGB(this Color color, double r = 0, double g = 0, double b = 0) - => new Color(color.A, color.R + r, color.G + g, color.B + b); - - /// - /// Adds the given alpha value to this color. - /// - /// The alpha value to add. - /// The new color after the modification. - public static Color AddA(this Color color, int a) - => new Color(color.GetA() + a, color.R, color.G, color.B); - - /// - /// Adds the given alpha-percent value to this color. - /// - /// The alpha value to add. - /// The new color after the modification. - public static Color AddA(this Color color, double a) - => new Color(color.A + a, color.R, color.G, color.B); - - #endregion - - #region Subtract - - /// - /// Subtracts the given RGB values to this color. - /// - /// The red value to subtract. - /// The green value to subtract. - /// The blue value to subtract. - /// The new color after the modification. - public static Color SubtractRGB(this Color color, int r = 0, int g = 0, int b = 0) - => new Color(color.A, color.GetR() - r, color.GetG() - g, color.GetB() - b); - - /// - /// Subtracts the given RGB values to this color. - /// - /// The red value to subtract. - /// The green value to subtract. - /// The blue value to subtract. - /// The new color after the modification. - public static Color SubtractRGB(this Color color, double r = 0, double g = 0, double b = 0) - => new Color(color.A, color.R - r, color.G - g, color.B - b); - - /// - /// Subtracts the given alpha value to this color. - /// - /// The alpha value to subtract. - /// The new color after the modification. - public static Color SubtractA(this Color color, int a) - => new Color(color.GetA() - a, color.R, color.G, color.B); - - /// - /// Subtracts the given alpha-percent value to this color. - /// - /// The alpha value to subtract. - /// The new color after the modification. - public static Color SubtractA(this Color color, double aPercent) - => new Color(color.A - aPercent, color.R, color.G, color.B); - - #endregion - - #region Multiply - - /// - /// Multiplies the given RGB values to this color. - /// - /// The red value to multiply. - /// The green value to multiply. - /// The blue value to multiply. - /// The new color after the modification. - public static Color MultiplyRGB(this Color color, double r = 1, double g = 1, double b = 1) - => new Color(color.A, color.R * r, color.G * g, color.B * b); - - /// - /// Multiplies the given alpha value to this color. - /// - /// The alpha value to multiply. - /// The new color after the modification. - public static Color MultiplyA(this Color color, double a) - => new Color(color.A * a, color.R, color.G, color.B); - - #endregion - - #region Divide - - /// - /// Divides the given RGB values to this color. - /// - /// The red value to divide. - /// The green value to divide. - /// The blue value to divide. - /// The new color after the modification. - public static Color DivideRGB(this Color color, double r = 1, double g = 1, double b = 1) - => new Color(color.A, color.R / r, color.G / g, color.B / b); - - /// - /// Divides the given alpha value to this color. - /// - /// The alpha value to divide. - /// The new color after the modification. - public static Color DivideA(this Color color, double a) - => new Color(color.A / a, color.R, color.G, color.B); - - #endregion - - #region Set - - /// - /// Sets the given RGB value of this color. - /// - /// The red value to set. - /// The green value to set. - /// The blue value to set. - /// The new color after the modification. - public static Color SetRGB(this Color color, byte? r = null, byte? g = null, byte? b = null) - => new Color(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); - - /// - /// Sets the given RGB value of this color. - /// - /// The red value to set. - /// The green value to set. - /// The blue value to set. - /// The new color after the modification. - public static Color SetRGB(this Color color, int? r = null, int? g = null, int? b = null) - => new Color(color.A, r ?? color.GetR(), g ?? color.GetG(), b ?? color.GetB()); - - /// - /// Sets the given RGB value of this color. - /// - /// The red value to set. - /// The green value to set. - /// The blue value to set. - /// The new color after the modification. - public static Color SetRGB(this Color color, double? r = null, double? g = null, double? b = null) - => new Color(color.A, r ?? color.R, g ?? color.G, b ?? color.B); - - /// - /// Sets the given alpha value of this color. - /// - /// The alpha value to set. - /// The new color after the modification. - public static Color SetA(this Color color, int a) => new Color(a, color.R, color.G, color.B); - - /// - /// Sets the given alpha value of this color. - /// - /// The alpha value to set. - /// The new color after the modification. - public static Color SetA(this Color color, double a) => new Color(a, color.R, color.G, color.B); - - #endregion - - #endregion - - #region Conversion - - /// - /// Gets the current color as a RGB-HEX-string. - /// - /// The RGB-HEX-string. - public static string AsRGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetR(), color.GetG(), color.GetB()); - - /// - /// Gets the current color as a ARGB-HEX-string. - /// - /// The ARGB-HEX-string. - public static string AsARGBHexString(this Color color, bool leadingHash = true) => (leadingHash ? "#" : "") + ConversionHelper.ToHex(color.GetA(), color.GetR(), color.GetG(), color.GetB()); - - #endregion - - #region Factory - - /// - /// Creates a new instance of the struct using a HEX-string. - /// - /// The HEX-representation of the color. - /// The color created from the HEX-string. - public static Color FromHexString(string hexString) - { - if ((hexString == null) || (hexString.Length < 6)) - throw new ArgumentException("Invalid hex string", nameof(hexString)); - - if (hexString[0] == '#') - hexString = hexString.Substring(1); - - byte[] data = ConversionHelper.HexToBytes(hexString); - if (data.Length == 3) - return new Color(data[0], data[1], data[2]); - if (data.Length == 4) - return new Color(data[0], data[1], data[2], data[3]); - + if ((hexString == null) || (hexString.Length < 6)) throw new ArgumentException("Invalid hex string", nameof(hexString)); - } - #endregion + ReadOnlySpan span = hexString.AsSpan(); + if (span[0] == '#') + span = span[1..]; + + byte[] data = ConversionHelper.HexToBytes(span); + return data.Length switch + { + 3 => new Color(data[0], data[1], data[2]), + 4 => new Color(data[0], data[1], data[2], data[3]), + _ => throw new ArgumentException($"Invalid hex string '{hexString}'", nameof(hexString)) + }; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Color/XYZColor.cs b/RGB.NET.Core/Color/XYZColor.cs new file mode 100644 index 00000000..168d4f73 --- /dev/null +++ b/RGB.NET.Core/Color/XYZColor.cs @@ -0,0 +1,207 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global +using System; + +namespace RGB.NET.Core; + +/// +/// Contains helper-methods and extension for the -type to work in the XYZ color space. +/// +public static class XYZColor +{ + #region Getter + + /// + /// Gets the X component value (XYZ-color space) of this in the range [0..95.047]. + /// + /// The color to get the value from. + /// The X component value of the color. + public static float GetX(this in Color color) => color.GetXYZ().x; + + /// + /// Gets the Y component value (XYZ-color space) of this in the range [0..100]. + /// + /// The color to get the value from. + /// The Y component value of the color. + public static float GetY(this in Color color) => color.GetXYZ().y; + + /// + /// Gets the Z component value (XYZ-color space) of this in the range [0..108.883]. + /// + /// The color to get the value from. + /// The Z component value of the color. + public static float GetZ(this in Color color) => color.GetXYZ().z; + + /// + /// Gets the X, Y and Z component values (XYZ-color space) of this . + /// X in the range [0..95.047]. + /// Y in the range [0..100]. + /// Z in the range [0..108.883]. + /// + /// The color to get the value from. + /// A tuple containing the X, Y and Z component value of the color. + public static (float x, float y, float z) GetXYZ(this in Color color) + => CaclulateXYZFromRGB(color.R, color.G, color.B); + + #endregion + + #region Manipulation + + /// + /// Adds the specified XYZ values to this color. + /// + /// The color to modify. + /// The X value to add. + /// The Y value to add. + /// The Z value to add. + /// The new color after the modification. + public static Color AddXYZ(this in Color color, float x = 0, float y = 0, float z = 0) + { + (float cX, float cY, float cZ) = color.GetXYZ(); + return Create(color.A, cX + x, cY + y, cZ + z); + } + + /// + /// Subtracts the specified XYZ values to this color. + /// + /// The color to modify. + /// The X value to subtract. + /// The Y value to subtract. + /// The Z value to subtract. + /// The new color after the modification. + public static Color SubtractXYZ(this in Color color, float x = 0, float y = 0, float z = 0) + { + (float cX, float cY, float cZ) = color.GetXYZ(); + return Create(color.A, cX - x, cY - y, cZ - z); + } + + /// + /// Multiplies the specified XYZ values to this color. + /// + /// The color to modify. + /// The X value to multiply. + /// The Y value to multiply. + /// The Z value to multiply. + /// The new color after the modification. + public static Color MultiplyXYZ(this in Color color, float x = 1, float y = 1, float z = 1) + { + (float cX, float cY, float cZ) = color.GetXYZ(); + return Create(color.A, cX * x, cY * y, cZ * z); + } + + /// + /// Divides the specified XYZ values to this color. + /// + /// The color to modify. + /// The X value to divide. + /// The Y value to divide. + /// The Z value to divide. + /// The new color after the modification. + public static Color DivideXYZ(this in Color color, float x = 1, float y = 1, float z = 1) + { + (float cX, float cY, float cZ) = color.GetXYZ(); + return Create(color.A, cX / x, cY / y, cZ / z); + } + + /// + /// Sets the specified X valueof this color. + /// + /// The color to modify. + /// The X value to set. + /// The Y value to set. + /// The Z value to set. + /// The new color after the modification. + public static Color SetXYZ(this in Color color, float? x = null, float? y = null, float? z = null) + { + (float cX, float cY, float cZ) = color.GetXYZ(); + return Create(color.A, x ?? cX, y ?? cY, z ?? cZ); + } + + #endregion + + #region Factory + + /// + /// Creates a new instance of the struct using XYZ-Values. + /// + /// The X component value of this . + /// The Y component value of this . + /// The Z component value of this . + /// The color created from the values. + public static Color Create(float x, float y, float z) + => Create(1.0f, x, y, z); + + /// + /// Creates a new instance of the struct using alpha and XYZ-Values. + /// + /// The alpha component value of this . + /// The X component value of this . + /// The Y component value of this . + /// The Z component value of this . + /// The color created from the values. + public static Color Create(byte a, float x, float y, float z) + => Create((float)a / byte.MaxValue, x, y, z); + + /// + /// Creates a new instance of the struct using alpha and XYZ-Values. + /// + /// The alpha component value of this . + /// The X component value of this . + /// The Y component value of this . + /// The Z component value of this . + /// The color created from the values. + public static Color Create(int a, float x, float y, float z) + => Create((float)a / byte.MaxValue, x, y, z); + + /// + /// Creates a new instance of the struct using alpha and XYZ-Values. + /// + /// The alpha component value of this . + /// The X component value of this . + /// The Y component value of this . + /// The Z component value of this . + /// The color created from the values. + public static Color Create(float a, float x, float y, float z) + { + (float r, float g, float b) = CalculateRGBFromXYZ(x, y, z); + return new Color(a, r, g, b); + } + + #endregion + + #region Helper + + internal static (float x, float y, float z) CaclulateXYZFromRGB(float r, float g, float b) + { + r = ((r > 0.04045f) ? MathF.Pow(((r + 0.055f) / 1.055f), 2.4f) : (r / 12.92f)) * 100.0f; + g = ((g > 0.04045f) ? MathF.Pow(((g + 0.055f) / 1.055f), 2.4f) : (g / 12.92f)) * 100.0f; + b = ((b > 0.04045f) ? MathF.Pow(((b + 0.055f) / 1.055f), 2.4f) : (b / 12.92f)) * 100.0f; + + float x = (r * 0.4124f) + (g * 0.3576f) + (b * 0.1805f); + float y = (r * 0.2126f) + (g * 0.7152f) + (b * 0.0722f); + float z = (r * 0.0193f) + (g * 0.1192f) + (b * 0.9505f); + + return (x, y, z); + } + + internal static (float r, float g, float b) CalculateRGBFromXYZ(float x, float y, float z) + { + const float INVERSE_EXPONENT = 1.0f / 2.4f; + + x /= 100.0f; + y /= 100.0f; + z /= 100.0f; + + float r = (x * 3.2406f) + (y * -1.5372f) + (z * -0.4986f); + float g = (x * -0.9689f) + (y * 1.8758f) + (z * 0.0415f); + float b = (x * 0.0557f) + (y * -0.2040f) + (z * 1.0570f); + + r = ((r > 0.0031308f) ? ((1.055f * (MathF.Pow(r, INVERSE_EXPONENT))) - 0.055f) : (12.92f * r)); + g = ((g > 0.0031308f) ? ((1.055f * (MathF.Pow(g, INVERSE_EXPONENT))) - 0.055f) : (12.92f * g)); + b = ((b > 0.0031308f) ? ((1.055f * (MathF.Pow(b, INVERSE_EXPONENT))) - 0.055f) : (12.92f * b)); + + return (r, g, b); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/ColorCorrection/IColorCorrection.cs b/RGB.NET.Core/ColorCorrection/IColorCorrection.cs index e3e417a2..25a6be85 100644 --- a/RGB.NET.Core/ColorCorrection/IColorCorrection.cs +++ b/RGB.NET.Core/ColorCorrection/IColorCorrection.cs @@ -1,16 +1,15 @@ // ReSharper disable UnusedMember.Global -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a generic color-correction. +/// +public interface IColorCorrection { /// - /// Represents a generic color-correction. + /// Applies the to the specified . /// - public interface IColorCorrection - { - /// - /// Applies the to the given . - /// - /// The to correct. - Color ApplyTo(Color color); - } -} + /// The to correct. + void ApplyTo(ref Color color); +} \ No newline at end of file diff --git a/RGB.NET.Core/Decorators/AbstractDecorateable.cs b/RGB.NET.Core/Decorators/AbstractDecorateable.cs index d12afcd3..5312eab6 100644 --- a/RGB.NET.Core/Decorators/AbstractDecorateable.cs +++ b/RGB.NET.Core/Decorators/AbstractDecorateable.cs @@ -2,64 +2,68 @@ using System.Collections.ObjectModel; using System.Linq; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +public abstract class AbstractDecoratable : AbstractBindable, IDecoratable + where T : IDecorator { - /// - /// - public abstract class AbstractDecoratable : AbstractBindable, IDecoratable - where T : IDecorator - { - #region Properties & Fields + #region Properties & Fields - private readonly List _decorators = new List(); + private readonly List _decorators = new(); - /// - public IReadOnlyCollection Decorators - { - get - { - lock (_decorators) - return new ReadOnlyCollection(_decorators); - } - } + /// + public IReadOnlyList Decorators { get; } - #endregion + #endregion - #region Methods + #region Constructors - /// - public void AddDecorator(T decorator) - { - lock (Decorators) - { - _decorators.Add(decorator); - _decorators.Sort((d1, d2) => d1.Order.CompareTo(d2.Order)); - } + /// + /// Initializes a new instance of the class. + /// + protected AbstractDecoratable() + { + Decorators = new ReadOnlyCollection(_decorators); + } - decorator.OnAttached(this); - } + #endregion - /// - public void RemoveDecorator(T decorator) - { - lock (Decorators) - _decorators.Remove(decorator); + #region Methods - decorator.OnDetached(this); + /// + public void AddDecorator(T decorator) + { + lock (Decorators) + { + _decorators.Add(decorator); + _decorators.Sort((d1, d2) => d1.Order.CompareTo(d2.Order)); } - /// - public void RemoveAllDecorators() - { - IEnumerable decorators; + decorator.OnAttached(this); + } - lock (Decorators) - decorators = Decorators.ToList(); + /// + public void RemoveDecorator(T decorator) + { + lock (Decorators) + _decorators.Remove(decorator); - foreach (T decorator in decorators) - RemoveDecorator(decorator); - } + decorator.OnDetached(this); + } + + /// + public void RemoveAllDecorators() + { + IEnumerable decorators; - #endregion + lock (Decorators) + decorators = Decorators.ToList(); + + foreach (T decorator in decorators) + RemoveDecorator(decorator); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Decorators/AbstractDecorator.cs b/RGB.NET.Core/Decorators/AbstractDecorator.cs index 50e007c6..159fb4b2 100644 --- a/RGB.NET.Core/Decorators/AbstractDecorator.cs +++ b/RGB.NET.Core/Decorators/AbstractDecorator.cs @@ -2,61 +2,60 @@ using System.Collections.Generic; using System.Linq; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +public abstract class AbstractDecorator : AbstractBindable, IDecorator { - /// - /// - public abstract class AbstractDecorator : AbstractBindable, IDecorator - { - #region Properties & Fields + #region Properties & Fields - private bool _isEnabled = true; - /// - public bool IsEnabled - { - get => _isEnabled; - set => SetProperty(ref _isEnabled, value); - } + private bool _isEnabled = true; + /// + public bool IsEnabled + { + get => _isEnabled; + set => SetProperty(ref _isEnabled, value); + } - private int _order; - /// - public int Order - { - get => _order; - set => SetProperty(ref _order, value); - } + private int _order; + /// + public int Order + { + get => _order; + set => SetProperty(ref _order, value); + } - /// - /// Gets a readonly-list of all this decorator is attached to. - /// - protected List DecoratedObjects { get; } = new List(); + /// + /// Gets a readonly-list of all this decorator is attached to. + /// + protected List DecoratedObjects { get; } = new(); - #endregion + #endregion - #region Methods + #region Methods - /// - public virtual void OnAttached(IDecoratable decoratable) => DecoratedObjects.Add(decoratable); + /// + public virtual void OnAttached(IDecoratable decoratable) => DecoratedObjects.Add(decoratable); - /// - public virtual void OnDetached(IDecoratable decoratable) => DecoratedObjects.Remove(decoratable); + /// + public virtual void OnDetached(IDecoratable decoratable) => DecoratedObjects.Remove(decoratable); - /// - /// Detaches the decorator from all it is currently attached to. - /// - protected virtual void Detach() + /// + /// Detaches the decorator from all it is currently attached to. + /// + protected virtual void Detach() + { + List decoratables = new(DecoratedObjects); + foreach (IDecoratable decoratable in decoratables) { - List decoratables = new List(DecoratedObjects); - foreach (IDecoratable decoratable in decoratables) - { - IEnumerable types = decoratable.GetType().GetInterfaces().Where(t => t.IsGenericType - && (t.Name == typeof(IDecoratable<>).Name) - && t.GenericTypeArguments[0].IsInstanceOfType(this)); - foreach (Type decoratableType in types) - decoratableType.GetMethod(nameof(IDecoratable.RemoveDecorator))?.Invoke(decoratable, new object[] { this }); - } + IEnumerable types = decoratable.GetType().GetInterfaces().Where(t => t.IsGenericType + && (t.Name == typeof(IDecoratable<>).Name) + && t.GenericTypeArguments[0].IsInstanceOfType(this)); + foreach (Type decoratableType in types) + decoratableType.GetMethod(nameof(IDecoratable.RemoveDecorator))?.Invoke(decoratable, new object[] { this }); } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Decorators/AbstractUpdateAwareDecorator.cs b/RGB.NET.Core/Decorators/AbstractUpdateAwareDecorator.cs index 98e64b2b..7a1b32a3 100644 --- a/RGB.NET.Core/Decorators/AbstractUpdateAwareDecorator.cs +++ b/RGB.NET.Core/Decorators/AbstractUpdateAwareDecorator.cs @@ -1,65 +1,71 @@ -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// Represents a basic decorator which is aware of the event. +/// +public abstract class AbstractUpdateAwareDecorator : AbstractDecorator { - /// + #region Properties & Fields + /// - /// Represents a basic decorator which is aware of the event. + /// Gets the surface this decorator is attached to. /// - public abstract class AbstractUpdateAwareDecorator : AbstractDecorator - { - #region Properties & Fields + protected RGBSurface Surface { get; } - /// - /// Gets or sets if the should call even if the Decorator is disabled. - /// - protected bool UpdateIfDisabled { get; set; } + /// + /// Gets or sets if the should call even if the Decorator is disabled. + /// + protected bool UpdateIfDisabled { get; set; } - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// Bool indicating if the should call even if the Decorator is disabled. - protected AbstractUpdateAwareDecorator(bool updateIfDisabled = false) - { - this.UpdateIfDisabled = updateIfDisabled; - } + /// + /// Initializes a new instance of the class. + /// + /// The surface this decorator is attached to. + /// Bool indicating if the should call even if the Decorator is disabled. + protected AbstractUpdateAwareDecorator(RGBSurface surface, bool updateIfDisabled = false) + { + this.Surface = surface; + this.UpdateIfDisabled = updateIfDisabled; + } - #endregion + #endregion - #region Methods + #region Methods - /// - public override void OnAttached(IDecoratable decoratable) - { - if (DecoratedObjects.Count == 0) - RGBSurface.Instance.Updating += OnSurfaceUpdating; + /// + public override void OnAttached(IDecoratable decoratable) + { + if (DecoratedObjects.Count == 0) + Surface.Updating += OnSurfaceUpdating; - base.OnAttached(decoratable); - } + base.OnAttached(decoratable); + } - /// - public override void OnDetached(IDecoratable decoratable) - { - base.OnDetached(decoratable); + /// + public override void OnDetached(IDecoratable decoratable) + { + base.OnDetached(decoratable); - if (DecoratedObjects.Count == 0) - RGBSurface.Instance.Updating -= OnSurfaceUpdating; - } + if (DecoratedObjects.Count == 0) + Surface.Updating -= OnSurfaceUpdating; + } - private void OnSurfaceUpdating(UpdatingEventArgs args) - { - if (IsEnabled || UpdateIfDisabled) - Update(args.DeltaTime); - } + private void OnSurfaceUpdating(UpdatingEventArgs args) + { + if (IsEnabled || UpdateIfDisabled) + Update(args.DeltaTime); + } - /// - /// Updates this . - /// - /// The elapsed time (in seconds) since the last update. - protected abstract void Update(double deltaTime); + /// + /// Updates this . + /// + /// The elapsed time (in seconds) since the last update. + protected abstract void Update(double deltaTime); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Decorators/IBrushDecorator.cs b/RGB.NET.Core/Decorators/IBrushDecorator.cs index 812af246..ec1c4325 100644 --- a/RGB.NET.Core/Decorators/IBrushDecorator.cs +++ b/RGB.NET.Core/Decorators/IBrushDecorator.cs @@ -1,17 +1,16 @@ -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// Represents a decorating a . +/// +public interface IBrushDecorator : IDecorator { - /// /// - /// Represents a decorating a . + /// Decorator-Method called by the . /// - public interface IBrushDecorator : IDecorator - { - /// - /// Decorator-Method called by the . - /// - /// The rectangle in which the should be drawn. - /// The target (key/point) from which the should be taken. - /// The to be modified. - Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color); - } -} + /// The rectangle in which the should be drawn. + /// The target (key/point) from which the should be taken. + /// The to be modified. + void ManipulateColor(in Rectangle rectangle, in RenderTarget renderTarget, ref Color color); +} \ No newline at end of file diff --git a/RGB.NET.Core/Decorators/IDecoratable.cs b/RGB.NET.Core/Decorators/IDecoratable.cs index 781d9f10..5fddf47a 100644 --- a/RGB.NET.Core/Decorators/IDecoratable.cs +++ b/RGB.NET.Core/Decorators/IDecoratable.cs @@ -1,42 +1,41 @@ using System.Collections.Generic; using System.ComponentModel; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a basic decoratable. +/// +public interface IDecoratable : INotifyPropertyChanged +{ } + +/// +/// +/// Represents a basic decoratable for a specific type of +/// +/// The type of decorators this decoratable can be decorated with. +public interface IDecoratable : IDecoratable + where T : IDecorator { /// - /// Represents a basic decoratable. + /// Gets a readonly-list of all attached to this . /// - public interface IDecoratable : INotifyPropertyChanged - { } + IReadOnlyList Decorators { get; } - /// /// - /// Represents a basic decoratable for a specific type of + /// Adds an to the . /// - /// - public interface IDecoratable : IDecoratable - where T : IDecorator - { - /// - /// Gets a readonly-list of all attached to this . - /// - IReadOnlyCollection Decorators { get; } + /// The to be added. + void AddDecorator(T decorator); - /// - /// Adds an to the . - /// - /// The to be added. - void AddDecorator(T decorator); - - /// - /// Removes an from the . - /// - /// The to be removed. - void RemoveDecorator(T decorator); + /// + /// Removes an from the . + /// + /// The to be removed. + void RemoveDecorator(T decorator); - /// - /// Removes all from the . - /// - void RemoveAllDecorators(); - } -} + /// + /// Removes all from the . + /// + void RemoveAllDecorators(); +} \ No newline at end of file diff --git a/RGB.NET.Core/Decorators/IDecorator.cs b/RGB.NET.Core/Decorators/IDecorator.cs index 1e9acddc..0a77a0e4 100644 --- a/RGB.NET.Core/Decorators/IDecorator.cs +++ b/RGB.NET.Core/Decorators/IDecorator.cs @@ -1,39 +1,38 @@ -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a basic decorator. +/// +public interface IDecorator { + #region Properties & Fields + + /// + /// Gets or sets if the is enabled and will be used. + /// + bool IsEnabled { get; set; } + + /// + /// Gets or sets the order in which multiple decorators should be applied on the same object. + /// Higher orders are processed first. + /// + int Order { get; set; } + + #endregion + + #region Methods + /// - /// Represents a basic decorator. + /// Attaches this to the specified target. /// - public interface IDecorator - { - #region Properties & Fields - - /// - /// Gets or sets if the is enabled and will be used. - /// - bool IsEnabled { get; set; } - - /// - /// Gets or sets the order in which multiple decorators should be applied on the same object. - /// Higher orders are processed first. - /// - int Order { get; set; } - - #endregion - - #region Methods - - /// - /// Attaches this to the given target. - /// - /// The object this should be attached to. - void OnAttached(IDecoratable decoratable); - - /// - /// Detaches this from the given target. - /// - /// The object this should be detached from. - void OnDetached(IDecoratable decoratable); - - #endregion - } -} + /// The object this should be attached to. + void OnAttached(IDecoratable decoratable); + + /// + /// Detaches this from the specified target. + /// + /// The object this should be detached from. + void OnDetached(IDecoratable decoratable); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Decorators/ILedGroupDecorator.cs b/RGB.NET.Core/Decorators/ILedGroupDecorator.cs index e893de75..051ca9d8 100644 --- a/RGB.NET.Core/Decorators/ILedGroupDecorator.cs +++ b/RGB.NET.Core/Decorators/ILedGroupDecorator.cs @@ -1,9 +1,8 @@ -namespace RGB.NET.Core -{ - /// - /// - /// Represents a basic decorator decorating a . - /// - public interface ILedGroupDecorator : IDecorator - { } -} +namespace RGB.NET.Core; + +/// +/// +/// Represents a basic decorator decorating a . +/// +public interface ILedGroupDecorator : IDecorator +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/AbstractRGBDevice.cs b/RGB.NET.Core/Devices/AbstractRGBDevice.cs index a737f29c..1457e0a0 100644 --- a/RGB.NET.Core/Devices/AbstractRGBDevice.cs +++ b/RGB.NET.Core/Devices/AbstractRGBDevice.cs @@ -2,297 +2,237 @@ // ReSharper disable UnusedMember.Global // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -using System; using System.Collections; using System.Collections.Generic; -using System.IO; using System.Linq; -using RGB.NET.Core.Layout; -namespace RGB.NET.Core -{ - /// - /// - /// - /// Represents a generic RGB-device. - /// - public abstract class AbstractRGBDevice : AbstractBindable, IRGBDevice - where TDeviceInfo : class, IRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Core; - /// - public abstract TDeviceInfo DeviceInfo { get; } +/// +/// +/// +/// Represents a generic RGB-device. +/// +public abstract class AbstractRGBDevice : Placeable, IRGBDevice + where TDeviceInfo : class, IRGBDeviceInfo +{ + private RGBSurface? _surface; - /// - IRGBDeviceInfo IRGBDevice.DeviceInfo => DeviceInfo; + #region Properties & Fields - private Point _location = new Point(0, 0); - /// - public Point Location + RGBSurface? IRGBDevice.Surface + { + get => _surface; + set { - get => _location; - set + if (SetProperty(ref _surface, value)) { - if (SetProperty(ref _location, value)) - UpdateActualData(); + if (value == null) OnDetached(); + else OnAttached(); } } + } - private Size _size = Size.Invalid; - /// - public Size Size - { - get => _size; - protected set - { - if (SetProperty(ref _size, value)) - UpdateActualData(); - } - } + /// + public TDeviceInfo DeviceInfo { get; } - private Size _actualSize; - /// - public Size ActualSize - { - get => _actualSize; - private set => SetProperty(ref _actualSize, value); - } + /// + IRGBDeviceInfo IRGBDevice.DeviceInfo => DeviceInfo; - private Rectangle _deviceRectangle; - /// - public Rectangle DeviceRectangle - { - get => _deviceRectangle; - private set => SetProperty(ref _deviceRectangle, value); - } + /// + public IList ColorCorrections { get; } = new List(); - private Scale _scale = new Scale(1); - /// - public Scale Scale - { - get => _scale; - set - { - if (SetProperty(ref _scale, value)) - UpdateActualData(); - } - } - - private Rotation _rotation = new Rotation(0); - /// - public Rotation Rotation - { - get => _rotation; - set - { - if (SetProperty(ref _rotation, value)) - UpdateActualData(); - } - } + /// + /// Gets or sets if the device needs to be flushed on every update. + /// + protected bool RequiresFlush { get; set; } = false; - /// - /// Gets or sets if the device needs to be flushed on every update. - /// - protected bool RequiresFlush { get; set; } = false; + /// + /// Gets a dictionary containing all of the . + /// + protected Dictionary LedMapping { get; } = new(); - /// - public DeviceUpdateMode UpdateMode { get; set; } = DeviceUpdateMode.Sync; + /// + /// Gets the update queue used to update this device. + /// + protected IUpdateQueue UpdateQueue { get; } - /// - /// Gets a dictionary containing all of the . - /// - protected Dictionary LedMapping { get; } = new Dictionary(); + #region Indexer - /// - /// Gets a dictionary containing all associated with this . - /// - protected Dictionary SpecialDeviceParts { get; } = new Dictionary(); + /// + Led? IRGBDevice.this[LedId ledId] => LedMapping.TryGetValue(ledId, out Led? led) ? led : null; - #region Indexer + /// + Led? IRGBDevice.this[Point location] => LedMapping.Values.FirstOrDefault(x => x.Boundary.Contains(location)); - /// - Led IRGBDevice.this[LedId ledId] => LedMapping.TryGetValue(ledId, out Led led) ? led : null; + /// + IEnumerable IRGBDevice.this[Rectangle referenceRect, double minOverlayPercentage] + => LedMapping.Values.Where(x => referenceRect.CalculateIntersectPercentage(x.Boundary) >= minOverlayPercentage); - /// - Led IRGBDevice.this[Point location] => LedMapping.Values.FirstOrDefault(x => x.LedRectangle.Contains(location)); + #endregion - /// - IEnumerable IRGBDevice.this[Rectangle referenceRect, double minOverlayPercentage] - => LedMapping.Values.Where(x => referenceRect.CalculateIntersectPercentage(x.LedRectangle) >= minOverlayPercentage); + #endregion - #endregion + #region Constructors - #endregion + /// + /// Initializes a new instance of the class. + /// + /// The device info of this device. + /// The queue used to update this device. + protected AbstractRGBDevice(TDeviceInfo deviceInfo, IUpdateQueue updateQueue) + { + this.DeviceInfo = deviceInfo; + this.UpdateQueue = updateQueue; + } - #region Methods + #endregion - private void UpdateActualData() - { - ActualSize = Size * Scale; - DeviceRectangle = new Rectangle(Location, new Rectangle(new Rectangle(Location, ActualSize).Rotate(Rotation)).Size); - } + #region Methods - /// - public virtual void Update(bool flushLeds = false) - { - // Device-specific updates - DeviceUpdate(); + /// + public virtual void Update(bool flushLeds = false) + { + // Device-specific updates + DeviceUpdate(); - // Send LEDs to SDK - List ledsToUpdate = GetLedsToUpdate(flushLeds)?.ToList() ?? new List(); - foreach (Led ledToUpdate in ledsToUpdate) - ledToUpdate.Update(); + // Send LEDs to SDK + List ledsToUpdate = GetLedsToUpdate(flushLeds).ToList(); - if (UpdateMode.HasFlag(DeviceUpdateMode.Sync)) - UpdateLeds(ledsToUpdate); - } + foreach (Led led in ledsToUpdate) + led.Update(); - protected virtual IEnumerable GetLedsToUpdate(bool flushLeds) => ((RequiresFlush || flushLeds) ? LedMapping.Values : LedMapping.Values.Where(x => x.IsDirty)); + UpdateLeds(ledsToUpdate); + } - /// - public virtual void SyncBack() - { } + /// + /// Gets an enumerable of LEDs that are changed and requires an update. + /// + /// Forces all LEDs to be treated as dirty. + /// The collection LEDs to update. + protected virtual IEnumerable GetLedsToUpdate(bool flushLeds) => ((RequiresFlush || flushLeds) ? LedMapping.Values : LedMapping.Values.Where(x => x.IsDirty)).Where(led => led.RequestedColor?.A > 0); - /// - public virtual void Dispose() + /// + /// Gets an enumerable of a custom data and color tuple for the specified leds. + /// + /// + /// Applies all . + /// if no ist specified the is used. + /// + /// The enumerable of leds to convert. + /// The enumerable of custom data and color tuples for the specified leds. + protected virtual IEnumerable<(object key, Color color)> GetUpdateData(IEnumerable leds) + { + if (ColorCorrections.Count > 0) { - try + foreach (Led led in leds) { - SpecialDeviceParts.Clear(); - LedMapping.Clear(); + Color color = led.Color; + object key = led.CustomData ?? led.Id; + + foreach (IColorCorrection colorCorrection in ColorCorrections) + colorCorrection.ApplyTo(ref color); + + yield return (key, color); } - catch { /* this really shouldn't happen */ } } - - /// - /// Performs device specific updates. - /// - protected virtual void DeviceUpdate() - { } - - /// - /// Sends all the updated to the device. - /// - protected abstract void UpdateLeds(IEnumerable ledsToUpdate); - - /// - /// Initializes the with the specified id. - /// - /// The to initialize. - /// The representing the position of the to initialize. - /// - [Obsolete("Use InitializeLed(LedId ledId, Point location, Size size) instead.")] - protected virtual Led InitializeLed(LedId ledId, Rectangle rectangle) => InitializeLed(ledId, rectangle.Location, rectangle.Size); - - /// - /// Initializes the with the specified id. - /// - /// The to initialize. - /// The location of the to initialize. - /// The size of the to initialize. - /// The initialized led. - protected virtual Led InitializeLed(LedId ledId, Point location, Size size) + else { - if ((ledId == LedId.Invalid) || LedMapping.ContainsKey(ledId)) return null; + foreach (Led led in leds) + { + Color color = led.Color; + object key = led.CustomData ?? led.Id; - Led led = new Led(this, ledId, location, size, CreateLedCustomData(ledId)); - LedMapping.Add(ledId, led); - return led; + yield return (key, color); + } } + } - /// - /// Applies the give to the ignoring internal workflows regarding locks and update-requests. - /// This should be only used for syncbacks! - /// - /// The the should be aplied to. - /// The to apply. - protected virtual void SetLedColorWithoutRequest(Led led, Color color) - { - if (led == null) return; + /// + /// Sends all the updated to the device. + /// + protected virtual void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - led.InternalColor = color; - } + /// + public virtual void Dispose() + { + try { UpdateQueue.Dispose(); } catch { /* :( */ } + try { LedMapping.Clear(); } catch { /* this really shouldn't happen */ } - /// - /// Applies the given layout. - /// - /// The file containing the layout. - /// The name of the layout used to get the images of the leds. - /// If set to true a new led is initialized for every id in the layout if it doesn't already exist. - protected virtual DeviceLayout ApplyLayoutFromFile(string layoutPath, string imageLayout, bool createMissingLeds = false) - { - DeviceLayout layout = DeviceLayout.Load(layoutPath); - if (layout != null) - { - string imageBasePath = string.IsNullOrWhiteSpace(layout.ImageBasePath) ? null : PathHelper.GetAbsolutePath(this, layout.ImageBasePath); - if ((imageBasePath != null) && !string.IsNullOrWhiteSpace(layout.DeviceImage) && (DeviceInfo != null)) - DeviceInfo.Image = new Uri(Path.Combine(imageBasePath, layout.DeviceImage), UriKind.Absolute); - - LedImageLayout ledImageLayout = layout.LedImageLayouts.FirstOrDefault(x => string.Equals(x.Layout, imageLayout, StringComparison.OrdinalIgnoreCase)); - - Size = new Size(layout.Width, layout.Height); - - if (layout.Leds != null) - foreach (LedLayout layoutLed in layout.Leds) - { - if (Enum.TryParse(layoutLed.Id, true, out LedId ledId)) - { - if (!LedMapping.TryGetValue(ledId, out Led led) && createMissingLeds) - led = InitializeLed(ledId, new Point(), new Size()); - - if (led != null) - { - led.Location = new Point(layoutLed.X, layoutLed.Y); - led.Size = new Size(layoutLed.Width, layoutLed.Height); - led.Shape = layoutLed.Shape; - led.ShapeData = layoutLed.ShapeData; - - LedImage image = ledImageLayout?.LedImages.FirstOrDefault(x => x.Id == layoutLed.Id); - if ((imageBasePath != null) && !string.IsNullOrEmpty(image?.Image)) - led.Image = new Uri(Path.Combine(imageBasePath, image.Image), UriKind.Absolute); - } - } - } - } + IdGenerator.ResetCounter(GetType().Assembly); + } - return layout; - } + /// + /// Performs device specific updates. + /// + protected virtual void DeviceUpdate() + { } + + /// + public virtual Led? AddLed(LedId ledId, in Point location, in Size size, object? customData = null) + { + if ((ledId == LedId.Invalid) || LedMapping.ContainsKey(ledId)) return null; + + Led led = new(this, ledId, location, size, customData ?? GetLedCustomData(ledId)); + LedMapping.Add(ledId, led); + return led; + } + + /// + public virtual Led? RemoveLed(LedId ledId) + { + if (ledId == LedId.Invalid) return null; + if (!LedMapping.TryGetValue(ledId, out Led? led)) return null; - /// - /// Creates provider-specific data associated with this . - /// - /// The . - protected virtual object CreateLedCustomData(LedId ledId) => null; - - /// - public void AddSpecialDevicePart(T specialDevicePart) - where T : class, IRGBDeviceSpecialPart - => SpecialDeviceParts[typeof(T)] = specialDevicePart; - - /// - public T GetSpecialDevicePart() - where T : class, IRGBDeviceSpecialPart - => SpecialDeviceParts.TryGetValue(typeof(T), out IRGBDeviceSpecialPart devicePart) ? (T)devicePart : default; - - #region Enumerator - - /// - /// - /// Returns an enumerator that iterates over all of the . - /// - /// An enumerator for all of the . - public IEnumerator GetEnumerator() => LedMapping.Values.GetEnumerator(); - - /// - /// - /// Returns an enumerator that iterates over all of the . - /// - /// An enumerator for all of the . - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - #endregion - - #endregion + LedMapping.Remove(ledId); + return led; } -} + + /// + /// Gets the custom data associated with the specified LED. + /// + /// The id of the led. + /// The custom data for the specified LED. + protected virtual object? GetLedCustomData(LedId ledId) => null; + + /// + /// Called when the device is attached to a surface. + /// + /// + /// When overriden base should be called to validate boundries. + /// + protected virtual void OnAttached() + { + if (Location == Point.Invalid) Location = new Point(0, 0); + if (Size == Size.Invalid) + { + Rectangle ledRectangle = new(this.Select(x => x.Boundary)); + Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); + } + } + + /// + /// Called when the device is detached from a surface. + /// + protected virtual void OnDetached() { } + + #region Enumerator + + /// + /// + /// Returns an enumerator that iterates over all of the . + /// + /// An enumerator for all of the . + public IEnumerator GetEnumerator() => LedMapping.Values.GetEnumerator(); + + /// + /// + /// Returns an enumerator that iterates over all of the . + /// + /// An enumerator for all of the . + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + #endregion + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs new file mode 100644 index 00000000..ae66ca00 --- /dev/null +++ b/RGB.NET.Core/Devices/AbstractRGBDeviceProvider.cs @@ -0,0 +1,205 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace RGB.NET.Core; + +/// +/// Represents the abstract base implementation for a . +/// +public abstract class AbstractRGBDeviceProvider : IRGBDeviceProvider +{ + #region Properties & Fields + + private readonly double _defaultUpdateRateHardLimit; + + /// + public bool IsInitialized { get; protected set; } + + /// + public bool ThrowsExceptions { get; protected set; } + + /// + public virtual IEnumerable Devices { get; protected set; } = Enumerable.Empty(); + + /// + /// Gets the dictionary containing the registered update triggers. + /// Normally should be used to access them. + /// + protected Dictionary UpdateTriggerMapping { get; } = new(); + + /// + public IReadOnlyList<(int id, IDeviceUpdateTrigger trigger)> UpdateTriggers => new ReadOnlyCollection<(int id, IDeviceUpdateTrigger trigger)>(UpdateTriggerMapping.Select(x => (x.Key, x.Value)).ToList()); + + #endregion + + #region Events + + /// + public event EventHandler? Exception; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The update rate hard limit all update triggers for this device provider are initialized with. + protected AbstractRGBDeviceProvider(double defaultUpdateRateHardLimit = 0) + { + this._defaultUpdateRateHardLimit = defaultUpdateRateHardLimit; + } + + #endregion + + #region Methods + + /// + public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + { + ThrowsExceptions = throwExceptions; + + try + { + Reset(); + + InitializeSDK(); + + Devices = new ReadOnlyCollection(GetLoadedDevices(loadFilter).ToList()); + + foreach (IDeviceUpdateTrigger updateTrigger in UpdateTriggerMapping.Values) + updateTrigger.Start(); + + IsInitialized = true; + } + catch (DeviceProviderException) + { + Reset(); + throw; + } + catch (Exception ex) + { + Reset(); + Throw(ex, true); + return false; + } + + return true; + } + + /// + /// Loads devices and returns a filtered list of them. + /// + /// + /// The underlying loading of the devices happens in . + /// + /// -flags to filter the device with. + /// The filtered collection of loaded devices. + protected virtual IEnumerable GetLoadedDevices(RGBDeviceType loadFilter) + { + List devices = new(); + foreach (IRGBDevice device in LoadDevices()) + { + try + { + if (loadFilter.HasFlag(device.DeviceInfo.DeviceType)) + devices.Add(device); + else + device.Dispose(); + } + catch (Exception ex) + { + Throw(ex); + } + } + + return devices; + } + + /// + /// Initializes the underlying SDK. + /// + protected abstract void InitializeSDK(); + + /// + /// Loads all devices this device provider is capable of loading. + /// + /// + /// Filtering happens in . + /// + /// A collection of loaded devices. + protected abstract IEnumerable LoadDevices(); + + /// + /// Gets the mapped to the specified id or a new one if the id wasn't requested before. + /// + /// + /// The creation of the update trigger happens in . + /// + /// The id of the update trigger. + /// The update rate hard limit to be set in the update trigger. + /// The update trigger mapped to the specified id. + protected virtual IDeviceUpdateTrigger GetUpdateTrigger(int id = -1, double? updateRateHardLimit = null) + { + if (!UpdateTriggerMapping.TryGetValue(id, out IDeviceUpdateTrigger? updaeTrigger)) + UpdateTriggerMapping[id] = (updaeTrigger = CreateUpdateTrigger(id, updateRateHardLimit ?? _defaultUpdateRateHardLimit)); + + return updaeTrigger; + } + + /// + /// Creates a update trigger with the specified id and the specified update rate hard limit. + /// + /// The id of the update trigger. + /// The update rate hard limit tobe set in the update trigger. + /// The newly created update trigger. + protected virtual IDeviceUpdateTrigger CreateUpdateTrigger(int id, double updateRateHardLimit) => new DeviceUpdateTrigger(updateRateHardLimit); + + /// + /// Resets the device provider and disposes all devices and update triggers. + /// + protected virtual void Reset() + { + foreach (IDeviceUpdateTrigger updateTrigger in UpdateTriggerMapping.Values) + updateTrigger.Dispose(); + + foreach (IRGBDevice device in Devices) + device.Dispose(); + + Devices = Enumerable.Empty(); + UpdateTriggerMapping.Clear(); + IsInitialized = false; + } + + /// + /// Triggers the -event and throws the specified exception if is true and it is not overriden in the event. + /// + /// The exception to throw. + /// Indicates if the exception is critical for device provider to work correctly. + protected virtual void Throw(Exception ex, bool isCritical = false) + { + ExceptionEventArgs args = new(ex, isCritical, ThrowsExceptions); + try { OnException(args); } catch { /* we don't want to throw due to bad event handlers */ } + + if (args.Throw) + throw new DeviceProviderException(ex, isCritical); + } + + /// + /// Throws the event. + /// + /// The parameters passed to the event. + protected virtual void OnException(ExceptionEventArgs args) => Exception?.Invoke(this, args); + + /// + public virtual void Dispose() + { + Reset(); + + GC.SuppressFinalize(this); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Devices/DeviceUpdateMode.cs b/RGB.NET.Core/Devices/DeviceUpdateMode.cs deleted file mode 100644 index b6e27d9d..00000000 --- a/RGB.NET.Core/Devices/DeviceUpdateMode.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; - -namespace RGB.NET.Core -{ - /// - /// Contains a list of different device device update modes. - /// - [Flags] - public enum DeviceUpdateMode - { - /// - /// Represents nothing. - /// - None = 0, - - /// - /// Represents a mode which updates the leds of the device. - /// - Sync = 1 << 0, - - /// - /// Represents a mode which reads the color of the leds of the device. - /// This isn't supported by all devices! - /// - SyncBack = 1 << 1, - - /// - /// Represents all update modes. - /// - NoUpdate = 1 << 0xFF - } -} diff --git a/RGB.NET.Core/Devices/IRGBDevice.cs b/RGB.NET.Core/Devices/IRGBDevice.cs index 23278ba3..6e79fb3f 100644 --- a/RGB.NET.Core/Devices/IRGBDevice.cs +++ b/RGB.NET.Core/Devices/IRGBDevice.cs @@ -1,129 +1,98 @@ using System; using System.Collections.Generic; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// +/// +/// Represents a generic RGB-device. +/// +public interface IRGBDevice : IEnumerable, IPlaceable, IBindable, IDisposable { - /// - /// - /// + #region Properties + + /// + /// Gets the surface this device is attached to. + /// + RGBSurface? Surface { get; internal set; } + + /// + /// Gets generic information about the . + /// + IRGBDeviceInfo DeviceInfo { get; } + + /// + /// Gets a list of color corrections applied to this device. + /// + IList ColorCorrections { get; } + + #endregion + + #region Indexer + + /// + /// Gets the with the specified . + /// + /// The of the to get. + /// The with the specified or null if no is found. + Led? this[LedId ledId] { get; } + + /// + /// Gets the at the specified physical location. + /// + /// The to get the location from. + /// The at the specified or null if no location is found. + Led? this[Point location] { get; } + + /// + /// Gets a list of inside the specified . + /// + /// The to check. + /// The minimal percentage overlay a must have with the to be taken into the list. + /// A enumerable of leds inside the specified rectangle. + IEnumerable this[Rectangle referenceRect, double minOverlayPercentage = 0.5] { get; } + + #endregion + + #region Methods + + /// + /// Perform an update for all dirty , or all if flushLeds is set to true. + /// + /// Specifies whether all (including clean ones) should be updated. + void Update(bool flushLeds = false); + /// - /// Represents a generic RGB-device. + /// Adds a led to the device. /// - public interface IRGBDevice : IEnumerable, IBindable, IDisposable - { - #region Properties - - /// - /// Gets generic information about the . - /// - IRGBDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the location of the . - /// - Point Location { get; set; } - - /// - /// Gets the of the . - /// - Size Size { get; } - - /// - /// Gets the actual of the . - /// This includes the . - /// - Size ActualSize { get; } - - /// - /// Gets a representing the logical location of the relative to the . - /// - Rectangle DeviceRectangle { get; } - - /// - /// Gets or sets the scale of the . - /// - Scale Scale { get; set; } - - /// - /// Gets or sets the rotation of the . - /// - Rotation Rotation { get; set; } - - /// - /// Gets or sets the of the . - /// - DeviceUpdateMode UpdateMode { get; set; } - - #endregion - - #region Indexer - - /// - /// Gets the with the specified . - /// - /// The of the to get. - /// The with the specified or null if no is found. - Led this[LedId ledId] { get; } - - /// - /// Gets the at the given physical location. - /// - /// The to get the location from. - /// The at the given or null if no location is found. - Led this[Point location] { get; } - - /// - /// Gets a list of inside the given . - /// - /// The to check. - /// The minimal percentage overlay a must have with the to be taken into the list. - /// - IEnumerable this[Rectangle referenceRect, double minOverlayPercentage = 0.5] { get; } - - #endregion - - #region Methods - - /// - /// Perform an update for all dirty , or all if flushLeds is set to true. - /// - /// Specifies whether all (including clean ones) should be updated. - void Update(bool flushLeds = false); - - /// - /// Synchronizes the internal state of the device to the real (physical) state. - /// This isn't supported by all devices! Check to see if it's supported or not. - /// - void SyncBack(); - - /// - /// Adds the given to the device. - /// This will override existing of the same type. - /// - /// The to add. - /// The generic typeof of the to add. - void AddSpecialDevicePart(T specialDevicePart) where T : class, IRGBDeviceSpecialPart; - - /// - /// Gets the requested if available on this . - /// - /// The generic type of the requested . - /// The requested or null if not available in this . - T GetSpecialDevicePart() where T : class, IRGBDeviceSpecialPart; - - #endregion - } - - /// + /// The id of the led. + /// The location of the led on the device. + /// The size of the led. + /// Custom data saved on the led. + /// The newly added led or null if a led with this id is already added. + Led? AddLed(LedId ledId, in Point location, in Size size, object? customData = null); + /// - /// Represents a generic RGB-device with an known device-info type. + /// Removes the led with the specified id from the device. /// - public interface IRGBDevice : IRGBDevice - where TDeviceInfo : IRGBDeviceInfo - { - /// - /// Gets generic information about the . - /// - new TDeviceInfo DeviceInfo { get; } - } + /// The id of the led to remove. + /// The removed led or null if there was no led with the specified id. + Led? RemoveLed(LedId ledId); + + #endregion } + +/// +/// +/// Represents a generic RGB-device with an known device-info type. +/// +public interface IRGBDevice : IRGBDevice + where TDeviceInfo : IRGBDeviceInfo +{ + /// + /// Gets generic information about the . + /// + new TDeviceInfo DeviceInfo { get; } +} \ No newline at end of file diff --git a/RGB.NET.Core/Devices/IRGBDeviceInfo.cs b/RGB.NET.Core/Devices/IRGBDeviceInfo.cs index 68bb9dc0..f255eb8d 100644 --- a/RGB.NET.Core/Devices/IRGBDeviceInfo.cs +++ b/RGB.NET.Core/Devices/IRGBDeviceInfo.cs @@ -1,49 +1,36 @@ -using System; +namespace RGB.NET.Core; -namespace RGB.NET.Core +/// +/// Represents a generic information for a +/// +public interface IRGBDeviceInfo { + #region Properties & Fields + /// - /// Represents a generic information for a + /// Gets the of the . /// - public interface IRGBDeviceInfo - { - #region Properties & Fields - - /// - /// Gets the of the . - /// - RGBDeviceType DeviceType { get; } - - /// - /// Unique name of the . - /// - string DeviceName { get; } + RGBDeviceType DeviceType { get; } - /// - /// Gets the manufacturer-name of the . - /// - string Manufacturer { get; } - - /// - /// Gets the model-name of the . - /// - string Model { get; } + /// + /// Unique name of the . + /// + string DeviceName { get; } - /// - /// Gets the lighting capability of the - /// - RGBDeviceLighting Lighting { get; } + /// + /// Gets the manufacturer-name of the . + /// + string Manufacturer { get; } - /// - /// Gets a bool indicating, if the supports SynBacks or not. - /// - bool SupportsSyncBack { get; } + /// + /// Gets the model-name of the . + /// + string Model { get; } - /// - /// Gets the URI of an image of the or null if there is no image. - /// - Uri Image { get; set; } + /// + /// Gets custom metadata added to the layout. + /// + object? LayoutMetadata { get; set; } - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs index dca3645c..48edc4d2 100644 --- a/RGB.NET.Core/Devices/IRGBDeviceProvider.cs +++ b/RGB.NET.Core/Devices/IRGBDeviceProvider.cs @@ -1,48 +1,57 @@ -using System; +// ReSharper disable EventNeverSubscribedTo.Global + +using System; using System.Collections.Generic; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a generic device provider. +/// +public interface IRGBDeviceProvider : IDisposable { + #region Properties & Fields + + /// + /// Indicates if the used SDK is initialized and ready to use. + /// + bool IsInitialized { get; } + + /// + /// Indicates if exceptions in the device provider are thrown or silently ignored. + /// + bool ThrowsExceptions { get; } + + /// + /// Gets a collection of loaded by this . + /// + IEnumerable Devices { get; } + /// - /// Represents a generic device provider. + /// Gets a collection registered to this device provider. /// - public interface IRGBDeviceProvider : IDisposable - { - #region Properties & Fields - - /// - /// Indicates if the used SDK is initialized and ready to use. - /// - bool IsInitialized { get; } - - /// - /// Gets a list of loaded by this . - /// - IEnumerable Devices { get; } - - /// - /// Gets whether the application has exclusive access to devices or not. - /// - bool HasExclusiveAccess { get; } - - #endregion - - #region Methods - - /// - /// Initializes the if not already happened or reloads it if it is already initialized. - /// - /// Specifies which types of devices to load. - /// Specifies whether the application should request exclusive access of possible or not. - /// Specifies whether exception during the initialization sequence should be thrown or not. - /// - bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false); - - /// - /// Resets all handled back top default. - /// - void ResetDevices(); - - #endregion - } -} + IReadOnlyList<(int id, IDeviceUpdateTrigger trigger)> UpdateTriggers { get; } + + #endregion + + #region Events + + /// + /// Occurs when an exception is thrown in the device provider. + /// + event EventHandler? Exception; + + #endregion + + #region Methods + + /// + /// Initializes the device provider and loads available devices. + /// + /// -flags to filter the devices to load. + /// Specifies if exceptions should be thrown or silently be ignored. + /// true if the initialization was successful; false otherwise. + bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Devices/IRGBDeviceProviderLoader.cs b/RGB.NET.Core/Devices/IRGBDeviceProviderLoader.cs deleted file mode 100644 index 14a60cb2..00000000 --- a/RGB.NET.Core/Devices/IRGBDeviceProviderLoader.cs +++ /dev/null @@ -1,20 +0,0 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a generic device provider loaded used to dynamically load devices into an application. - /// This class should always provide an empty public constructor! - /// - public interface IRGBDeviceProviderLoader - { - /// - /// Indicates if the returned device-provider needs some specific initialization before use. - /// - bool RequiresInitialization { get; } - - /// - /// Gets the device-provider. - /// - /// The device-provider. - IRGBDeviceProvider GetDeviceProvider(); - } -} diff --git a/RGB.NET.Core/Devices/IRGBDeviceSpecialPart.cs b/RGB.NET.Core/Devices/IRGBDeviceSpecialPart.cs deleted file mode 100644 index 58c4e370..00000000 --- a/RGB.NET.Core/Devices/IRGBDeviceSpecialPart.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Collections.Generic; - -namespace RGB.NET.Core -{ - /// - /// - /// Represents a special part of a . - /// - public interface IRGBDeviceSpecialPart : IEnumerable - { } -} diff --git a/RGB.NET.Core/Devices/KeyboardLayoutType.cs b/RGB.NET.Core/Devices/KeyboardLayoutType.cs new file mode 100644 index 00000000..fedeaf05 --- /dev/null +++ b/RGB.NET.Core/Devices/KeyboardLayoutType.cs @@ -0,0 +1,17 @@ +// ReSharper disable InconsistentNaming +#pragma warning disable 1591 + +namespace RGB.NET.Core; + +/// +/// Contains a list of available keyboard layout types. +/// +public enum KeyboardLayoutType +{ + Unknown = 0, + ANSI = 1, + ISO = 2, + JIS = 3, + ABNT = 4, + KS = 5 +} \ No newline at end of file diff --git a/RGB.NET.Core/Devices/Layout/DeviceLayout.cs b/RGB.NET.Core/Devices/Layout/DeviceLayout.cs deleted file mode 100644 index 267c7d0f..00000000 --- a/RGB.NET.Core/Devices/Layout/DeviceLayout.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Xml.Serialization; - -namespace RGB.NET.Core.Layout -{ - /// - /// Represents the serializable layout of a . - /// - [Serializable] - [XmlRoot("Device")] - public class DeviceLayout - { - #region Properties & Fields - - /// - /// Gets or sets the name of the . - /// - [XmlElement("Name")] - public string Name { get; set; } - - /// - /// Gets or sets the description of the . - /// - [XmlElement("Description")] - public string Description { get; set; } - - /// - /// Gets or sets the of the . - /// - [XmlElement("Type")] - public RGBDeviceType Type { get; set; } - - /// - /// Gets or sets the of the . - /// - [XmlElement("Lighting")] - public RGBDeviceLighting Lighting { get; set; } - - /// - /// Gets or sets the vendor of the . - /// - [XmlElement("Vendor")] - public string Vendor { get; set; } - - /// - /// Gets or sets the model of the . - /// - [XmlElement("Model")] - public string Model { get; set; } - - /// - /// Gets or sets the of the . - /// - [XmlElement("Shape")] - [DefaultValue(Shape.Rectangle)] - public Shape Shape { get; set; } = Shape.Rectangle; - - /// - /// Gets or sets the width of the . - /// - [XmlElement("Width")] - public double Width { get; set; } - - /// - /// Gets or sets the height of the . - /// - [XmlElement("Height")] - public double Height { get; set; } - - /// - /// Gets or sets the width of one 'unit' used for the calculation of led positions and sizes. - /// - [XmlElement("LedUnitWidth")] - [DefaultValue(19.0)] - public double LedUnitWidth { get; set; } = 19.0; - - /// - /// Gets or sets the height of one 'unit' used for the calculation of led positions and sizes. - /// - [XmlElement("LedUnitHeight")] - [DefaultValue(19.0)] - public double LedUnitHeight { get; set; } = 19.0; - - /// - /// The path images for this device are collected in. - /// - [XmlElement("ImageBasePath")] - public string ImageBasePath { get; set; } - - /// - /// The image file for this device. - /// - [XmlElement("DeviceImage")] - public string DeviceImage { get; set; } - - /// - /// Gets or sets a list of representing all the of the . - /// - [XmlArray("Leds")] - public List Leds { get; set; } = new List(); - - /// - /// Gets or sets a list of representing the layouts for the images of all the of the . - /// - [XmlArray("LedImageLayouts")] - public List LedImageLayouts { get; set; } = new List(); - - #endregion - - #region Methods - - /// - /// Creates a new from the given xml. - /// - /// The path to the xml file. - /// The deserialized . - public static DeviceLayout Load(string path) - { - if (!File.Exists(path)) return null; - - try - { - XmlSerializer serializer = new XmlSerializer(typeof(DeviceLayout)); - using (StreamReader reader = new StreamReader(path)) - { - DeviceLayout layout = serializer.Deserialize(reader) as DeviceLayout; - if (layout?.Leds != null) - { - LedLayout lastLed = null; - foreach (LedLayout led in layout.Leds) - { - led.CalculateValues(layout, lastLed); - lastLed = led; - } - } - - return layout; - } - } - catch - { - return null; - } - } - - #endregion - } -} diff --git a/RGB.NET.Core/Devices/Layout/LedImage.cs b/RGB.NET.Core/Devices/Layout/LedImage.cs deleted file mode 100644 index c76d95ac..00000000 --- a/RGB.NET.Core/Devices/Layout/LedImage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Xml.Serialization; - -namespace RGB.NET.Core.Layout -{ - /// - /// Represents the serializable image-data of a specific . - /// - [Serializable] - [XmlRoot("LedImage")] - public class LedImage - { - /// - /// Gets or sets the Id of the . - /// - [XmlAttribute("Id")] - public string Id { get; set; } - - /// - /// Gets or sets the image of the . - /// - [XmlAttribute("Image")] - public string Image { get; set; } - } -} diff --git a/RGB.NET.Core/Devices/Layout/LedImageLayout.cs b/RGB.NET.Core/Devices/Layout/LedImageLayout.cs deleted file mode 100644 index 2c3a4914..00000000 --- a/RGB.NET.Core/Devices/Layout/LedImageLayout.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Xml.Serialization; - -namespace RGB.NET.Core.Layout -{ - /// - /// Represents the serializable collection of for a specific layout. - /// - [Serializable] - [XmlRoot("LedImageLayout")] - public class LedImageLayout - { - /// - /// Gets or sets the layout of the . - /// - [XmlAttribute("Layout")] - [DefaultValue(null)] - public string Layout { get; set; } - - /// - /// Gets or sets a list of representing the images of all the of the represented layout. - /// - [XmlArray("LedImages")] - public List LedImages { get; set; } = new List(); - } -} diff --git a/RGB.NET.Core/Devices/Layout/LedLayout.cs b/RGB.NET.Core/Devices/Layout/LedLayout.cs deleted file mode 100644 index c382520e..00000000 --- a/RGB.NET.Core/Devices/Layout/LedLayout.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.ComponentModel; -using System.Globalization; -using System.Xml.Serialization; - -namespace RGB.NET.Core.Layout -{ - /// - /// Represents the serializable layout of a . - /// - [Serializable] - [XmlType("Led")] - public class LedLayout - { - #region Properties & Fields - - /// - /// Gets or sets the Id of the . - /// - [XmlAttribute("Id")] - public string Id { get; set; } - - /// - /// Gets or sets the descriptive of the . - /// This property is for XML-serialization only and should not be directly accessed. - /// - [XmlElement("Shape")] - [DefaultValue("Rectangle")] - public string DescriptiveShape { get; set; } = "Rectangle"; - - /// - /// Gets or sets the descriptive x-position of the . - /// This property is for XML-serialization only and should not be directly accessed. - /// - [XmlElement("X")] - [DefaultValue("+")] - public string DescriptiveX { get; set; } = "+"; - - /// - /// Gets or sets the descriptive y-position of the . - /// This property is for XML-serialization only and should not be directly accessed. - /// - [XmlElement("Y")] - [DefaultValue("=")] - public string DescriptiveY { get; set; } = "="; - - /// - /// Gets or sets the descriptive width of the . - /// This property is for XML-serialization only and should not be directly accessed. - /// - [XmlElement("Width")] - [DefaultValue("1.0")] - public string DescriptiveWidth { get; set; } = "1.0"; - - /// - /// Gets or sets the descriptive height of the . - /// This property is for XML-serialization only and should not be directly accessed. - /// - [XmlElement("Height")] - [DefaultValue("1.0")] - public string DescriptiveHeight { get; set; } = "1.0"; - - /// - /// Gets or sets the of the . - /// - [XmlIgnore] - public Shape Shape { get; set; } - - /// - /// Gets or sets the vecor-data representing a custom-shape of the . - /// - [XmlIgnore] - public string ShapeData { get; set; } - - /// - /// Gets or sets the x-position of the . - /// - [XmlIgnore] - public double X { get; private set; } - - /// - /// Gets or sets the y-position of the . - /// - [XmlIgnore] - public double Y { get; private set; } - - /// - /// Gets or sets the width of the . - /// - [XmlIgnore] - public double Width { get; private set; } - - /// - /// Gets or sets the height of the . - /// - [XmlIgnore] - public double Height { get; private set; } - - #endregion - - #region Methods - - /// - /// Calculates the position- and size-data from the respective descriptive values. - /// - /// The this belongs to. - /// The previously calculated. - public void CalculateValues(DeviceLayout device, LedLayout lastLed) - { - if (!Enum.TryParse(DescriptiveShape, true, out Shape shape)) - { - shape = Shape.Custom; - ShapeData = DescriptiveShape; - } - Shape = shape; - - Width = GetSizeValue(DescriptiveWidth, device.LedUnitWidth); - Height = GetSizeValue(DescriptiveHeight, device.LedUnitHeight); - - X = GetLocationValue(DescriptiveX, lastLed?.X ?? 0, Width, lastLed?.Width ?? 0); - Y = GetLocationValue(DescriptiveY, lastLed?.Y ?? 0, Height, lastLed?.Height ?? 0); - } - - private double GetLocationValue(string value, double lastValue, double currentSize, double lastSize) - { - try - { - if (string.IsNullOrWhiteSpace(value)) return 0; - - value = value.Replace(" ", string.Empty); - - if (string.Equals(value, "=", StringComparison.Ordinal)) - return lastValue; - - if (string.Equals(value, "+", StringComparison.Ordinal)) - return lastValue + lastSize; - - if (value.StartsWith("+", StringComparison.Ordinal)) - return lastValue + lastSize + double.Parse(value.Substring(1), CultureInfo.InvariantCulture); - - if (string.Equals(value, "-", StringComparison.Ordinal)) - return lastValue - currentSize; - - if (value.StartsWith("-", StringComparison.Ordinal)) - return lastValue - currentSize - double.Parse(value.Substring(1), CultureInfo.InvariantCulture); - - if (string.Equals(value, "~", StringComparison.Ordinal)) - return (lastValue + lastSize) - currentSize; - - if (value.StartsWith("~", StringComparison.Ordinal)) - return (lastValue + lastSize) - currentSize - double.Parse(value.Substring(1), CultureInfo.InvariantCulture); - - return double.Parse(value, CultureInfo.InvariantCulture); - } - catch - { - return 0; - } - } - - private double GetSizeValue(string value, double unitSize) - { - try - { - if (string.IsNullOrWhiteSpace(value)) return 0; - - value = value.Replace(" ", string.Empty); - - if (value.EndsWith("mm", StringComparison.OrdinalIgnoreCase)) - return double.Parse(value.Substring(0, value.Length - 2), CultureInfo.InvariantCulture); - - return unitSize * double.Parse(value, CultureInfo.InvariantCulture); - } - catch - { - return 0; - } - } - - #endregion - } -} diff --git a/RGB.NET.Core/Devices/RGBDeviceLighting.cs b/RGB.NET.Core/Devices/RGBDeviceLighting.cs deleted file mode 100644 index 70a0607d..00000000 --- a/RGB.NET.Core/Devices/RGBDeviceLighting.cs +++ /dev/null @@ -1,25 +0,0 @@ -using RGB.NET.Core.Layout; - -namespace RGB.NET.Core -{ - /// - /// Contains a list of different lightning-modes used by . - /// - public enum RGBDeviceLighting - { - /// - /// The doesn't support lighting, - /// - None = 0, - - /// - /// The supports per-key-lightning. - /// - Key = 1, - - /// - /// The supports per-device-lightning. - /// - Device = 2, - } -} diff --git a/RGB.NET.Core/Devices/RGBDeviceType.cs b/RGB.NET.Core/Devices/RGBDeviceType.cs index b0de5e37..88e4f822 100644 --- a/RGB.NET.Core/Devices/RGBDeviceType.cs +++ b/RGB.NET.Core/Devices/RGBDeviceType.cs @@ -1,96 +1,105 @@ using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Contains a list of different types of device. +/// +[Flags] +public enum RGBDeviceType { /// - /// Contains a list of different types of device. - /// - [Flags] - public enum RGBDeviceType - { - /// - /// Represents nothing. - /// - None = 0, - - /// - /// Represents a keyboard. - /// - Keyboard = 1 << 0, - - /// - /// Represents a mouse. - /// - Mouse = 1 << 1, - - /// - /// Represents a headset. - /// - Headset = 1 << 2, - - /// - /// Represents a mousepad. - /// - Mousepad = 1 << 3, - - /// - /// Represents a LED-stipe. - /// - LedStripe = 1 << 4, - - /// - /// Represents a LED-matrix. - /// - LedMatrix = 1 << 5, - - /// - /// Represents a Mainboard. - /// - Mainboard = 1 << 6, - - /// - /// Represents a Graphics card. - /// - GraphicsCard = 1 << 7, - - /// - /// Represents a DRAM-bank. - /// - DRAM = 1 << 8, - - /// - /// Represents a headset stand. - /// - HeadsetStand = 1 << 9, - - /// - /// Represents a keypad. - /// - Keypad = 1 << 10, - - /// - /// Represents a fan. - /// - Fan = 1 << 11, - - /// - /// Represents a speaker - /// - Speaker = 1 << 12, - - /// - /// Represents a cooler. - /// - Cooler = 1 << 13, - - /// - /// Represents a device where the type is not known or not present in the list. - /// - Unknown = 1 << 31, - - /// - /// Represents all devices. - /// - All = ~None - } -} + /// Represents nothing. + /// + None = 0, + + /// + /// Represents a keyboard. + /// + Keyboard = 1 << 0, + + /// + /// Represents a mouse. + /// + Mouse = 1 << 1, + + /// + /// Represents a headset. + /// + Headset = 1 << 2, + + /// + /// Represents a mousepad. + /// + Mousepad = 1 << 3, + + /// + /// Represents a LED-stipe. + /// + LedStripe = 1 << 4, + + /// + /// Represents a LED-matrix. + /// + LedMatrix = 1 << 5, + + /// + /// Represents a Mainboard. + /// + Mainboard = 1 << 6, + + /// + /// Represents a Graphics card. + /// + GraphicsCard = 1 << 7, + + /// + /// Represents a DRAM-bank. + /// + DRAM = 1 << 8, + + /// + /// Represents a headset stand. + /// + HeadsetStand = 1 << 9, + + /// + /// Represents a keypad. + /// + Keypad = 1 << 10, + + /// + /// Represents a fan. + /// + Fan = 1 << 11, + + /// + /// Represents a speaker + /// + Speaker = 1 << 12, + + /// + /// Represents a cooler. + /// + Cooler = 1 << 13, + + /// + /// Represents a monitor. + /// + Monitor = 1 << 14, + + /// + /// Represents a generic led-controller. + /// + LedController = 1 << 15, + + /// + /// Represents a device where the type is not known or not present in the list. + /// + Unknown = 1 << 31, + + /// + /// Represents all devices. + /// + All = ~None +} \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/ICooler.cs b/RGB.NET.Core/Devices/TypeInterfaces/ICooler.cs index 6053c40b..1e1eb2f2 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/ICooler.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/ICooler.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a cooler-device - /// - public interface ICooler : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a cooler-device +/// +public interface ICooler : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IDRAM.cs b/RGB.NET.Core/Devices/TypeInterfaces/IDRAM.cs index 6734e165..3bb4c23a 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IDRAM.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IDRAM.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a DRAM-device - /// - public interface IDRAM : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a DRAM-device +/// +public interface IDRAM : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IFan.cs b/RGB.NET.Core/Devices/TypeInterfaces/IFan.cs index 3f9eb570..9f0c803a 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IFan.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IFan.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// represents a fan-device - /// - public interface IFan : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// represents a fan-device +/// +public interface IFan : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IGraphicsCard.cs b/RGB.NET.Core/Devices/TypeInterfaces/IGraphicsCard.cs index 30fc9d4f..372ec092 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IGraphicsCard.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IGraphicsCard.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a graphics-card-device - /// - public interface IGraphicsCard : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a graphics-card-device +/// +public interface IGraphicsCard : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IHeadset.cs b/RGB.NET.Core/Devices/TypeInterfaces/IHeadset.cs index 25cde5c4..0256cd5c 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IHeadset.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IHeadset.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a headset-device - /// - public interface IHeadset : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a headset-device +/// +public interface IHeadset : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IHeadsetStand.cs b/RGB.NET.Core/Devices/TypeInterfaces/IHeadsetStand.cs index 9c5c81a0..537c8564 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IHeadsetStand.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IHeadsetStand.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a headset-stand-device - /// - public interface IHeadsetStand : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a headset-stand-device +/// +public interface IHeadsetStand : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IKeyboard.cs b/RGB.NET.Core/Devices/TypeInterfaces/IKeyboard.cs index 7e32e96c..33f4e63c 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IKeyboard.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IKeyboard.cs @@ -1,8 +1,23 @@ -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a generic keyboard-device. +/// +public interface IKeyboard : IRGBDevice { /// - /// Represents a keyboard-device + /// Gets the device information assiciated with this device. /// - public interface IKeyboard : IRGBDevice - { } + new IKeyboardDeviceInfo DeviceInfo { get; } } + +/// +/// Represents a generic keyboard device information. +/// +public interface IKeyboardDeviceInfo : IRGBDeviceInfo +{ + /// + /// Gets the of the keyboard. + /// + KeyboardLayoutType Layout { get; } +} \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IKeypad.cs b/RGB.NET.Core/Devices/TypeInterfaces/IKeypad.cs index 30304926..2a65233b 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IKeypad.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IKeypad.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a keypad-device - /// - public interface IKeypad : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a keypad-device +/// +public interface IKeypad : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/ILedMatrix.cs b/RGB.NET.Core/Devices/TypeInterfaces/ILedMatrix.cs index 2ba759dc..b0f401e5 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/ILedMatrix.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/ILedMatrix.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a led-matrix-device - /// - public interface ILedMatrix : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a led-matrix-device +/// +public interface ILedMatrix : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/ILedStripe.cs b/RGB.NET.Core/Devices/TypeInterfaces/ILedStripe.cs index 9c97ab53..4bb5fd80 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/ILedStripe.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/ILedStripe.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a led-stripe-device - /// - public interface ILedStripe : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a led-stripe-device +/// +public interface ILedStripe : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IMainboard.cs b/RGB.NET.Core/Devices/TypeInterfaces/IMainboard.cs index e043c6f9..10af8f4a 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IMainboard.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IMainboard.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a mainboard-device - /// - public interface IMainboard : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a mainboard-device +/// +public interface IMainboard : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IMouse.cs b/RGB.NET.Core/Devices/TypeInterfaces/IMouse.cs index 6064012d..76e62e2e 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IMouse.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IMouse.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a mouse-device - /// - public interface IMouse : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a mouse-device +/// +public interface IMouse : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IMousepad.cs b/RGB.NET.Core/Devices/TypeInterfaces/IMousepad.cs index e6812fc1..c89b2548 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IMousepad.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IMousepad.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a mousepad-device - /// - public interface IMousepad : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a mousepad-device +/// +public interface IMousepad : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/ISpeaker.cs b/RGB.NET.Core/Devices/TypeInterfaces/ISpeaker.cs index 6670297f..cde47e4e 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/ISpeaker.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/ISpeaker.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a speaker-device - /// - public interface ISpeaker : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a speaker-device +/// +public interface ISpeaker : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Devices/TypeInterfaces/IUnknownDevice.cs b/RGB.NET.Core/Devices/TypeInterfaces/IUnknownDevice.cs index 724dc4dc..1d136ad7 100644 --- a/RGB.NET.Core/Devices/TypeInterfaces/IUnknownDevice.cs +++ b/RGB.NET.Core/Devices/TypeInterfaces/IUnknownDevice.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Core -{ - /// - /// Represents a device with unkown or not specified type. - /// - public interface IUnknownDevice : IRGBDevice - { } -} +namespace RGB.NET.Core; + +/// +/// Represents a device with unkown or not specified type. +/// +public interface IUnknownDevice : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Events/ExceptionEventArgs.cs b/RGB.NET.Core/Events/ExceptionEventArgs.cs index 01e58ae8..63cb3abe 100644 --- a/RGB.NET.Core/Events/ExceptionEventArgs.cs +++ b/RGB.NET.Core/Events/ExceptionEventArgs.cs @@ -3,35 +3,48 @@ using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// Represents the information supplied with an -event. +/// +public class ExceptionEventArgs : EventArgs { - /// + #region Properties & Fields + /// - /// Represents the information supplied with an -event. + /// Gets the which is responsible for the event-call. /// - public class ExceptionEventArgs : EventArgs - { - #region Properties & Fields + public Exception Exception { get; } - /// - /// Gets the which is responsible for the event-call. - /// - public Exception Exception { get; } + /// + /// Gets a bool indicating if the exception is critical for the thrower. + /// + public bool IsCritical { get; } - #endregion + /// + /// Gets or sets if the exception should be thrown after the event is handled. + /// + public bool Throw { get; set; } - #region Constructors + #endregion - /// - /// - /// Initializes a new instance of the class. - /// - /// The which is responsible for the event-call. - public ExceptionEventArgs(Exception exception) - { - this.Exception = exception; - } + #region Constructors - #endregion + /// + /// + /// Initializes a new instance of the class. + /// + /// The which is responsible for the event-call. + /// Indicates if the exception is critical for the thrower. + /// Indicates if the exception should be thrown after the event is handled. + public ExceptionEventArgs(Exception exception, bool isCritical = false, bool @throw = false) + { + this.Exception = exception; + this.IsCritical = isCritical; + this.Throw = @throw; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Events/ResolvePathEventArgs.cs b/RGB.NET.Core/Events/ResolvePathEventArgs.cs deleted file mode 100644 index 2b73a2e5..00000000 --- a/RGB.NET.Core/Events/ResolvePathEventArgs.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; - -namespace RGB.NET.Core -{ - public class ResolvePathEventArgs : EventArgs - { - #region Properties & Fields - - /// - /// Gets the filename used to resolve the path. - /// This has to be checked for null since it'S possible that only is used. - /// Also check before use. - /// - public string RelativePart { get; } - - /// - /// Gets the filename used to resolve the path. - /// This has to be checked for null since it'S possible that only is used. - /// Also check before use. - /// - public string FileName { get; } - - /// - /// Gets the relative path used to resolve the path. - /// If this is set and are unused. - /// - public string RelativePath { get; } - - /// - /// Gets or sets the resolved path. - /// - public string FinalPath { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The filename used to resolve the path. - /// The filename used to resolve the path. - /// The relative part used to resolve the path. - public ResolvePathEventArgs(string relativePart, string fileName, string finalPath) - { - this.RelativePart = relativePart; - this.FileName = fileName; - this.FinalPath = finalPath; - } - - /// - /// Initializes a new instance of the class. - /// - /// The relative path used to resolve the path. - /// The relative part used to resolve the path. - public ResolvePathEventArgs(string relativePath, string finalPath) - { - this.RelativePath = relativePath; - this.FinalPath = finalPath; - } - - #endregion - } -} diff --git a/RGB.NET.Core/Events/SurfaceLayoutChangedEventArgs.cs b/RGB.NET.Core/Events/SurfaceLayoutChangedEventArgs.cs index 5e4840a4..1cee8465 100644 --- a/RGB.NET.Core/Events/SurfaceLayoutChangedEventArgs.cs +++ b/RGB.NET.Core/Events/SurfaceLayoutChangedEventArgs.cs @@ -2,51 +2,65 @@ // ReSharper disable UnusedAutoPropertyAccessor.Global using System; -using System.Collections.Generic; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// Represents the information supplied with an -event. +/// +public class SurfaceLayoutChangedEventArgs : EventArgs { + #region Properties & Fields + + /// + /// Gets the that caused the change. Returns null if the change isn't caused by a . + /// + public IRGBDevice? Devices { get; } + + /// + /// Gets a value indicating if the event is caused by the addition of a new to the . + /// + public bool DeviceAdded { get; } + + /// + /// Gets a value indicating if the event is caused by the removal of a to the . + /// + public bool DeviceRemoved { get; } + + /// + /// Gets a value indicating if the event is caused by a changed location or size of one of the on the . + /// + public bool DeviceChanged { get; } + + #endregion + + #region Constructors + /// /// - /// Represents the information supplied with an -event. + /// Initializes a new instance of the class. /// - public class SurfaceLayoutChangedEventArgs : EventArgs + /// The that caused the change. + /// A value indicating if the event is caused by the addition of a new to the . + /// A value indicating if the event is caused by the removal of a from the . + /// A value indicating if the event is caused by a change to a on the . + private SurfaceLayoutChangedEventArgs(IRGBDevice? devices, bool deviceAdded, bool deviceRemoved, bool deviceChanged) { - #region Properties & Fields - - /// - /// Gets the that caused the change. Returns null if the change isn't caused by a . - /// - public IEnumerable Devices { get; } - - /// - /// Gets a value indicating if the event is caused by the addition of a new to the . - /// - public bool DeviceAdded { get; } - - /// - /// Gets a value indicating if the event is caused by a changed location of one of the devices on the . - /// - public bool DeviceLocationChanged { get; } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The that caused the change. - /// A value indicating if the event is caused by the addition of a new to the . - /// A value indicating if the event is caused by a changed location of one of the devices on the . - public SurfaceLayoutChangedEventArgs(IEnumerable devices, bool deviceAdded, bool deviceLocationChanged) - { - this.Devices = devices; - this.DeviceAdded = deviceAdded; - this.DeviceLocationChanged = deviceLocationChanged; - } - - #endregion + this.Devices = devices; + this.DeviceAdded = deviceAdded; + this.DeviceRemoved = deviceRemoved; + this.DeviceChanged = deviceChanged; } -} + + #endregion + + #region Factory + + internal static SurfaceLayoutChangedEventArgs FromAddedDevice(IRGBDevice device) => new(device, true, false, false); + internal static SurfaceLayoutChangedEventArgs FromRemovedDevice(IRGBDevice device) => new(device, false, true, false); + internal static SurfaceLayoutChangedEventArgs FromChangedDevice(IRGBDevice device) => new(device, false, false, true); + internal static SurfaceLayoutChangedEventArgs Misc() => new(null, false, false, false); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Events/UpdatedEventArgs.cs b/RGB.NET.Core/Events/UpdatedEventArgs.cs index fe2c4e6a..b4251d4d 100644 --- a/RGB.NET.Core/Events/UpdatedEventArgs.cs +++ b/RGB.NET.Core/Events/UpdatedEventArgs.cs @@ -1,11 +1,10 @@ using System; -namespace RGB.NET.Core -{ - /// - /// - /// Represents the information supplied with an -event. - /// - public class UpdatedEventArgs : EventArgs - { } -} +namespace RGB.NET.Core; + +/// +/// +/// Represents the information supplied with an -event. +/// +public class UpdatedEventArgs : EventArgs +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Events/UpdatingEventArgs.cs b/RGB.NET.Core/Events/UpdatingEventArgs.cs index 46e1f73f..47df4af4 100644 --- a/RGB.NET.Core/Events/UpdatingEventArgs.cs +++ b/RGB.NET.Core/Events/UpdatingEventArgs.cs @@ -3,49 +3,48 @@ using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// Represents the information supplied with an -event. +/// +public class UpdatingEventArgs : EventArgs { + #region Properties & Fields + + /// + /// Gets the elapsed time (in seconds) since the last update. + /// + public double DeltaTime { get; } + + /// + /// Gets the trigger causing this update. + /// + public IUpdateTrigger? Trigger { get; } + + /// + /// Gets the custom-data provided by the trigger for this update. + /// + public CustomUpdateData CustomData { get; } + + #endregion + + #region Constructors + /// /// - /// Represents the information supplied with an -event. + /// Initializes a new instance of the class. /// - public class UpdatingEventArgs : EventArgs + /// The elapsed time (in seconds) since the last update. + /// The trigger causing this update. + /// The custom-data provided by the trigger for this update. + public UpdatingEventArgs(double deltaTime, IUpdateTrigger? trigger, CustomUpdateData customData) { - #region Properties & Fields - - /// - /// Gets the elapsed time (in seconds) since the last update. - /// - public double DeltaTime { get; } - - /// - /// Gets the trigger causing this update. - /// - public IUpdateTrigger Trigger { get; } - - /// - /// Gets the custom-data provided by the trigger for this update. - /// - public CustomUpdateData CustomData { get; } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The elapsed time (in seconds) since the last update. - /// The trigger causing this update. - /// The custom-data provided by the trigger for this update. - public UpdatingEventArgs(double deltaTime, IUpdateTrigger trigger, CustomUpdateData customData) - { - this.DeltaTime = deltaTime; - this.Trigger = trigger; - this.CustomData = customData; - } - - #endregion + this.DeltaTime = deltaTime; + this.Trigger = trigger; + this.CustomData = customData; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Exceptions/DeviceProviderException.cs b/RGB.NET.Core/Exceptions/DeviceProviderException.cs new file mode 100644 index 00000000..4d852887 --- /dev/null +++ b/RGB.NET.Core/Exceptions/DeviceProviderException.cs @@ -0,0 +1,34 @@ +using System; + +namespace RGB.NET.Core; + +/// +/// +/// Represents an exception thrown by a . +/// +public class DeviceProviderException : ApplicationException +{ + #region Properties & Fields + + /// + /// Gets a bool indicating if the exception is critical and shouldn't be ingored. + /// + public bool IsCritical { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The exception that is the casue of the current exception or null if this exception was thrown on purpose. + /// A value indicating if the exception is critical and shouldn't be ignored. + public DeviceProviderException(Exception? innerException, bool isCritical) + : base(innerException?.Message, innerException) + { + this.IsCritical = isCritical; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Exceptions/RGBDeviceException.cs b/RGB.NET.Core/Exceptions/RGBDeviceException.cs index 735b0c49..0ccea387 100644 --- a/RGB.NET.Core/Exceptions/RGBDeviceException.cs +++ b/RGB.NET.Core/Exceptions/RGBDeviceException.cs @@ -1,25 +1,24 @@ using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// Represents an exception thrown by an . +/// +public class RGBDeviceException : ApplicationException { + #region Constructors + /// /// - /// Represents an exception thrown by an . + /// Initializes a new instance of the class. /// - public class RGBDeviceException : ApplicationException - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The message which describes the reason of throwing this exception. - /// Optional inner exception, which lead to this exception. - public RGBDeviceException(string message, Exception innerException = null) - : base(message, innerException) - { } + /// The message which describes the reason of throwing this exception. + /// Optional inner exception, which lead to this exception. + public RGBDeviceException(string message, Exception? innerException = null) + : base(message, innerException) + { } - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Exceptions/RGBSurfaceException.cs b/RGB.NET.Core/Exceptions/RGBSurfaceException.cs new file mode 100644 index 00000000..eb2b27c6 --- /dev/null +++ b/RGB.NET.Core/Exceptions/RGBSurfaceException.cs @@ -0,0 +1,24 @@ +using System; + +namespace RGB.NET.Core; + +/// +/// +/// Represents an exception thrown by an . +/// +public class RGBSurfaceException : ApplicationException +{ + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The message which describes the reason of throwing this exception. + /// Optional inner exception, which lead to this exception. + public RGBSurfaceException(string message, Exception? innerException = null) + : base(message, innerException) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Extensions/ColorExtensions.cs b/RGB.NET.Core/Extensions/ColorExtensions.cs index 15d0c804..c2afc234 100644 --- a/RGB.NET.Core/Extensions/ColorExtensions.cs +++ b/RGB.NET.Core/Extensions/ColorExtensions.cs @@ -1,30 +1,32 @@ using System; -namespace RGB.NET.Core -{ - public static class ColorExtensions - { - #region Methods +namespace RGB.NET.Core; - /// - /// Calculates the distance between the two given colors using the redmean algorithm. - /// For more infos check https://www.compuphase.com/cmetric.htm - /// - /// The start color of the distance calculation. - /// The end color fot the distance calculation. - /// - public static double DistanceTo(this Color color1, Color color2) - { - (_, byte r1, byte g1, byte b1) = color1.GetRGBBytes(); - (_, byte r2, byte g2, byte b2) = color2.GetRGBBytes(); +/// +/// Offers some extensions and helper-methods for related things. +/// +public static class ColorExtensions +{ + #region Methods - long rmean = (r1 + r2) / 2; - long r = r1 - r2; - long g = g1 - g2; - long b = b1 - b2; - return Math.Sqrt((((512 + rmean) * r * r) >> 8) + (4 * g * g) + (((767 - rmean) * b * b) >> 8)); - } + /// + /// Calculates the distance between the two specified colors using the redmean algorithm. + /// For more infos check https://www.compuphase.com/cmetric.htm + /// + /// The start color of the distance calculation. + /// The end color fot the distance calculation. + /// The redmean distance between the two specified colors. + public static double DistanceTo(this in Color color1, in Color color2) + { + (_, byte r1, byte g1, byte b1) = color1.GetRGBBytes(); + (_, byte r2, byte g2, byte b2) = color2.GetRGBBytes(); - #endregion + long rmean = (r1 + r2) / 2; + long r = r1 - r2; + long g = g1 - g2; + long b = b1 - b2; + return Math.Sqrt((((512 + rmean) * r * r) >> 8) + (4 * g * g) + (((767 - rmean) * b * b) >> 8)); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Extensions/CustomUpdateDataExtension.cs b/RGB.NET.Core/Extensions/CustomUpdateDataExtension.cs new file mode 100644 index 00000000..ff014a91 --- /dev/null +++ b/RGB.NET.Core/Extensions/CustomUpdateDataExtension.cs @@ -0,0 +1,55 @@ +namespace RGB.NET.Core; + +/// +/// Offers some extensions for easier use of . +/// +public static class CustomUpdateDataExtension +{ + /// + /// Sets the -Parameter to the given value. + /// + /// The update-data to modify. + /// The value to set. + /// The modified update-data. + public static CustomUpdateData FlushLeds(this CustomUpdateData customUpdateData, bool value = true) + { + customUpdateData[CustomUpdateDataIndex.FLUSH_LEDS] = value; + return customUpdateData; + } + + /// + /// Sets the -Parameter to the given value. + /// + /// The update-data to modify. + /// The value to set. + /// The modified update-data. + public static CustomUpdateData Render(this CustomUpdateData customUpdateData, bool value = true) + { + customUpdateData[CustomUpdateDataIndex.RENDER] = value; + return customUpdateData; + } + + /// + /// Sets the -Parameter to the given value. + /// + /// The update-data to modify. + /// The value to set. + /// The modified update-data. + public static CustomUpdateData UpdateDevices(this CustomUpdateData customUpdateData, bool value = true) + { + customUpdateData[CustomUpdateDataIndex.UPDATE_DEVICES] = value; + return customUpdateData; + } + + /// + /// Sets the -Parameter to the given value. + /// + /// The update-data to modify. + /// The value to set. + /// The modified update-data. + public static CustomUpdateData Heartbeat(this CustomUpdateData customUpdateData, bool value = true) + { + customUpdateData[CustomUpdateDataIndex.HEARTBEAT] = value; + return customUpdateData; + } +} \ No newline at end of file diff --git a/RGB.NET.Core/Extensions/MathExtensions.cs b/RGB.NET.Core/Extensions/MathExtensions.cs index 0a9fb885..c3176b1a 100644 --- a/RGB.NET.Core/Extensions/MathExtensions.cs +++ b/RGB.NET.Core/Extensions/MathExtensions.cs @@ -1,101 +1,110 @@ using System; using System.Runtime.CompilerServices; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Offers some extensions and helper-methods for the work with floats. +/// +public static class FloatExtensions { + #region Constants + /// - /// Offers some extensions and helper-methods for the work with doubles + /// Defines the precision RGB.NET processes floating point comparisons in. /// - public static class DoubleExtensions + public const float TOLERANCE = 1E-7f; + + #endregion + + #region Methods + + /// + /// Checks if two values are equal respecting the . + /// + /// The first value to compare. + /// The first value to compare. + /// true if the difference is smaller than the ; otherwise, false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static bool EqualsInTolerance(this float value1, float value2) => Math.Abs(value1 - value2) < TOLERANCE; + + /// + /// Clamps the provided value to be bigger or equal min and smaller or equal max. + /// + /// The value to clamp. + /// The lower value of the range the value is clamped to. + /// The higher value of the range the value is clamped to. + /// The clamped value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Clamp(this float value, float min, float max) + { + // ReSharper disable ConvertIfStatementToReturnStatement - I'm not sure why, but inlining this statement reduces performance by ~10% + if (value < min) return min; + if (value > max) return max; + return value; + // ReSharper restore ConvertIfStatementToReturnStatement + } + + /// + /// Clamps the provided value to be bigger or equal min and smaller or equal max. + /// + /// The value to clamp. + /// The lower value of the range the value is clamped to. + /// The higher value of the range the value is clamped to. + /// The clamped value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Clamp(this int value, int min, int max) { - #region Constants - - /// - /// Defines the precision RGB.NET processes floating point comparisons in. - /// - public const double TOLERANCE = 1E-10; - - #endregion - - #region Methods - - /// - /// Checks if two values are equal respecting the . - /// - /// The first value to compare. - /// The first value to compare. - /// true if the difference is smaller than the ; otherwise, false. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool EqualsInTolerance(this double value1, double value2) => Math.Abs(value1 - value2) < TOLERANCE; - - /// - /// Clamps the provided value to be bigger or equal min and smaller or equal max. - /// - /// The value to clamp. - /// The lower value of the range the value is clamped to. - /// The higher value of the range the value is clamped to. - /// The clamped value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Clamp(this double value, double min, double max) - { - // ReSharper disable ConvertIfStatementToReturnStatement - I'm not sure why, but inlining this statement reduces performance by ~10% - if (value < min) return min; - if (value > max) return max; - return value; - // ReSharper restore ConvertIfStatementToReturnStatement - } - - /// - /// Clamps the provided value to be bigger or equal min and smaller or equal max. - /// - /// The value to clamp. - /// The lower value of the range the value is clamped to. - /// The higher value of the range the value is clamped to. - /// The clamped value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int Clamp(this int value, int min, int max) - { - // ReSharper disable ConvertIfStatementToReturnStatement - I'm not sure why, but inlining this statement reduces performance by ~10% - if (value < min) return min; - if (value > max) return max; - return value; - // ReSharper restore ConvertIfStatementToReturnStatement - } - - /// - /// Enforces the provided value to be in the specified range by wrapping it around the edges if it exceeds them. - /// - /// The value to wrap. - /// The lower value of the range the value is wrapped into. - /// The higher value of the range the value is wrapped into. - /// The wrapped value. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Wrap(this double value, double min, double max) - { - double range = max - min; - - while (value >= max) - value -= range; - - while (value < min) - value += range; - - return value; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static byte GetByteValueFromPercentage(this double percentage) - { - if (double.IsNaN(percentage)) return 0; - - percentage = percentage.Clamp(0, 1.0); - return (byte)(percentage >= 1.0 ? 255 : percentage * 256.0); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double GetPercentageFromByteValue(this byte value) - => ((double)value) / byte.MaxValue; - - #endregion + // ReSharper disable ConvertIfStatementToReturnStatement - I'm not sure why, but inlining this statement reduces performance by ~10% + if (value < min) return min; + if (value > max) return max; + return value; + // ReSharper restore ConvertIfStatementToReturnStatement } -} + + /// + /// Enforces the provided value to be in the specified range by wrapping it around the edges if it exceeds them. + /// + /// The value to wrap. + /// The lower value of the range the value is wrapped into. + /// The higher value of the range the value is wrapped into. + /// The wrapped value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float Wrap(this float value, float min, float max) + { + float range = max - min; + + while (value >= max) + value -= range; + + while (value < min) + value += range; + + return value; + } + + /// + /// Converts a normalized float value in the range [0..1] to a byte [0..255]. + /// + /// The normalized float value to convert. + /// The byte value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static byte GetByteValueFromPercentage(this float percentage) + { + if (float.IsNaN(percentage)) return 0; + + percentage = percentage.Clamp(0, 1.0f); + return (byte)(percentage >= 1.0f ? 255 : percentage * 256.0f); + } + + /// + /// Converts a byte value [0..255] to a normalized float value in the range [0..1]. + /// + /// The byte value to convert. + /// The normalized float value. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float GetPercentageFromByteValue(this byte value) + => value == 255 ? 1.0f : (value / 256.0f); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Extensions/PointExtensions.cs b/RGB.NET.Core/Extensions/PointExtensions.cs index 7c413e92..1acab3a7 100644 --- a/RGB.NET.Core/Extensions/PointExtensions.cs +++ b/RGB.NET.Core/Extensions/PointExtensions.cs @@ -1,37 +1,43 @@ using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Offers some extensions and helper-methods for related things. +/// +public static class PointExtensions { - public static class PointExtensions + #region Methods + + /// + /// Moves the specified by the specified amount. + /// + /// The to move. + /// The x-ammount to move. + /// The y-ammount to move. + /// The new location of the point. + public static Point Translate(this in Point point, float x = 0, float y = 0) => new(point.X + x, point.Y + y); + + /// + /// Rotates the specified by the specified amuont around the specified origin. + /// + /// The to rotate. + /// The rotation. + /// The origin to rotate around. [0,0] if not set. + /// The new location of the point. + public static Point Rotate(this in Point point, in Rotation rotation, in Point origin = new()) { - #region Methods - - /// - /// Moves the specified by the given amount. - /// - /// The to move. - /// The x-ammount to move. - /// The y-ammount to move. - /// The new location of the point. - public static Point Translate(this Point point, double x = 0, double y = 0) => new Point(point.X + x, point.Y + y); - - /// - /// Rotates the specified by the given amuont around the given origin. - /// - /// The to rotate. - /// The rotation. - /// The origin to rotate around. [0,0] if not set. - /// The new location of the point. - public static Point Rotate(this Point point, Rotation rotation, Point origin = new Point()) - { - double sin = Math.Sin(rotation.Radians); - double cos = Math.Cos(rotation.Radians); - - point = new Point(point.X - origin.X, point.Y - origin.Y); - point = new Point((point.X * cos) - (point.Y * sin), (point.X * sin) + (point.Y * cos)); - return new Point(point.X + origin.X, point.Y + origin.Y); ; - } - - #endregion + float sin = MathF.Sin(rotation.Radians); + float cos = MathF.Cos(rotation.Radians); + + float x = point.X - origin.X; + float y = point.Y - origin.Y; + + x = (x * cos) - (y * sin); + y = (x * sin) + (y * cos); + + return new Point(x + origin.X, y + origin.Y); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Extensions/RectangleExtensions.cs b/RGB.NET.Core/Extensions/RectangleExtensions.cs index aae9b043..68fec324 100644 --- a/RGB.NET.Core/Extensions/RectangleExtensions.cs +++ b/RGB.NET.Core/Extensions/RectangleExtensions.cs @@ -1,169 +1,176 @@ using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Offers some extensions and helper-methods for the work with rectangles. +/// +public static class RectangleExtensions { - public static class RectangleExtensions + #region Methods + + /// + /// Sets the of the specified rectangle. + /// + /// The rectangle to modify. + /// The new location of the rectangle. + /// The modified . + public static Rectangle SetLocation(this in Rectangle rect, in Point location) => new(location, rect.Size); + + /// + /// Sets the of the of the specified rectangle. + /// + /// The rectangle to modify. + /// The new x-location of the rectangle. + /// The modified . + public static Rectangle SetX(this in Rectangle rect, float x) => new(new Point(x, rect.Location.Y), rect.Size); + + /// + /// Sets the of the of the specified rectangle. + /// + /// The rectangle to modify. + /// The new y-location of the rectangle. + /// The modified . + public static Rectangle SetY(this in Rectangle rect, float y) => new(new Point(rect.Location.X, y), rect.Size); + + /// + /// Sets the of the specified rectangle. + /// + /// The rectangle to modify. + /// The new size of the rectangle. + /// The modified . + public static Rectangle SetSize(this in Rectangle rect, in Size size) => new(rect.Location, size); + + /// + /// Sets the of the of the specified rectangle. + /// + /// The rectangle to modify. + /// The new width of the rectangle. + /// The modified . + public static Rectangle SetWidth(this in Rectangle rect, float width) => new(rect.Location, new Size(width, rect.Size.Height)); + + /// + /// Sets the of the of the specified rectangle. + /// + /// The rectangle to modify. + /// The new height of the rectangle. + /// The modified . + public static Rectangle SetHeight(this in Rectangle rect, float height) => new(rect.Location, new Size(rect.Size.Width, height)); + + /// + /// Calculates the percentage of intersection of a rectangle. + /// + /// The rectangle to calculate the intersection for. + /// The intersecting rectangle. + /// The percentage of intersection. + public static float CalculateIntersectPercentage(this in Rectangle rect, in Rectangle intersectingRect) { - #region Methods - - /// - /// Sets the of the given rectangle. - /// - /// The rectangle to modify. - /// The new location of the rectangle. - /// The modified . - public static Rectangle SetLocation(this Rectangle rect, Point location) => new Rectangle(location, rect.Size); - - /// - /// Sets the of the of the given rectangle. - /// - /// The rectangle to modify. - /// The new x-location of the rectangle. - /// The modified . - public static Rectangle SetX(this Rectangle rect, double x) => new Rectangle(new Point(x, rect.Location.Y), rect.Size); - - /// - /// Sets the of the of the given rectangle. - /// - /// The rectangle to modify. - /// The new y-location of the rectangle. - /// The modified . - public static Rectangle SetY(this Rectangle rect, double y) => new Rectangle(new Point(rect.Location.X, y), rect.Size); - - /// - /// Sets the of the given rectangle. - /// - /// The rectangle to modify. - /// The new size of the rectangle. - /// The modified . - public static Rectangle SetSize(this Rectangle rect, Size size) => new Rectangle(rect.Location, size); - - /// - /// Sets the of the of the given rectangle. - /// - /// The rectangle to modify. - /// The new width of the rectangle. - /// The modified . - public static Rectangle SetWidth(this Rectangle rect, double width) => new Rectangle(rect.Location, new Size(width, rect.Size.Height)); - - /// - /// Sets the of the of the given rectangle. - /// - /// The rectangle to modify. - /// The new height of the rectangle. - /// The modified . - public static Rectangle SetHeight(this Rectangle rect, double height) => new Rectangle(rect.Location, new Size(rect.Size.Width, height)); - - /// - /// Calculates the percentage of intersection of a rectangle. - /// - /// The intersecting rectangle. - /// The percentage of intersection. - public static double CalculateIntersectPercentage(this Rectangle rect, Rectangle intersectingRect) - { - if (rect.IsEmpty || intersectingRect.IsEmpty) return 0; + if (rect.IsEmpty || intersectingRect.IsEmpty) return 0; - Rectangle intersection = rect.CalculateIntersection(intersectingRect); - return (intersection.Size.Width * intersection.Size.Height) / (rect.Size.Width * rect.Size.Height); - } + Rectangle intersection = rect.CalculateIntersection(intersectingRect); + return (intersection.Size.Width * intersection.Size.Height) / (rect.Size.Width * rect.Size.Height); + } - /// - /// Calculates the representing the intersection of this and the one provided as parameter. - /// - /// The intersecting - /// A new representing the intersection this and the one provided as parameter. - public static Rectangle CalculateIntersection(this Rectangle rect, Rectangle intersectingRectangle) - { - double x1 = Math.Max(rect.Location.X, intersectingRectangle.Location.X); - double x2 = Math.Min(rect.Location.X + rect.Size.Width, intersectingRectangle.Location.X + intersectingRectangle.Size.Width); + /// + /// Calculates the representing the intersection of this and the one provided as parameter. + /// + /// The rectangle to calculate the intersection for. + /// The intersecting . + /// A new representing the intersection this and the one provided as parameter. + public static Rectangle CalculateIntersection(this in Rectangle rect, in Rectangle intersectingRectangle) + { + float x1 = Math.Max(rect.Location.X, intersectingRectangle.Location.X); + float x2 = Math.Min(rect.Location.X + rect.Size.Width, intersectingRectangle.Location.X + intersectingRectangle.Size.Width); - double y1 = Math.Max(rect.Location.Y, intersectingRectangle.Location.Y); - double y2 = Math.Min(rect.Location.Y + rect.Size.Height, intersectingRectangle.Location.Y + intersectingRectangle.Size.Height); + float y1 = Math.Max(rect.Location.Y, intersectingRectangle.Location.Y); + float y2 = Math.Min(rect.Location.Y + rect.Size.Height, intersectingRectangle.Location.Y + intersectingRectangle.Size.Height); - if ((x2 >= x1) && (y2 >= y1)) - return new Rectangle(x1, y1, x2 - x1, y2 - y1); + if ((x2 >= x1) && (y2 >= y1)) + return new Rectangle(x1, y1, x2 - x1, y2 - y1); - return new Rectangle(); - } + return new Rectangle(); + } + + /// + /// Determines if the specified is contained within this . + /// + /// The containing rectangle. + /// The to test. + /// true if the rectangle contains the specified point; otherwise false. + public static bool Contains(this in Rectangle rect, in Point point) => rect.Contains(point.X, point.Y); + + /// + /// Determines if the specified location is contained within this . + /// + /// The containing rectangle. + /// The X-location to test. + /// The Y-location to test. + /// true if the rectangle contains the specified coordinates; otherwise false. + public static bool Contains(this in Rectangle rect, float x, float y) => (rect.Location.X <= x) && (x < (rect.Location.X + rect.Size.Width)) + && (rect.Location.Y <= y) && (y < (rect.Location.Y + rect.Size.Height)); + + /// + /// Determines if the specified is contained within this . + /// + /// The containing rectangle. + /// The to test. + /// true if the rectangle contains the specified rect; otherwise false. + public static bool Contains(this in Rectangle rect, in Rectangle rect2) => (rect.Location.X <= rect2.Location.X) && ((rect2.Location.X + rect2.Size.Width) <= (rect.Location.X + rect.Size.Width)) + && (rect.Location.Y <= rect2.Location.Y) && ((rect2.Location.Y + rect2.Size.Height) <= (rect.Location.Y + rect.Size.Height)); + + /// + /// Moves the specified by the specified amount. + /// + /// The to move. + /// The amount to move. + /// The moved rectangle. + public static Rectangle Translate(this in Rectangle rect, in Point point) => rect.Translate(point.X, point.Y); + + /// + /// Moves the specified by the specified amount. + /// + /// The to move. + /// The x-ammount to move. + /// The y-ammount to move. + /// The moved rectangle. + public static Rectangle Translate(this in Rectangle rect, float x = 0, float y = 0) => new(rect.Location.Translate(x, y), rect.Size); + + /// + /// Rotates the specified by the specified amuont around the specified origin. + /// + /// + /// The returned array of is filled with the new locations of the rectangle clockwise starting from the top left: + /// [0] = top left + /// [1] = top right + /// [2] = bottom right + /// [3] = bottom left + /// + /// The to rotate. + /// The rotation. + /// The origin to rotate around. [0,0] if not set. + /// A array of containing the new locations of the corners of the original rectangle. + public static Point[] Rotate(this in Rectangle rect, in Rotation rotation, in Point origin = new()) + { + Point[] points = { + rect.Location, // top left + new(rect.Location.X + rect.Size.Width, rect.Location.Y), // top right + new(rect.Location.X + rect.Size.Width, rect.Location.Y + rect.Size.Height), // bottom right + new(rect.Location.X, rect.Location.Y + rect.Size.Height), // bottom right + }; + + float sin = MathF.Sin(rotation.Radians); + float cos = MathF.Cos(rotation.Radians); - /// - /// Determines if the specified is contained within this . - /// - /// The to test. - /// true if the rectangle contains the given point; otherwise false. - public static bool Contains(this Rectangle rect, Point point) => rect.Contains(point.X, point.Y); - - /// - /// Determines if the specified location is contained within this . - /// - /// The X-location to test. - /// The Y-location to test. - /// true if the rectangle contains the given coordinates; otherwise false. - public static bool Contains(this Rectangle rect, double x, double y) => (rect.Location.X <= x) && (x < (rect.Location.X + rect.Size.Width)) - && (rect.Location.Y <= y) && (y < (rect.Location.Y + rect.Size.Height)); - - /// - /// Determines if the specified is contained within this . - /// - /// The to test. - /// true if the rectangle contains the given rect; otherwise false. - public static bool Contains(this Rectangle rect, Rectangle rect2) => (rect.Location.X <= rect2.Location.X) && ((rect2.Location.X + rect2.Size.Width) <= (rect.Location.X + rect.Size.Width)) - && (rect.Location.Y <= rect2.Location.Y) && ((rect2.Location.Y + rect2.Size.Height) <= (rect.Location.Y + rect.Size.Height)); - - /// - /// Moves the specified by the given amount. - /// - /// The to move. - /// The amount to move. - /// The moved rectangle. - public static Rectangle Translate(this Rectangle rect, Point point) => rect.Translate(point.X, point.Y); - - /// - /// Moves the specified by the given amount. - /// - /// The to move. - /// The x-ammount to move. - /// The y-ammount to move. - /// The moved rectangle. - public static Rectangle Translate(this Rectangle rect, double x = 0, double y = 0) => new Rectangle(rect.Location.Translate(x, y), rect.Size); - - /// - /// Rotates the specified by the given amuont around the given origin. - /// - /// - /// The returned array of is filled with the new locations of the rectangle clockwise starting from the top left: - /// [0] = top left - /// [1] = top right - /// [2] = bottom right - /// [3] = bottom left - /// - /// The to rotate. - /// The rotation. - /// The origin to rotate around. [0,0] if not set. - /// A array of containing the new locations of the corners of the original rectangle. - public static Point[] Rotate(this Rectangle rect, Rotation rotation, Point origin = new Point()) + for (int i = 0; i < points.Length; i++) { - Point[] points = { - rect.Location, // top left - new Point(rect.Location.X + rect.Size.Width, rect.Location.Y), // top right - new Point(rect.Location.X + rect.Size.Width, rect.Location.Y + rect.Size.Height), // bottom right - new Point(rect.Location.X, rect.Location.Y + rect.Size.Height), // bottom right - }; - - double sin = Math.Sin(rotation.Radians); - double cos = Math.Cos(rotation.Radians); - - for (int i = 0; i < points.Length; i++) - { - Point point = points[i]; - point = new Point(point.X - origin.X, point.Y - origin.Y); - point = new Point((point.X * cos) - (point.Y * sin), (point.X * sin) + (point.Y * cos)); - points[i] = new Point(point.X + origin.X, point.Y + origin.Y); - } - - return points; + Point point = points[i]; + point = new Point(point.X - origin.X, point.Y - origin.Y); + point = new Point((point.X * cos) - (point.Y * sin), (point.X * sin) + (point.Y * cos)); + points[i] = new Point(point.X + origin.X, point.Y + origin.Y); } - #endregion + return points; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Extensions/SurfaceExtensions.cs b/RGB.NET.Core/Extensions/SurfaceExtensions.cs new file mode 100644 index 00000000..67e5e3a1 --- /dev/null +++ b/RGB.NET.Core/Extensions/SurfaceExtensions.cs @@ -0,0 +1,84 @@ +// ReSharper disable UnusedMember.Global + +using System.Collections.Generic; +using System.Linq; + +namespace RGB.NET.Core; + +/// +/// Offers some extensions and helper-methods for the work with the surface. +/// +public static class SurfaceExtensions +{ + #region Methods + + /// + /// Initializes the specifiec device provider and attaches all devices. + /// + /// The surface to attach the devices to. + /// The device provider to load. + /// -flags to filter the devices to load. + /// Specifies if exceptions should be thrown or silently be ignored. + public static void Load(this RGBSurface surface, IRGBDeviceProvider deviceProvider, RGBDeviceType loadFilter = RGBDeviceType.All, bool throwExceptions = false) + { + if (!deviceProvider.IsInitialized) + deviceProvider.Initialize(loadFilter, throwExceptions); + + surface.Attach(deviceProvider.Devices); + } + + /// + /// Attaches the specified devices to the surface. + /// + /// The surface the devices are attached to. + /// The devices to attach. + public static void Attach(this RGBSurface surface, IEnumerable devices) + { + foreach (IRGBDevice device in devices) + surface.Attach(device); + } + + /// + /// Detaches the specified devices from the surface. + /// + /// The surface the devices are detached from. + /// The devices to detach. + public static void Detach(this RGBSurface surface, IEnumerable devices) + { + foreach (IRGBDevice device in devices) + surface.Detach(device); + } + + /// + /// Gets all devices of a specific type. + /// + /// The type of devices to get. + /// A collection of devices with the specified type. + public static IEnumerable GetDevices(this RGBSurface surface) + where T : class + => surface.Devices.Where(x => x is T).Cast(); + + /// + /// Gets all devices of the specified . + /// + /// The surface to get the devices from. + /// The of the devices to get. + /// A collection of devices matching the specified . + public static IEnumerable GetDevices(this RGBSurface surface, RGBDeviceType deviceType) + => surface.Devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType)); + + /// + /// Automatically aligns all devices to prevent overlaps. + /// + public static void AlignDevices(this RGBSurface surface) + { + float posX = 0; + foreach (IRGBDevice device in surface.Devices) + { + device.Location += new Point(posX, 0); + posX += device.ActualSize.Width + 1; + } + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Groups/AbstractLedGroup.cs b/RGB.NET.Core/Groups/AbstractLedGroup.cs index eab68038..6569dac9 100644 --- a/RGB.NET.Core/Groups/AbstractLedGroup.cs +++ b/RGB.NET.Core/Groups/AbstractLedGroup.cs @@ -1,51 +1,61 @@ -using System.Collections.Generic; +using System.Collections; +using System.Collections.Generic; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// +/// Represents a generic . +/// +public abstract class AbstractLedGroup : AbstractDecoratable, ILedGroup { - /// - /// - /// - /// Represents a generic . - /// - public abstract class AbstractLedGroup : AbstractDecoratable, ILedGroup - { - #region Properties & Fields + #region Properties & Fields - /// - public IBrush Brush { get; set; } + RGBSurface? ILedGroup.Surface { get; set; } - /// - public int ZIndex { get; set; } = 0; + /// + public RGBSurface? Surface => ((ILedGroup)this).Surface; - #endregion + /// + public IBrush? Brush { get; set; } - #region Constructors + /// + public int ZIndex { get; set; } = 0; - /// - /// Initializes a new instance of the class. - /// - /// Specifies whether this should be automatically attached or not. - protected AbstractLedGroup(bool autoAttach) - { - if (autoAttach) - RGBSurface.Instance.AttachLedGroup(this); - } + #endregion - #endregion + #region Constructors - #region Methods + /// + /// Initializes a new instance of the class. + /// + protected AbstractLedGroup(RGBSurface? attachTo) + { + attachTo?.Attach(this); + } - /// - public abstract IList GetLeds(); + #endregion - /// - public virtual void OnAttach() - { } + #region Methods - /// - public virtual void OnDetach() - { } + /// + /// Gets a enumerable containing all leds in this group. + /// + /// A enumerable containing all leds of this group. + protected abstract IEnumerable GetLeds(); - #endregion - } -} + /// + public virtual void OnAttach() { } + + /// + public virtual void OnDetach() { } + + /// + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator GetEnumerator() => GetLeds().GetEnumerator(); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Groups/ILedGroup.cs b/RGB.NET.Core/Groups/ILedGroup.cs index 5db5e639..88b5b976 100644 --- a/RGB.NET.Core/Groups/ILedGroup.cs +++ b/RGB.NET.Core/Groups/ILedGroup.cs @@ -3,38 +3,40 @@ using System.Collections.Generic; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a generic ledgroup. +/// +public interface ILedGroup : IDecoratable, IEnumerable { - /// /// - /// Represents a generic ledgroup. + /// Gets the surface this group is attached to or null if it is not attached to any surface. + /// + RGBSurface? Surface { get; internal set; } + + /// + /// Gets a bool indicating if the group is attached to a surface. + /// + bool IsAttached => Surface != null; + + /// + /// Gets or sets the which should be drawn over this . + /// + IBrush? Brush { get; set; } + + /// + /// Gets or sets the z-index of this to allow ordering them before drawing. (lowest first) (default: 0) + /// + int ZIndex { get; set; } + + /// + /// Called when the is attached to the . + /// + void OnAttach(); + + /// + /// Called when the is detached from the . /// - public interface ILedGroup : IDecoratable - { - /// - /// Gets or sets the which should be drawn over this . - /// - IBrush Brush { get; set; } - - /// - /// Gets or sets the z-index of this to allow ordering them before drawing. (lowest first) (default: 0) - /// - int ZIndex { get; set; } - - /// - /// Gets a list containing all of this . - /// - /// The list containing all of this . - IList GetLeds(); - - /// - /// Called when the is attached to the . - /// - void OnAttach(); - - /// - /// Called when the is detached from the . - /// - void OnDetach(); - } -} + void OnDetach(); +} \ No newline at end of file diff --git a/RGB.NET.Core/Groups/LedGroupExtension.cs b/RGB.NET.Core/Groups/LedGroupExtension.cs new file mode 100644 index 00000000..f6fd6d38 --- /dev/null +++ b/RGB.NET.Core/Groups/LedGroupExtension.cs @@ -0,0 +1,57 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +namespace RGB.NET.Core; + +/// +/// Offers some extensions and helper-methods for related things. +/// +public static class LedGroupExtension +{ + /// + /// Converts the specified to a . + /// + /// The to convert. + /// The converted . + public static ListLedGroup ToListLedGroup(this ILedGroup ledGroup) + { + // ReSharper disable once InvertIf + if (ledGroup is not ListLedGroup listLedGroup) + { + if (ledGroup.IsAttached) + ledGroup.Detach(); + listLedGroup = new ListLedGroup(ledGroup.Surface, ledGroup) { Brush = ledGroup.Brush, ZIndex = ledGroup.ZIndex }; + } + return listLedGroup; + } + + /// + /// Returns a new which contains all from the specified excluding the specified ones. + /// + /// The base . + /// The to exclude. + /// The new . + public static ListLedGroup Exclude(this ILedGroup ledGroup, params Led[] ledIds) + { + ListLedGroup listLedGroup = ledGroup.ToListLedGroup(); + foreach (Led led in ledIds) + listLedGroup.RemoveLed(led); + return listLedGroup; + } + + // ReSharper disable once UnusedMethodReturnValue.Global + /// + /// Attaches the specified to the . + /// + /// The to attach. + /// The to attach this group to. + /// true if the could be attached; otherwise, false. + public static bool Attach(this ILedGroup ledGroup, RGBSurface surface) => surface.Attach(ledGroup); + + /// + /// Detaches the specified from the . + /// + /// The to attach. + /// true if the could be detached; otherwise, false. + public static bool Detach(this ILedGroup ledGroup) => ledGroup.Surface?.Detach(ledGroup) ?? false; +} \ No newline at end of file diff --git a/RGB.NET.Core/Groups/ListLedGroup.cs b/RGB.NET.Core/Groups/ListLedGroup.cs new file mode 100644 index 00000000..a33fc56e --- /dev/null +++ b/RGB.NET.Core/Groups/ListLedGroup.cs @@ -0,0 +1,132 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using System.Collections.Generic; + +namespace RGB.NET.Core; + +/// +/// +/// Represents a ledgroup containing arbitrary . +/// +public class ListLedGroup : AbstractLedGroup +{ + #region Properties & Fields + + /// + /// Gets the list containing the of this . + /// + protected IList GroupLeds { get; } = new List(); + + #endregion + + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// Specifies the surface to attach this group to or null if the group should not be attached on creation. + public ListLedGroup(RGBSurface? surface) + : base(surface) + { } + + /// + /// + /// Initializes a new instance of the class. + /// + /// Specifies the surface to attach this group to or null if the group should not be attached on creation. + /// The initial of this . + public ListLedGroup(RGBSurface? surface, IEnumerable leds) + : base(surface) + { + AddLeds(leds); + } + + /// + /// + /// Initializes a new instance of the class. + /// + /// Specifies the surface to attach this group to or null if the group should not be attached on creation. + /// The initial of this . + public ListLedGroup(RGBSurface? surface, params Led[] leds) + : base(surface) + { + AddLeds(leds); + } + + #endregion + + #region Methods + + /// + /// Adds the specified LED(s) to this . + /// + /// The LED(s) to add. + public void AddLed(params Led[] leds) => AddLeds(leds); + + /// + /// Adds the specified to this . + /// + /// The to add. + public void AddLeds(IEnumerable leds) + { + lock (GroupLeds) + foreach (Led led in leds) + if (!ContainsLed(led)) + GroupLeds.Add(led); + } + + /// + /// Removes the specified LED(s) from this . + /// + /// The LED(s) to remove. + public void RemoveLed(params Led[] leds) => RemoveLeds(leds); + + /// + /// Removes the specified from this . + /// + /// The to remove. + public void RemoveLeds(IEnumerable leds) + { + lock (GroupLeds) + foreach (Led led in leds) + GroupLeds.Remove(led); + } + + /// + /// Checks if a specified LED is contained by this ledgroup. + /// + /// The LED which should be checked. + /// true if the LED is contained by this ledgroup; otherwise, false. + public bool ContainsLed(Led led) + { + lock (GroupLeds) + return GroupLeds.Contains(led); + } + + /// + /// Merges the from the specified ledgroup in this ledgroup. + /// + /// The ledgroup to merge. + public void MergeLeds(ILedGroup groupToMerge) + { + lock (GroupLeds) + foreach (Led led in groupToMerge) + if (!GroupLeds.Contains(led)) + GroupLeds.Add(led); + } + + /// + /// + /// Gets a list containing the from this group. + /// + /// The list containing the . + protected override IEnumerable GetLeds() + { + lock (GroupLeds) + return new List(GroupLeds); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Helper/ConversionHelper.cs b/RGB.NET.Core/Helper/ConversionHelper.cs index cf96a36b..0be3dfbc 100644 --- a/RGB.NET.Core/Helper/ConversionHelper.cs +++ b/RGB.NET.Core/Helper/ConversionHelper.cs @@ -1,60 +1,61 @@ -namespace RGB.NET.Core +using System; + +namespace RGB.NET.Core; + +/// +/// Contains helper methods for converting things. +/// +public static class ConversionHelper { + #region Methods + + // Source: https://web.archive.org/web/20180224104425/https://stackoverflow.com/questions/623104/byte-to-hex-string/3974535 /// - /// Contains helper methods for converting things. + /// Converts an array of bytes to a HEX-representation. /// - public static class ConversionHelper + /// The array of bytes. + /// The HEX-representation of the provided bytes. + public static string ToHex(params byte[] bytes) { - #region Methods - - // Source: https://web.archive.org/web/20180224104425/https://stackoverflow.com/questions/623104/byte-to-hex-string/3974535 - /// - /// Converts an array of bytes to a HEX-representation. - /// - /// The array of bytes. - /// The HEX-representation of the provided bytes. - public static string ToHex(params byte[] bytes) + char[] c = new char[bytes.Length * 2]; + + for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx) { - char[] c = new char[bytes.Length * 2]; + byte b = ((byte)(bytes[bx] >> 4)); + c[cx] = (char)(b > 9 ? b + 0x37 : b + 0x30); - for (int bx = 0, cx = 0; bx < bytes.Length; ++bx, ++cx) - { - byte b = ((byte)(bytes[bx] >> 4)); - c[cx] = (char)(b > 9 ? b + 0x37: b + 0x30); + b = ((byte)(bytes[bx] & 0x0F)); + c[++cx] = (char)(b > 9 ? b + 0x37 : b + 0x30); + } - b = ((byte)(bytes[bx] & 0x0F)); - c[++cx] = (char)(b > 9 ? b + 0x37: b + 0x30); - } + return new string(c); + } - return new string(c); - } + // Source: https://web.archive.org/web/20180224104425/https://stackoverflow.com/questions/623104/byte-to-hex-string/3974535 + /// + /// Converts the HEX-representation of a byte array to that array. + /// + /// The HEX-string to convert. + /// The correspondending byte array. + public static byte[] HexToBytes(ReadOnlySpan hexString) + { + if ((hexString.Length == 0) || ((hexString.Length % 2) != 0)) + return Array.Empty(); - // Source: https://web.archive.org/web/20180224104425/https://stackoverflow.com/questions/623104/byte-to-hex-string/3974535 - /// - /// Converts the HEX-representation of a byte array to that array. - /// - /// The HEX-string to convert. - /// The correspondending byte array. - public static byte[] HexToBytes(string hexString) + byte[] buffer = new byte[hexString.Length / 2]; + for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx) { - if ((hexString.Length == 0) || ((hexString.Length % 2) != 0)) - return new byte[0]; - - byte[] buffer = new byte[hexString.Length / 2]; - for (int bx = 0, sx = 0; bx < buffer.Length; ++bx, ++sx) - { - // Convert first half of byte - char c = hexString[sx]; - buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? ((c - 'a') + 10) : ((c - 'A') + 10)) : (c - '0')) << 4); - - // Convert second half of byte - c = hexString[++sx]; - buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? ((c - 'a') + 10) : ((c - 'A') + 10)) : (c - '0')); - } - - return buffer; + // Convert first half of byte + char c = hexString[sx]; + buffer[bx] = (byte)((c > '9' ? (c > 'Z' ? ((c - 'a') + 10) : ((c - 'A') + 10)) : (c - '0')) << 4); + + // Convert second half of byte + c = hexString[++sx]; + buffer[bx] |= (byte)(c > '9' ? (c > 'Z' ? ((c - 'a') + 10) : ((c - 'A') + 10)) : (c - '0')); } - #endregion + return buffer; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Helper/CultureHelper.cs b/RGB.NET.Core/Helper/CultureHelper.cs deleted file mode 100644 index 3ea900ab..00000000 --- a/RGB.NET.Core/Helper/CultureHelper.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Globalization; -using System.Runtime.InteropServices; - -namespace RGB.NET.Core -{ - /// - /// Offers some helper-methods for culture related things. - /// - public static class CultureHelper - { - #region DLLImports - - [DllImport("user32.dll")] - private static extern IntPtr GetKeyboardLayout(uint thread); - - #endregion - - #region Constructors - - #endregion - - #region Methods - - /// - /// Gets the current keyboard-layout from the OS. - /// - /// The current keyboard-layout - public static CultureInfo GetCurrentCulture() - { - try - { - int keyboardLayout = GetKeyboardLayout(0).ToInt32() & 0xFFFF; - return new CultureInfo(keyboardLayout); - } - catch - { - return new CultureInfo(1033); // en-US on error. - } - } - - #endregion - } -} diff --git a/RGB.NET.Core/Helper/DeviceHelper.cs b/RGB.NET.Core/Helper/DeviceHelper.cs new file mode 100644 index 00000000..0fd9f9b7 --- /dev/null +++ b/RGB.NET.Core/Helper/DeviceHelper.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace RGB.NET.Core; + +/// +/// Offsers some helper methods for device creation. +/// +public static class DeviceHelper +{ + #region Methods + + /// + /// Creates a unique device name from a manufacturer and model name. + /// + /// + /// The id is made unique based on the assembly calling this method. + /// + /// The manufacturer of the device. + /// The model of the device. + /// The unique identifier for this device. + [MethodImpl(MethodImplOptions.NoInlining)] + public static string CreateDeviceName(string manufacturer, string model) => IdGenerator.MakeUnique(Assembly.GetCallingAssembly(), $"{manufacturer} {model}"); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Helper/PathHelper.cs b/RGB.NET.Core/Helper/PathHelper.cs deleted file mode 100644 index d67e5b72..00000000 --- a/RGB.NET.Core/Helper/PathHelper.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.IO; -using System.Reflection; - -namespace RGB.NET.Core -{ - /// - /// Offers some helper-methods for file-path related things. - /// - public static class PathHelper - { - #region Events - - /// - /// Occurs when a path is resolving. - /// - public static event EventHandler ResolvingAbsolutePath; - - #endregion - - #region Methods - - /// - /// Returns an absolute path created from an relative path relatvie to the location of the executung assembly. - /// - /// The relative part of the path to convert. - /// The absolute path. - public static string GetAbsolutePath(string relativePath) => GetAbsolutePath((object)null, relativePath); - - /// - /// Returns an absolute path created from an relative path relatvie to the location of the executung assembly. - /// - /// The relative part of the path to convert. - /// The file name of the path to convert. - /// The absolute path. - public static string GetAbsolutePath(string relativePath, string fileName) => GetAbsolutePath(null, relativePath, fileName); - - /// - /// Returns an absolute path created from an relative path relatvie to the location of the executung assembly. - /// - /// The requester of this path. (Used for better control when using the event to override this behavior.) - /// The relative path to convert. - /// The file name of the path to convert. - /// The absolute path. - public static string GetAbsolutePath(object sender, string relativePath, string fileName) - { - string relativePart = Path.Combine(relativePath, fileName); - - string assemblyLocation = Assembly.GetEntryAssembly()?.Location; - if (assemblyLocation == null) return relativePart; - - string directoryName = Path.GetDirectoryName(assemblyLocation); - string path = directoryName == null ? null : Path.Combine(directoryName, relativePart); - - ResolvePathEventArgs args = new ResolvePathEventArgs(relativePath, fileName, path); - ResolvingAbsolutePath?.Invoke(sender, args); - - return args.FinalPath; - } - - /// - /// Returns an absolute path created from an relative path relatvie to the location of the executung assembly. - /// - /// The requester of this path. (Used for better control when using the event to override this behavior.) - /// The relative path to convert. - /// The absolute path. - public static string GetAbsolutePath(object sender, string relativePath) - { - string assemblyLocation = Assembly.GetEntryAssembly()?.Location; - if (assemblyLocation == null) return relativePath; - - string directoryName = Path.GetDirectoryName(assemblyLocation); - string path = directoryName == null ? null : Path.Combine(directoryName, relativePath); - - ResolvePathEventArgs args = new ResolvePathEventArgs(relativePath, path); - ResolvingAbsolutePath?.Invoke(sender, args); - - return args.FinalPath; - } - - #endregion - } -} diff --git a/RGB.NET.Core/Helper/TimerHelper.cs b/RGB.NET.Core/Helper/TimerHelper.cs new file mode 100644 index 00000000..432170bf --- /dev/null +++ b/RGB.NET.Core/Helper/TimerHelper.cs @@ -0,0 +1,178 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Threading; + +namespace RGB.NET.Core; + +/// +/// Offers some helper methods for timed operations. +/// +public static class TimerHelper +{ + #region DLL-Imports + + [DllImport("winmm.dll", EntryPoint = "timeBeginPeriod")] + private static extern void TimeBeginPeriod(int t); + + [DllImport("winmm.dll", EntryPoint = "timeEndPeriod")] + private static extern void TimeEndPeriod(int t); + + #endregion + + #region Properties & Fields + + private static readonly object HIGH_RESOLUTION_TIMER_LOCK = new(); + + private static bool _areHighResolutionTimersEnabled = false; + + private static bool _useHighResolutionTimers = true; + /// + /// Gets or sets if High Resolution Timers should be used. + /// + public static bool UseHighResolutionTimers + { + get => _useHighResolutionTimers; + set + { + lock (HIGH_RESOLUTION_TIMER_LOCK) + { + _useHighResolutionTimers = value; + CheckHighResolutionTimerUsage(); + } + } + } + + // ReSharper disable once InconsistentNaming + private static readonly HashSet _timerLeases = new(); + + #endregion + + #region Methods + + /// + /// Executes the provided action and blocks if needed until the the has passed. + /// + /// The action to execute. + /// The time in ms this method should block. default: 0 + /// The time in ms spent executing the . + public static double Execute(Action action, double targetExecuteTime = 0) + { + long preUpdateTicks = Stopwatch.GetTimestamp(); + + action(); + + double updateTime = GetElapsedTime(preUpdateTicks); + + if (targetExecuteTime > 0) + { + int sleep = (int)(targetExecuteTime - updateTime); + if (sleep > 0) + Thread.Sleep(sleep); + } + + return updateTime; + } + + /// + /// Calculates the elapsed time in ms from the provided timestamp until now. + /// + /// The initial timestamp to calculate the time from. + /// The elapsed time in ms. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static double GetElapsedTime(long initialTimestamp) => ((Stopwatch.GetTimestamp() - initialTimestamp) / (Stopwatch.Frequency / 1000.0)); + + /// + /// Requests to use to use High Resolution Timers if enabled. + /// IMPORTANT: Always dispose the returned disposable if High Resolution Timers are no longer needed for the caller. + /// + /// A disposable to remove the request. + public static IDisposable RequestHighResolutionTimer() + { + HighResolutionTimerDisposable timerLease = new(); + lock (HIGH_RESOLUTION_TIMER_LOCK) + { + _timerLeases.Add(timerLease); + CheckHighResolutionTimerUsage(); + } + + return timerLease; + } + + private static void CheckHighResolutionTimerUsage() + { + if (UseHighResolutionTimers && (_timerLeases.Count > 0)) + EnableHighResolutionTimers(); + else + DisableHighResolutionTimers(); + } + + private static void EnableHighResolutionTimers() + { + lock (HIGH_RESOLUTION_TIMER_LOCK) + { + if (_areHighResolutionTimersEnabled) return; + + // DarthAffe 06.05.2022: Linux should use 1ms timers by default + if (OperatingSystem.IsWindows()) + TimeBeginPeriod(1); + + _areHighResolutionTimersEnabled = true; + } + } + + private static void DisableHighResolutionTimers() + { + lock (HIGH_RESOLUTION_TIMER_LOCK) + { + if (!_areHighResolutionTimersEnabled) return; + + if (OperatingSystem.IsWindows()) + TimeEndPeriod(1); + + _areHighResolutionTimersEnabled = false; + } + } + + /// + /// Disposes all open High Resolution Timer Requests. + /// This should be called once when exiting the application to make sure nothing remains open and the application correctly unregisters itself on OS level. + /// Shouldn't be needed if everything is disposed, but better safe then sorry. + /// + public static void DisposeAllHighResolutionTimerRequests() + { + List timerLeases = new(_timerLeases); + foreach (HighResolutionTimerDisposable timer in timerLeases) + timer.Dispose(); + } + + #endregion + + private class HighResolutionTimerDisposable : IDisposable + { + #region Properties & Fields + + private bool _isDisposed = false; + + #endregion + + #region Methods + + public void Dispose() + { + if (_isDisposed) return; + + _isDisposed = true; + + lock (HIGH_RESOLUTION_TIMER_LOCK) + { + _timerLeases.Remove(this); + CheckHighResolutionTimerUsage(); + } + } + + #endregion + } +} \ No newline at end of file diff --git a/RGB.NET.Core/Ids/IdGenerator.cs b/RGB.NET.Core/Ids/IdGenerator.cs new file mode 100644 index 00000000..99beaa68 --- /dev/null +++ b/RGB.NET.Core/Ids/IdGenerator.cs @@ -0,0 +1,74 @@ +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.CompilerServices; + +namespace RGB.NET.Core; + +/// +/// Offers some methods to create and handle unique identifiers. +/// +public static class IdGenerator +{ + #region Properties & Fields + + // ReSharper disable InconsistentNaming + private static readonly HashSet _registeredIds = new(); + private static readonly Dictionary> _idMappings = new(); + private static readonly Dictionary> _counter = new(); + // ReSharper restore InconsistentNaming + + #endregion + + #region Methods + + /// + /// Makes the specified id unique based on the calling assembly by adding a counter if needed. + /// + /// The id to make unique. + /// The unique id. + [MethodImpl(MethodImplOptions.NoInlining)] + public static string MakeUnique(string id) => MakeUnique(Assembly.GetCallingAssembly(), id); + + internal static string MakeUnique(Assembly callingAssembly, string id) + { + if (!_idMappings.TryGetValue(callingAssembly, out Dictionary? idMapping)) + { + _idMappings.Add(callingAssembly, idMapping = new Dictionary()); + _counter.Add(callingAssembly, new Dictionary()); + } + + Dictionary counterMapping = _counter[callingAssembly]; + + if (!idMapping.TryGetValue(id, out string? mappedId)) + { + mappedId = id; + int mappingCounter = 1; + while (_registeredIds.Contains(mappedId)) + mappedId = $"{id} ({++mappingCounter})"; + + _registeredIds.Add(mappedId); + idMapping.Add(id, mappedId); + } + + if (!counterMapping.ContainsKey(mappedId)) + counterMapping.Add(mappedId, 0); + + int counter = ++counterMapping[mappedId]; + return counter <= 1 ? mappedId : $"{mappedId} ({counter})"; + } + + /// + /// Resets the counter used to create unique ids. + /// All previous generated ids are not garantueed to stay unique if this is called! + /// + [MethodImpl(MethodImplOptions.NoInlining)] + public static void ResetCounter() => ResetCounter(Assembly.GetCallingAssembly()); + + internal static void ResetCounter(Assembly callingAssembly) + { + if (_counter.TryGetValue(callingAssembly, out Dictionary? counter)) + counter.Clear(); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Leds/Led.cs b/RGB.NET.Core/Leds/Led.cs index 67cea337..ad2e3f9f 100644 --- a/RGB.NET.Core/Leds/Led.cs +++ b/RGB.NET.Core/Leds/Led.cs @@ -1,310 +1,175 @@ // ReSharper disable MemberCanBePrivate.Global -using System; -using System.ComponentModel; using System.Diagnostics; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// Represents a single LED of a RGB-device. +/// +[DebuggerDisplay("{Id} {Color}")] +public class Led : Placeable { - /// + #region Properties & Fields + /// - /// Represents a single LED of a RGB-device. + /// Gets the this is associated with. /// - [DebuggerDisplay("{Id} {Color}")] - public class Led : AbstractBindable - { - #region Properties & Fields - - /// - /// Gets the this is associated with. - /// - public IRGBDevice Device { get; } - - /// - /// Gets the of the . - /// - public LedId Id { get; } - - private Shape _shape = Shape.Rectangle; - /// - /// Gets or sets the of the . - /// - public Shape Shape - { - get => _shape; - set => SetProperty(ref _shape, value); - } - - private string _shapeData; - /// - /// Gets or sets the data used for by the -. - /// - public string ShapeData - { - get => _shapeData; - set => SetProperty(ref _shapeData, value); - } - - private Point _location; - /// - /// Gets or sets the relative location of the . - /// - public Point Location - { - get => _location; - set - { - if (SetProperty(ref _location, value)) - { - UpdateActualData(); - UpdateAbsoluteData(); - } - } - } + public IRGBDevice Device { get; } - private Size _size; - /// - /// Gets or sets the size of the . - /// - public Size Size - { - get => _size; - set - { - if (SetProperty(ref _size, value)) - { - UpdateActualData(); - UpdateAbsoluteData(); - } - } - } - - private Point _actualLocation; - /// - /// Gets the actual location of the . - /// This includes device-scaling and rotation. - /// - public Point ActualLocation - { - get => _actualLocation; - private set => SetProperty(ref _actualLocation, value); - } - - private Size _actualSize; - /// - /// Gets the actual size of the . - /// This includes device-scaling. - /// - public Size ActualSize - { - get => _actualSize; - private set => SetProperty(ref _actualSize, value); - } - - private Rectangle _ledRectangle; - /// - /// Gets a rectangle representing the logical location of the relative to the . - /// - public Rectangle LedRectangle - { - get => _ledRectangle; - private set => SetProperty(ref _ledRectangle, value); - } - - private Rectangle _absoluteLedRectangle; - /// - /// Gets a rectangle representing the logical location of the on the . - /// - public Rectangle AbsoluteLedRectangle - { - get => _absoluteLedRectangle; - private set => SetProperty(ref _absoluteLedRectangle, value); - } - - /// - /// Indicates whether the is about to change it's color. - /// - public bool IsDirty => RequestedColor.HasValue && (RequestedColor != InternalColor); + /// + /// Gets the of the . + /// + public LedId Id { get; } - private Color? _requestedColor; - /// - /// Gets a copy of the the LED should be set to on the next update. - /// Null if there is no update-request for the next update. - /// - public Color? RequestedColor - { - get => _requestedColor; - private set - { - SetProperty(ref _requestedColor, value); + private Shape _shape = Shape.Rectangle; + /// + /// Gets or sets the of the . + /// + public Shape Shape + { + get => _shape; + set => SetProperty(ref _shape, value); + } - // ReSharper disable once ExplicitCallerInfoArgument - OnPropertyChanged(nameof(IsDirty)); - } - } + private string? _shapeData; + /// + /// Gets or sets the data used for by the -. + /// + public string? ShapeData + { + get => _shapeData; + set => SetProperty(ref _shapeData, value); + } - private Color _color = Color.Transparent; - /// - /// Gets the current of the . Sets the for the next update. - /// - public Color Color - { - get => _color; - set - { - if (!IsLocked) - { - if (RequestedColor.HasValue) - RequestedColor += value; - else - RequestedColor = value; - } + private Rectangle _absoluteBoundary; + /// + /// Gets a rectangle representing the logical location of the on the . + /// + public Rectangle AbsoluteBoundary + { + get => _absoluteBoundary; + private set => SetProperty(ref _absoluteBoundary, value); + } - } - } + /// + /// Indicates whether the is about to change it's color. + /// + public bool IsDirty => RequestedColor.HasValue && (RequestedColor != Color); - /// - /// Gets or set the ignoring all workflows regarding locks and update-requests. /> - /// - internal Color InternalColor + private Color? _requestedColor; + /// + /// Gets a copy of the the LED should be set to on the next update. + /// Null if there is no update-request for the next update. + /// + public Color? RequestedColor + { + get => _requestedColor; + private set { - get => _color; - set => SetProperty(ref _color, value); - } + SetProperty(ref _requestedColor, value); - private bool _isLocked; - /// - /// Gets or sets if the color of this LED can be changed. - /// - public bool IsLocked - { - get => _isLocked; - set => SetProperty(ref _isLocked, value); + // ReSharper disable once ExplicitCallerInfoArgument + OnPropertyChanged(nameof(IsDirty)); } + } - /// - /// Gets the URI of an image of the or null if there is no image. - /// - public Uri Image { get; set; } - - /// - /// Gets the provider-specific data associated with this led. - /// - public object CustomData { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The the is associated with. - /// The of the . - /// The physical location of the relative to the . - /// The size of the . - /// The provider-specific data associated with this led. - internal Led(IRGBDevice device, LedId id, Point location, Size size, object customData = null) + private Color _color = Color.Transparent; + /// + /// Gets the current of the . Sets the for the next update. + /// + public Color Color + { + get => _color; + set { - this.Device = device; - this.Id = id; - this.Location = location; - this.Size = size; - this.CustomData = customData; - - device.PropertyChanged += DevicePropertyChanged; + if (RequestedColor.HasValue) + RequestedColor = RequestedColor.Value + value; + else + RequestedColor = _color + value; } + } - #endregion - - #region Methods - - private void DevicePropertyChanged(object sender, PropertyChangedEventArgs e) - { - if ((e.PropertyName == nameof(IRGBDevice.Location))) - UpdateAbsoluteData(); - else if (e.PropertyName == nameof(IRGBDevice.DeviceRectangle)) - { - UpdateActualData(); - UpdateAbsoluteData(); - } - } + /// + /// Gets the provider-specific data associated with this led. + /// + public object? CustomData { get; } - private void UpdateActualData() - { - ActualSize = Size * Device.Scale; + /// + /// Gets or sets some custom metadata of this led. + /// + public object? LayoutMetadata { get; set; } - Point actualLocation = (Location * Device.Scale); - Rectangle ledRectangle = new Rectangle(Location * Device.Scale, Size * Device.Scale); + #endregion - if (Device.Rotation.IsRotated) - { - Point deviceCenter = new Rectangle(Device.ActualSize).Center; - Point actualDeviceCenter = new Rectangle(Device.DeviceRectangle.Size).Center; - Point centerOffset = new Point(actualDeviceCenter.X - deviceCenter.X, actualDeviceCenter.Y - deviceCenter.Y); + #region Constructors - actualLocation = actualLocation.Rotate(Device.Rotation, new Rectangle(Device.ActualSize).Center) + centerOffset; - ledRectangle = new Rectangle(ledRectangle.Rotate(Device.Rotation, new Rectangle(Device.ActualSize).Center)).Translate(centerOffset); - } + /// + /// Initializes a new instance of the class. + /// + /// The the is associated with. + /// The of the . + /// The physical location of the relative to the . + /// The size of the . + /// The provider-specific data associated with this led. + internal Led(IRGBDevice device, LedId id, Point location, Size size, object? customData = null) + : base(device) + { + this.Device = device; + this.Id = id; + this.Location = location; + this.Size = size; + this.CustomData = customData; + } - ActualLocation = actualLocation; - LedRectangle = ledRectangle; - } + #endregion - private void UpdateAbsoluteData() - { - AbsoluteLedRectangle = LedRectangle.Translate(Device.Location); - } + #region Methods - /// - /// Converts the and the of this to a human-readable string. - /// - /// A string that contains the and the of this . For example "Enter [A: 255, R: 255, G: 0, B: 0]". - public override string ToString() => $"{Id} {Color}"; + /// + protected override void UpdateActualPlaceableData() + { + base.UpdateActualPlaceableData(); - /// - /// Updates the to the requested . - /// - internal void Update() - { - if (!RequestedColor.HasValue) return; + AbsoluteBoundary = Boundary.Translate(Device.Location); + } - _color = RequestedColor.Value; - RequestedColor = null; + /// + /// Converts the and the of this to a human-readable string. + /// + /// A string that contains the and the of this . For example "Enter [A: 255, R: 255, G: 0, B: 0]". + public override string ToString() => $"{Id} {Color}"; - // ReSharper disable once ExplicitCallerInfoArgument - OnPropertyChanged(nameof(Color)); - } + /// + /// Updates the to the requested . + /// + internal void Update() + { + if (!RequestedColor.HasValue) return; - /// - /// Resets the back to default. - /// - internal void Reset() - { - _color = Color.Transparent; - RequestedColor = null; - IsLocked = false; + _color = RequestedColor.Value; + RequestedColor = null; - // ReSharper disable once ExplicitCallerInfoArgument - OnPropertyChanged(nameof(Color)); - } + // ReSharper disable once ExplicitCallerInfoArgument + OnPropertyChanged(nameof(Color)); + } - #endregion + #endregion - #region Operators + #region Operators - /// - /// Converts a to a . - /// - /// The to convert. - public static implicit operator Color(Led led) => led?.Color ?? Color.Transparent; + /// + /// Converts a to a . + /// + /// The to convert. + public static implicit operator Color(Led led) => led.Color; - /// - /// Converts a to a . - /// - /// The to convert. - public static implicit operator Rectangle(Led led) => led?.LedRectangle ?? new Rectangle(); + /// + /// Converts a to a . + /// + /// The to convert. + public static implicit operator Rectangle(Led led) => led.Boundary; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Leds/LedId.cs b/RGB.NET.Core/Leds/LedId.cs index 536263e3..dff98a5d 100644 --- a/RGB.NET.Core/Leds/LedId.cs +++ b/RGB.NET.Core/Leds/LedId.cs @@ -3,1363 +3,8338 @@ #pragma warning disable 1591 // Missing XML comment for publicly visible type or member -namespace RGB.NET.Core +namespace RGB.NET.Core; + +public enum LedId { - public enum LedId - { - Invalid = -1, + Invalid = -1, + + Logo = 0, - Logo = 0, + /*### Keyboard ###*/ + Keyboard_Escape = 0x00000001, + Keyboard_F1 = 0x00000002, + Keyboard_F2 = 0x00000003, + Keyboard_F3 = 0x00000004, + Keyboard_F4 = 0x00000005, + Keyboard_F5 = 0x00000006, + Keyboard_F6 = 0x00000007, + Keyboard_F7 = 0x00000008, + Keyboard_F8 = 0x00000009, + Keyboard_F9 = 0x0000000A, + Keyboard_F10 = 0x0000000B, + Keyboard_F11 = 0x0000000C, + Keyboard_F12 = 0x0000000D, + Keyboard_GraveAccentAndTilde = 0x0000000E, + Keyboard_1 = 0x0000000F, + Keyboard_2 = 0x00000011, + Keyboard_3 = 0x00000012, + Keyboard_4 = 0x00000013, + Keyboard_5 = 0x00000014, + Keyboard_6 = 0x00000015, + Keyboard_7 = 0x00000016, + Keyboard_8 = 0x00000017, + Keyboard_9 = 0x00000018, + Keyboard_0 = 0x00000019, + Keyboard_MinusAndUnderscore = 0x0000001A, + Keyboard_EqualsAndPlus = 0x0000001B, + Keyboard_Backspace = 0x0000001C, + Keyboard_Tab = 0x0000001D, + Keyboard_Q = 0x0000001E, + Keyboard_W = 0x0000001F, + Keyboard_E = 0x00000020, + Keyboard_R = 0x00000021, + Keyboard_T = 0x00000022, + Keyboard_Y = 0x00000023, + Keyboard_U = 0x00000024, + Keyboard_I = 0x00000025, + Keyboard_O = 0x00000026, + Keyboard_P = 0x00000027, + Keyboard_BracketLeft = 0x000000028, + Keyboard_BracketRight = 0x000000029, + Keyboard_Backslash = 0x00000002A, + Keyboard_Enter = 0x0000002B, + Keyboard_CapsLock = 0x0000002C, + Keyboard_A = 0x0000002D, + Keyboard_S = 0x0000002E, + Keyboard_D = 0x0000002F, + Keyboard_F = 0x00000030, + Keyboard_G = 0x00000031, + Keyboard_H = 0x00000032, + Keyboard_J = 0x00000033, + Keyboard_K = 0x00000034, + Keyboard_L = 0x00000035, + Keyboard_SemicolonAndColon = 0x00000036, + Keyboard_ApostropheAndDoubleQuote = 0x00000037, + Keyboard_NonUsTilde = 0x00000038, + Keyboard_LeftShift = 0x00000039, + Keyboard_NonUsBackslash = 0x0000003A, + Keyboard_Z = 0x0000003B, + Keyboard_X = 0x0000003C, + Keyboard_C = 0x0000003D, + Keyboard_V = 0x0000003E, + Keyboard_B = 0x0000003F, + Keyboard_N = 0x00000040, + Keyboard_M = 0x00000041, + Keyboard_CommaAndLessThan = 0x00000042, + Keyboard_PeriodAndBiggerThan = 0x00000043, + Keyboard_SlashAndQuestionMark = 0x00000044, + Keyboard_RightShift = 0x00000045, + Keyboard_LeftCtrl = 0x00000046, + Keyboard_LeftGui = 0x00000047, + Keyboard_LeftAlt = 0x00000048, + Keyboard_Lang2 = 0x00000049, + Keyboard_Space = 0x0000004A, + Keyboard_Lang1 = 0x0000004B, + Keyboard_RightAlt = 0x0000004C, + Keyboard_RightGui = 0x0000004D, + Keyboard_Application = 0x0000004E, + Keyboard_RightCtrl = 0x0000004F, + Keyboard_International1 = 0x00000050, + Keyboard_International2 = 0x00000051, + Keyboard_International3 = 0x00000052, + Keyboard_International5 = 0x00000053, + Keyboard_International4 = 0x00000054, + Keyboard_Function = 0x00000055, - /*### Keyboard ###*/ - Keyboard_Escape = 0x00000001, - Keyboard_F1 = 0x00000002, - Keyboard_F2 = 0x00000003, - Keyboard_F3 = 0x00000004, - Keyboard_F4 = 0x00000005, - Keyboard_F5 = 0x00000006, - Keyboard_F6 = 0x00000007, - Keyboard_F7 = 0x00000008, - Keyboard_F8 = 0x00000009, - Keyboard_F9 = 0x0000000A, - Keyboard_F10 = 0x0000000B, - Keyboard_F11 = 0x0000000C, - Keyboard_F12 = 0x0000000D, - Keyboard_GraveAccentAndTilde = 0x0000000E, - Keyboard_1 = 0x0000000F, - Keyboard_2 = 0x00000011, - Keyboard_3 = 0x00000012, - Keyboard_4 = 0x00000013, - Keyboard_5 = 0x00000014, - Keyboard_6 = 0x00000015, - Keyboard_7 = 0x00000016, - Keyboard_8 = 0x00000017, - Keyboard_9 = 0x00000018, - Keyboard_0 = 0x00000019, - Keyboard_MinusAndUnderscore = 0x0000001A, - Keyboard_EqualsAndPlus = 0x0000001B, - Keyboard_Backspace = 0x0000001C, - Keyboard_Tab = 0x0000001D, - Keyboard_Q = 0x0000001E, - Keyboard_W = 0x0000001F, - Keyboard_E = 0x00000020, - Keyboard_R = 0x00000021, - Keyboard_T = 0x00000022, - Keyboard_Y = 0x00000023, - Keyboard_U = 0x00000024, - Keyboard_I = 0x00000025, - Keyboard_O = 0x00000026, - Keyboard_P = 0x00000027, - Keyboard_BracketLeft = 0x000000028, - Keyboard_BracketRight = 0x000000029, - Keyboard_Backslash = 0x00000002A, - Keyboard_Enter = 0x0000002B, - Keyboard_CapsLock = 0x0000002C, - Keyboard_A = 0x0000002D, - Keyboard_S = 0x0000002E, - Keyboard_D = 0x0000002F, - Keyboard_F = 0x00000030, - Keyboard_G = 0x00000031, - Keyboard_H = 0x00000032, - Keyboard_J = 0x00000033, - Keyboard_K = 0x00000034, - Keyboard_L = 0x00000035, - Keyboard_SemicolonAndColon = 0x00000036, - Keyboard_ApostropheAndDoubleQuote = 0x00000037, - Keyboard_NonUsTilde = 0x00000038, - Keyboard_LeftShift = 0x00000039, - Keyboard_NonUsBackslash = 0x0000003A, - Keyboard_Z = 0x0000003B, - Keyboard_X = 0x0000003C, - Keyboard_C = 0x0000003D, - Keyboard_V = 0x0000003E, - Keyboard_B = 0x0000003F, - Keyboard_N = 0x00000040, - Keyboard_M = 0x00000041, - Keyboard_CommaAndLessThan = 0x00000042, - Keyboard_PeriodAndBiggerThan = 0x00000043, - Keyboard_SlashAndQuestionMark = 0x00000044, - Keyboard_RightShift = 0x00000045, - Keyboard_LeftCtrl = 0x00000046, - Keyboard_LeftGui = 0x00000047, - Keyboard_LeftAlt = 0x00000048, - Keyboard_Lang2 = 0x00000049, - Keyboard_Space = 0x0000004A, - Keyboard_Lang1 = 0x0000004B, - Keyboard_RightAlt = 0x0000004C, - Keyboard_RightGui = 0x0000004D, - Keyboard_Application = 0x0000004E, - Keyboard_RightCtrl = 0x0000004F, - Keyboard_International1 = 0x00000050, - Keyboard_International2 = 0x00000051, - Keyboard_International3 = 0x00000052, - Keyboard_International5 = 0x00000053, - Keyboard_International4 = 0x00000054, + Keyboard_PrintScreen = 0x00001001, + Keyboard_ScrollLock = 0x000001002, + Keyboard_PauseBreak = 0x000001003, + Keyboard_Insert = 0x00001004, + Keyboard_Home = 0x00001005, + Keyboard_PageUp = 0x00001006, + Keyboard_Delete = 0x00001007, + Keyboard_End = 0x00001008, + Keyboard_PageDown = 0x00001009, + Keyboard_ArrowUp = 0x0000100A, + Keyboard_ArrowLeft = 0x0000100B, + Keyboard_ArrowDown = 0x0000100C, + Keyboard_ArrowRight = 0x0000100D, - Keyboard_PrintScreen = 0x00001001, - Keyboard_ScrollLock = 0x000001002, - Keyboard_PauseBreak = 0x000001003, - Keyboard_Insert = 0x00001004, - Keyboard_Home = 0x00001005, - Keyboard_PageUp = 0x00001006, - Keyboard_Delete = 0x00001007, - Keyboard_End = 0x00001008, - Keyboard_PageDown = 0x00001009, - Keyboard_ArrowUp = 0x0000100A, - Keyboard_ArrowLeft = 0x0000100B, - Keyboard_ArrowDown = 0x0000100C, - Keyboard_ArrowRight = 0x0000100D, + Keyboard_NumLock = 0x00002001, + Keyboard_NumSlash = 0x00002002, + Keyboard_NumAsterisk = 0x00002003, + Keyboard_NumMinus = 0x00002004, + Keyboard_Num7 = 0x00002005, + Keyboard_Num8 = 0x00002006, + Keyboard_Num9 = 0x00002007, + Keyboard_NumComma = 0x00002008, + Keyboard_NumPlus = 0x00002009, + Keyboard_Num4 = 0x0000200A, + Keyboard_Num5 = 0x0000200B, + Keyboard_Num6 = 0x0000200C, + Keyboard_Num1 = 0x0000200D, + Keyboard_Num2 = 0x0000200E, + Keyboard_Num3 = 0x0000200F, + Keyboard_NumEnter = 0x00002010, + Keyboard_Num0 = 0x00002011, + Keyboard_Num00 = 0x00002012, + Keyboard_NumPeriodAndDelete = 0x00002013, - Keyboard_NumLock = 0x00002001, - Keyboard_NumSlash = 0x00002002, - Keyboard_NumAsterisk = 0x00002003, - Keyboard_NumMinus = 0x00002004, - Keyboard_Num7 = 0x00002005, - Keyboard_Num8 = 0x00002006, - Keyboard_Num9 = 0x00002007, - Keyboard_NumComma = 0x00002008, - Keyboard_NumPlus = 0x00002009, - Keyboard_Num4 = 0x0000200A, - Keyboard_Num5 = 0x0000200B, - Keyboard_Num6 = 0x0000200C, - Keyboard_Num1 = 0x0000200D, - Keyboard_Num2 = 0x0000200E, - Keyboard_Num3 = 0x0000200F, - Keyboard_NumEnter = 0x00002010, - Keyboard_Num0 = 0x00002011, - Keyboard_Num00 = 0x00002012, - Keyboard_NumPeriodAndDelete = 0x00002013, + Keyboard_MediaMute = 0x00003001, + Keyboard_MediaVolumeDown = 0x00003002, + Keyboard_MediaVolumeUp = 0x00003003, + Keyboard_MediaStop = 0x00003004, + Keyboard_MediaPreviousTrack = 0x00003005, + Keyboard_MediaPlay = 0x00003006, + Keyboard_MediaNextTrack = 0x00003007, - Keyboard_MediaMute = 0x00003001, - Keyboard_MediaVolumeDown = 0x00003002, - Keyboard_MediaVolumeUp = 0x00003003, - Keyboard_MediaStop = 0x00003004, - Keyboard_MediaPreviousTrack = 0x00003005, - Keyboard_MediaPlay = 0x00003006, - Keyboard_MediaNextTrack = 0x00003007, + Keyboard_WinLock = 0x00004001, + Keyboard_Brightness = 0x00004002, + Keyboard_LedProgramming = 0x00004003, + Keyboard_Profile = 0x00004004, - Keyboard_WinLock = 0x00004001, - Keyboard_Brightness = 0x00004002, + Keyboard_MacroRecording = 0x00005001, + Keyboard_Macro1 = 0x00005002, + Keyboard_Macro2 = 0x00005003, + Keyboard_Macro3 = 0x00005004, + Keyboard_Macro4 = 0x00005005, + Keyboard_Macro5 = 0x00005006, + Keyboard_Macro6 = 0x00005007, + Keyboard_Macro7 = 0x00005008, + Keyboard_Macro8 = 0x00005009, + Keyboard_Macro9 = 0x0000500A, + Keyboard_Macro10 = 0x0000500B, + Keyboard_Macro11 = 0x0000500C, + Keyboard_Macro12 = 0x0000500D, + Keyboard_Macro13 = 0x0000500E, + Keyboard_Macro14 = 0x0000500F, + Keyboard_Macro15 = 0x00005010, + Keyboard_Macro16 = 0x00005011, + Keyboard_Macro17 = 0x00005012, + Keyboard_Macro18 = 0x00005013, + Keyboard_Macro19 = 0x00005014, + Keyboard_Macro20 = 0x00005015, + Keyboard_Macro21 = 0x00005016, + Keyboard_Macro22 = 0x00005017, + Keyboard_Macro23 = 0x00005018, + Keyboard_Macro24 = 0x00005019, + Keyboard_Macro25 = 0x0000501A, + Keyboard_Macro26 = 0x0000501B, + Keyboard_Macro27 = 0x0000501C, + Keyboard_Macro28 = 0x0000501D, + Keyboard_Macro29 = 0x0000501E, + Keyboard_Macro30 = 0x0000501F, + Keyboard_Macro31 = 0x00005020, + Keyboard_Macro32 = 0x00005021, - Keyboard_MacroRecording = 0x00005001, - Keyboard_Macro1 = 0x00005002, - Keyboard_Macro2 = 0x00005003, - Keyboard_Macro3 = 0x00005004, - Keyboard_Macro4 = 0x00005005, - Keyboard_Macro5 = 0x00005006, + Keyboard_Programmable1 = 0x00006001, + Keyboard_Programmable2 = 0x00006002, + Keyboard_Programmable3 = 0x00006003, + Keyboard_Programmable4 = 0x00006004, + Keyboard_Programmable5 = 0x00006005, + Keyboard_Programmable6 = 0x00006006, + Keyboard_Programmable7 = 0x00006007, + Keyboard_Programmable8 = 0x00006008, + Keyboard_Programmable9 = 0x00006009, + Keyboard_Programmable10 = 0x0000600A, + Keyboard_Programmable11 = 0x0000600B, + Keyboard_Programmable12 = 0x0000600C, + Keyboard_Programmable13 = 0x0000600D, + Keyboard_Programmable14 = 0x0000600E, + Keyboard_Programmable15 = 0x0000600F, + Keyboard_Programmable16 = 0x00006010, + Keyboard_Programmable17 = 0x00006011, + Keyboard_Programmable18 = 0x00006012, + Keyboard_Programmable19 = 0x00006013, + Keyboard_Programmable20 = 0x00006014, + Keyboard_Programmable21 = 0x00006015, + Keyboard_Programmable22 = 0x00006016, + Keyboard_Programmable23 = 0x00006017, + Keyboard_Programmable24 = 0x00006018, + Keyboard_Programmable25 = 0x00006019, + Keyboard_Programmable26 = 0x0000601A, + Keyboard_Programmable27 = 0x0000601B, + Keyboard_Programmable28 = 0x0000601C, + Keyboard_Programmable29 = 0x0000601D, + Keyboard_Programmable30 = 0x0000601E, + Keyboard_Programmable31 = 0x0000601F, + Keyboard_Programmable32 = 0x00006020, + Keyboard_Programmable33 = 0x00006021, + Keyboard_Programmable34 = 0x00006022, + Keyboard_Programmable35 = 0x00006023, + Keyboard_Programmable36 = 0x00006024, + Keyboard_Programmable37 = 0x00006025, + Keyboard_Programmable38 = 0x00006026, + Keyboard_Programmable39 = 0x00006027, + Keyboard_Programmable40 = 0x00006028, + Keyboard_Programmable41 = 0x00006029, + Keyboard_Programmable42 = 0x0000602A, + Keyboard_Programmable43 = 0x0000602B, + Keyboard_Programmable44 = 0x0000602C, + Keyboard_Programmable45 = 0x0000602D, + Keyboard_Programmable46 = 0x0000602E, + Keyboard_Programmable47 = 0x0000602F, + Keyboard_Programmable48 = 0x00006030, + Keyboard_Programmable49 = 0x00006031, + Keyboard_Programmable50 = 0x00006032, + Keyboard_Programmable51 = 0x00006033, + Keyboard_Programmable52 = 0x00006034, + Keyboard_Programmable53 = 0x00006035, + Keyboard_Programmable54 = 0x00006036, + Keyboard_Programmable55 = 0x00006037, + Keyboard_Programmable56 = 0x00006038, + Keyboard_Programmable57 = 0x00006039, + Keyboard_Programmable58 = 0x0000603A, + Keyboard_Programmable59 = 0x0000603B, + Keyboard_Programmable60 = 0x0000603C, + Keyboard_Programmable61 = 0x0000603D, + Keyboard_Programmable62 = 0x0000603E, + Keyboard_Programmable63 = 0x0000603F, + Keyboard_Programmable64 = 0x00006040, - Keyboard_Programmable1 = 0x00006001, - Keyboard_Programmable2 = 0x00006002, - Keyboard_Programmable3 = 0x00006003, - Keyboard_Programmable4 = 0x00006004, - Keyboard_Programmable5 = 0x00006005, - Keyboard_Programmable6 = 0x00006006, - Keyboard_Programmable7 = 0x00006007, - Keyboard_Programmable8 = 0x00006008, - Keyboard_Programmable9 = 0x00006009, - Keyboard_Programmable10 = 0x0000600A, - Keyboard_Programmable11 = 0x0000600B, - Keyboard_Programmable12 = 0x0000600C, - Keyboard_Programmable13 = 0x0000600D, - Keyboard_Programmable14 = 0x0000600E, - Keyboard_Programmable15 = 0x0000600F, - Keyboard_Programmable16 = 0x00006010, - Keyboard_Programmable17 = 0x00006011, - Keyboard_Programmable18 = 0x00006012, - Keyboard_Programmable19 = 0x00006013, - Keyboard_Programmable20 = 0x00006014, - Keyboard_Programmable21 = 0x00006015, - Keyboard_Programmable22 = 0x00006016, - Keyboard_Programmable23 = 0x00006017, - Keyboard_Programmable24 = 0x00006018, - Keyboard_Programmable25 = 0x00006019, - Keyboard_Programmable26 = 0x0000601A, - Keyboard_Programmable27 = 0x0000601B, - Keyboard_Programmable28 = 0x0000601C, - Keyboard_Programmable29 = 0x0000601D, - Keyboard_Programmable30 = 0x0000601E, - Keyboard_Programmable31 = 0x0000601F, - Keyboard_Programmable32 = 0x00006020, + Keyboard_Custom1 = 0x00007001, + Keyboard_Custom2 = 0x00007002, + Keyboard_Custom3 = 0x00007003, + Keyboard_Custom4 = 0x00007004, + Keyboard_Custom5 = 0x00007005, + Keyboard_Custom6 = 0x00007006, + Keyboard_Custom7 = 0x00007007, + Keyboard_Custom8 = 0x00007008, + Keyboard_Custom9 = 0x00007009, + Keyboard_Custom10 = 0x0000700A, + Keyboard_Custom11 = 0x0000700B, + Keyboard_Custom12 = 0x0000700C, + Keyboard_Custom13 = 0x0000700D, + Keyboard_Custom14 = 0x0000700E, + Keyboard_Custom15 = 0x0000700F, + Keyboard_Custom16 = 0x00007010, + Keyboard_Custom17 = 0x00007011, + Keyboard_Custom18 = 0x00007012, + Keyboard_Custom19 = 0x00007013, + Keyboard_Custom20 = 0x00007014, + Keyboard_Custom21 = 0x00007015, + Keyboard_Custom22 = 0x00007016, + Keyboard_Custom23 = 0x00007017, + Keyboard_Custom24 = 0x00007018, + Keyboard_Custom25 = 0x00007019, + Keyboard_Custom26 = 0x0000701A, + Keyboard_Custom27 = 0x0000701B, + Keyboard_Custom28 = 0x0000701C, + Keyboard_Custom29 = 0x0000701D, + Keyboard_Custom30 = 0x0000701E, + Keyboard_Custom31 = 0x0000701F, + Keyboard_Custom32 = 0x00007020, + Keyboard_Custom33 = 0x00007021, + Keyboard_Custom34 = 0x00007022, + Keyboard_Custom35 = 0x00007023, + Keyboard_Custom36 = 0x00007024, + Keyboard_Custom37 = 0x00007025, + Keyboard_Custom38 = 0x00007026, + Keyboard_Custom39 = 0x00007027, + Keyboard_Custom40 = 0x00007028, + Keyboard_Custom41 = 0x00007029, + Keyboard_Custom42 = 0x0000702A, + Keyboard_Custom43 = 0x0000702B, + Keyboard_Custom44 = 0x0000702C, + Keyboard_Custom45 = 0x0000702D, + Keyboard_Custom46 = 0x0000702E, + Keyboard_Custom47 = 0x0000702F, + Keyboard_Custom48 = 0x00007030, + Keyboard_Custom49 = 0x00007031, + Keyboard_Custom50 = 0x00007032, + Keyboard_Custom51 = 0x00007033, + Keyboard_Custom52 = 0x00007034, + Keyboard_Custom53 = 0x00007035, + Keyboard_Custom54 = 0x00007036, + Keyboard_Custom55 = 0x00007037, + Keyboard_Custom56 = 0x00007038, + Keyboard_Custom57 = 0x00007039, + Keyboard_Custom58 = 0x0000703A, + Keyboard_Custom59 = 0x0000703B, + Keyboard_Custom60 = 0x0000703C, + Keyboard_Custom61 = 0x0000703D, + Keyboard_Custom62 = 0x0000703E, + Keyboard_Custom63 = 0x0000703F, + Keyboard_Custom64 = 0x00007040, + Keyboard_Custom65 = 0x00007041, + Keyboard_Custom66 = 0x00007042, + Keyboard_Custom67 = 0x00007043, + Keyboard_Custom68 = 0x00007044, + Keyboard_Custom69 = 0x00007045, + Keyboard_Custom70 = 0x00007046, + Keyboard_Custom71 = 0x00007047, + Keyboard_Custom72 = 0x00007048, + Keyboard_Custom73 = 0x00007049, + Keyboard_Custom74 = 0x0000704A, + Keyboard_Custom75 = 0x0000704B, + Keyboard_Custom76 = 0x0000704C, + Keyboard_Custom77 = 0x0000704D, + Keyboard_Custom78 = 0x0000704E, + Keyboard_Custom79 = 0x0000704F, + Keyboard_Custom80 = 0x00007050, + Keyboard_Custom81 = 0x00007051, + Keyboard_Custom82 = 0x00007052, + Keyboard_Custom83 = 0x00007053, + Keyboard_Custom84 = 0x00007054, + Keyboard_Custom85 = 0x00007055, + Keyboard_Custom86 = 0x00007056, + Keyboard_Custom87 = 0x00007057, + Keyboard_Custom88 = 0x00007058, + Keyboard_Custom89 = 0x00007059, + Keyboard_Custom90 = 0x0000705A, + Keyboard_Custom91 = 0x0000705B, + Keyboard_Custom92 = 0x0000705C, + Keyboard_Custom93 = 0x0000705D, + Keyboard_Custom94 = 0x0000705E, + Keyboard_Custom95 = 0x0000705F, + Keyboard_Custom96 = 0x00007060, + Keyboard_Custom97 = 0x00007061, + Keyboard_Custom98 = 0x00007062, + Keyboard_Custom99 = 0x00007063, + Keyboard_Custom100 = 0x00007064, + Keyboard_Custom101 = 0x00007065, + Keyboard_Custom102 = 0x00007066, + Keyboard_Custom103 = 0x00007067, + Keyboard_Custom104 = 0x00007068, + Keyboard_Custom105 = 0x00007069, + Keyboard_Custom106 = 0x0000706A, + Keyboard_Custom107 = 0x0000706B, + Keyboard_Custom108 = 0x0000706C, + Keyboard_Custom109 = 0x0000706D, + Keyboard_Custom110 = 0x0000706E, + Keyboard_Custom111 = 0x0000706F, + Keyboard_Custom112 = 0x00007070, + Keyboard_Custom113 = 0x00007071, + Keyboard_Custom114 = 0x00007072, + Keyboard_Custom115 = 0x00007073, + Keyboard_Custom116 = 0x00007074, + Keyboard_Custom117 = 0x00007075, + Keyboard_Custom118 = 0x00007076, + Keyboard_Custom119 = 0x00007077, + Keyboard_Custom120 = 0x00007078, + Keyboard_Custom121 = 0x00007079, + Keyboard_Custom122 = 0x0000707A, + Keyboard_Custom123 = 0x0000707B, + Keyboard_Custom124 = 0x0000707C, + Keyboard_Custom125 = 0x0000707D, + Keyboard_Custom126 = 0x0000707E, + Keyboard_Custom127 = 0x0000707F, + Keyboard_Custom128 = 0x00007080, - Keyboard_Custom1 = 0x00007001, - Keyboard_Custom2 = 0x00007002, - Keyboard_Custom3 = 0x00007003, - Keyboard_Custom4 = 0x00007004, - Keyboard_Custom5 = 0x00007005, - Keyboard_Custom6 = 0x00007006, - Keyboard_Custom7 = 0x00007007, - Keyboard_Custom8 = 0x00007008, - Keyboard_Custom9 = 0x00007009, - Keyboard_Custom10 = 0x0000700A, - Keyboard_Custom11 = 0x0000700B, - Keyboard_Custom12 = 0x0000700C, - Keyboard_Custom13 = 0x0000700D, - Keyboard_Custom14 = 0x0000700E, - Keyboard_Custom15 = 0x0000700F, - Keyboard_Custom16 = 0x00007010, - Keyboard_Custom17 = 0x00007011, - Keyboard_Custom18 = 0x00007012, - Keyboard_Custom19 = 0x00007013, - Keyboard_Custom20 = 0x00007014, - Keyboard_Custom21 = 0x00007015, - Keyboard_Custom22 = 0x00007016, - Keyboard_Custom23 = 0x00007017, - Keyboard_Custom24 = 0x00007018, - Keyboard_Custom25 = 0x00007019, - Keyboard_Custom26 = 0x0000701A, - Keyboard_Custom27 = 0x0000701B, - Keyboard_Custom28 = 0x0000701C, - Keyboard_Custom29 = 0x0000701D, - Keyboard_Custom30 = 0x0000701E, - Keyboard_Custom31 = 0x0000701F, - Keyboard_Custom32 = 0x00007020, - Keyboard_Custom33 = 0x00007021, - Keyboard_Custom34 = 0x00007022, - Keyboard_Custom35 = 0x00007023, - Keyboard_Custom36 = 0x00007024, - Keyboard_Custom37 = 0x00007025, - Keyboard_Custom38 = 0x00007026, - Keyboard_Custom39 = 0x00007027, - Keyboard_Custom40 = 0x00007028, - Keyboard_Custom41 = 0x00007029, - Keyboard_Custom42 = 0x0000702A, - Keyboard_Custom43 = 0x0000702B, - Keyboard_Custom44 = 0x0000702C, - Keyboard_Custom45 = 0x0000702D, - Keyboard_Custom46 = 0x0000702E, - Keyboard_Custom47 = 0x0000702F, - Keyboard_Custom48 = 0x00007030, - Keyboard_Custom49 = 0x00007031, - Keyboard_Custom50 = 0x00007032, - Keyboard_Custom51 = 0x00007033, - Keyboard_Custom52 = 0x00007034, - Keyboard_Custom53 = 0x00007035, - Keyboard_Custom54 = 0x00007036, - Keyboard_Custom55 = 0x00007037, - Keyboard_Custom56 = 0x00007038, - Keyboard_Custom57 = 0x00007039, - Keyboard_Custom58 = 0x0000703A, - Keyboard_Custom59 = 0x0000703B, - Keyboard_Custom60 = 0x0000703C, - Keyboard_Custom61 = 0x0000703D, - Keyboard_Custom62 = 0x0000703E, - Keyboard_Custom63 = 0x0000703F, - Keyboard_Custom64 = 0x00007040, + /*### Mouse ###*/ + Mouse1 = 0x00100001, + Mouse2 = 0x00100002, + Mouse3 = 0x00100003, + Mouse4 = 0x00100004, + Mouse5 = 0x00100005, + Mouse6 = 0x00100006, + Mouse7 = 0x00100007, + Mouse8 = 0x00100008, + Mouse9 = 0x00100009, + Mouse10 = 0x0010000A, + Mouse11 = 0x0010000B, + Mouse12 = 0x0010000C, + Mouse13 = 0x0010000D, + Mouse14 = 0x0010000E, + Mouse15 = 0x0010000F, + Mouse16 = 0x00100010, + Mouse17 = 0x00100011, + Mouse18 = 0x00100012, + Mouse19 = 0x00100013, + Mouse20 = 0x00100014, + Mouse21 = 0x00100015, + Mouse22 = 0x00100016, + Mouse23 = 0x00100017, + Mouse24 = 0x00100018, + Mouse25 = 0x00100019, + Mouse26 = 0x0010001A, + Mouse27 = 0x0010001B, + Mouse28 = 0x0010001C, + Mouse29 = 0x0010001D, + Mouse30 = 0x0010001E, + Mouse31 = 0x0010001F, + Mouse32 = 0x00100020, + Mouse33 = 0x00100021, + Mouse34 = 0x00100022, + Mouse35 = 0x00100023, + Mouse36 = 0x00100024, + Mouse37 = 0x00100025, + Mouse38 = 0x00100026, + Mouse39 = 0x00100027, + Mouse40 = 0x00100028, + Mouse41 = 0x00100029, + Mouse42 = 0x0010002A, + Mouse43 = 0x0010002B, + Mouse44 = 0x0010002C, + Mouse45 = 0x0010002D, + Mouse46 = 0x0010002E, + Mouse47 = 0x0010002F, + Mouse48 = 0x00100030, + Mouse49 = 0x00100031, + Mouse50 = 0x00100032, + Mouse51 = 0x00100033, + Mouse52 = 0x00100034, + Mouse53 = 0x00100035, + Mouse54 = 0x00100036, + Mouse55 = 0x00100037, + Mouse56 = 0x00100038, + Mouse57 = 0x00100039, + Mouse58 = 0x0010003A, + Mouse59 = 0x0010003B, + Mouse60 = 0x0010003C, + Mouse61 = 0x0010003D, + Mouse62 = 0x0010003E, + Mouse63 = 0x0010003F, + Mouse64 = 0x00100040, + Mouse65 = 0x00100041, + Mouse66 = 0x00100042, + Mouse67 = 0x00100043, + Mouse68 = 0x00100044, + Mouse69 = 0x00100045, + Mouse70 = 0x00100046, + Mouse71 = 0x00100047, + Mouse72 = 0x00100048, + Mouse73 = 0x00100049, + Mouse74 = 0x0010004A, + Mouse75 = 0x0010004B, + Mouse76 = 0x0010004C, + Mouse77 = 0x0010004D, + Mouse78 = 0x0010004E, + Mouse79 = 0x0010004F, + Mouse80 = 0x00100050, + Mouse81 = 0x00100051, + Mouse82 = 0x00100052, + Mouse83 = 0x00100053, + Mouse84 = 0x00100054, + Mouse85 = 0x00100055, + Mouse86 = 0x00100056, + Mouse87 = 0x00100057, + Mouse88 = 0x00100058, + Mouse89 = 0x00100059, + Mouse90 = 0x0010005A, + Mouse91 = 0x0010005B, + Mouse92 = 0x0010005C, + Mouse93 = 0x0010005D, + Mouse94 = 0x0010005E, + Mouse95 = 0x0010005F, + Mouse96 = 0x00100060, + Mouse97 = 0x00100061, + Mouse98 = 0x00100062, + Mouse99 = 0x00100063, + Mouse100 = 0x00100064, + Mouse101 = 0x00100065, + Mouse102 = 0x00100066, + Mouse103 = 0x00100067, + Mouse104 = 0x00100068, + Mouse105 = 0x00100069, + Mouse106 = 0x0010006A, + Mouse107 = 0x0010006B, + Mouse108 = 0x0010006C, + Mouse109 = 0x0010006D, + Mouse110 = 0x0010006E, + Mouse111 = 0x0010006F, + Mouse112 = 0x00100070, + Mouse113 = 0x00100071, + Mouse114 = 0x00100072, + Mouse115 = 0x00100073, + Mouse116 = 0x00100074, + Mouse117 = 0x00100075, + Mouse118 = 0x00100076, + Mouse119 = 0x00100077, + Mouse120 = 0x00100078, + Mouse121 = 0x00100079, + Mouse122 = 0x0010007A, + Mouse123 = 0x0010007B, + Mouse124 = 0x0010007C, + Mouse125 = 0x0010007D, + Mouse126 = 0x0010007E, + Mouse127 = 0x0010007F, + Mouse128 = 0x00100080, - /*### Mouse ###*/ - Mouse1 = 0x00100001, - Mouse2 = 0x00100002, - Mouse3 = 0x00100003, - Mouse4 = 0x00100004, - Mouse5 = 0x00100005, - Mouse6 = 0x00100006, - Mouse7 = 0x00100007, - Mouse8 = 0x00100008, - Mouse9 = 0x00100009, - Mouse10 = 0x0010000A, - Mouse11 = 0x0010000B, - Mouse12 = 0x0010000C, - Mouse13 = 0x0010000D, - Mouse14 = 0x0010000E, - Mouse15 = 0x0010000F, - Mouse16 = 0x00100010, - Mouse17 = 0x00100011, - Mouse18 = 0x00100012, - Mouse19 = 0x00100013, - Mouse20 = 0x00100014, - Mouse21 = 0x00100015, - Mouse22 = 0x00100016, - Mouse23 = 0x00100017, - Mouse24 = 0x00100018, - Mouse25 = 0x00100019, - Mouse26 = 0x0010001A, - Mouse27 = 0x0010001B, - Mouse28 = 0x0010001C, - Mouse29 = 0x0010001D, - Mouse30 = 0x0010001E, - Mouse31 = 0x0010001F, - Mouse32 = 0x00100020, - Mouse33 = 0x00100021, - Mouse34 = 0x00100022, - Mouse35 = 0x00100023, - Mouse36 = 0x00100024, - Mouse37 = 0x00100025, - Mouse38 = 0x00100026, - Mouse39 = 0x00100027, - Mouse40 = 0x00100028, - Mouse41 = 0x00100029, - Mouse42 = 0x0010002A, - Mouse43 = 0x0010002B, - Mouse44 = 0x0010002C, - Mouse45 = 0x0010002D, - Mouse46 = 0x0010002E, - Mouse47 = 0x0010002F, - Mouse48 = 0x00100030, - Mouse49 = 0x00100031, - Mouse50 = 0x00100032, - Mouse51 = 0x00100033, - Mouse52 = 0x00100034, - Mouse53 = 0x00100035, - Mouse54 = 0x00100036, - Mouse55 = 0x00100037, - Mouse56 = 0x00100038, - Mouse57 = 0x00100039, - Mouse58 = 0x0010003A, - Mouse59 = 0x0010003B, - Mouse60 = 0x0010003C, - Mouse61 = 0x0010003D, - Mouse62 = 0x0010003E, - Mouse63 = 0x0010003F, - Mouse64 = 0x00100040, + /*### Headset ###*/ + Headset1 = 0x00200001, + Headset2 = 0x00200002, + Headset3 = 0x00200003, + Headset4 = 0x00200004, + Headset5 = 0x00200005, + Headset6 = 0x00200006, + Headset7 = 0x00200007, + Headset8 = 0x00200008, + Headset9 = 0x00200009, + Headset10 = 0x0020000A, + Headset11 = 0x0020000B, + Headset12 = 0x0020000C, + Headset13 = 0x0020000D, + Headset14 = 0x0020000E, + Headset15 = 0x0020000F, + Headset16 = 0x00200010, + Headset17 = 0x00200011, + Headset18 = 0x00200012, + Headset19 = 0x00200013, + Headset20 = 0x00200014, + Headset21 = 0x00200015, + Headset22 = 0x00200016, + Headset23 = 0x00200017, + Headset24 = 0x00200018, + Headset25 = 0x00200019, + Headset26 = 0x0020001A, + Headset27 = 0x0020001B, + Headset28 = 0x0020001C, + Headset29 = 0x0020001D, + Headset30 = 0x0020001E, + Headset31 = 0x0020001F, + Headset32 = 0x00200020, + Headset33 = 0x00200021, + Headset34 = 0x00200022, + Headset35 = 0x00200023, + Headset36 = 0x00200024, + Headset37 = 0x00200025, + Headset38 = 0x00200026, + Headset39 = 0x00200027, + Headset40 = 0x00200028, + Headset41 = 0x00200029, + Headset42 = 0x0020002A, + Headset43 = 0x0020002B, + Headset44 = 0x0020002C, + Headset45 = 0x0020002D, + Headset46 = 0x0020002E, + Headset47 = 0x0020002F, + Headset48 = 0x00200030, + Headset49 = 0x00200031, + Headset50 = 0x00200032, + Headset51 = 0x00200033, + Headset52 = 0x00200034, + Headset53 = 0x00200035, + Headset54 = 0x00200036, + Headset55 = 0x00200037, + Headset56 = 0x00200038, + Headset57 = 0x00200039, + Headset58 = 0x0020003A, + Headset59 = 0x0020003B, + Headset60 = 0x0020003C, + Headset61 = 0x0020003D, + Headset62 = 0x0020003E, + Headset63 = 0x0020003F, + Headset64 = 0x00200040, + Headset65 = 0x00200041, + Headset66 = 0x00200042, + Headset67 = 0x00200043, + Headset68 = 0x00200044, + Headset69 = 0x00200045, + Headset70 = 0x00200046, + Headset71 = 0x00200047, + Headset72 = 0x00200048, + Headset73 = 0x00200049, + Headset74 = 0x0020004A, + Headset75 = 0x0020004B, + Headset76 = 0x0020004C, + Headset77 = 0x0020004D, + Headset78 = 0x0020004E, + Headset79 = 0x0020004F, + Headset80 = 0x00200050, + Headset81 = 0x00200051, + Headset82 = 0x00200052, + Headset83 = 0x00200053, + Headset84 = 0x00200054, + Headset85 = 0x00200055, + Headset86 = 0x00200056, + Headset87 = 0x00200057, + Headset88 = 0x00200058, + Headset89 = 0x00200059, + Headset90 = 0x0020005A, + Headset91 = 0x0020005B, + Headset92 = 0x0020005C, + Headset93 = 0x0020005D, + Headset94 = 0x0020005E, + Headset95 = 0x0020005F, + Headset96 = 0x00200060, + Headset97 = 0x00200061, + Headset98 = 0x00200062, + Headset99 = 0x00200063, + Headset100 = 0x00200064, + Headset101 = 0x00200065, + Headset102 = 0x00200066, + Headset103 = 0x00200067, + Headset104 = 0x00200068, + Headset105 = 0x00200069, + Headset106 = 0x0020006A, + Headset107 = 0x0020006B, + Headset108 = 0x0020006C, + Headset109 = 0x0020006D, + Headset110 = 0x0020006E, + Headset111 = 0x0020006F, + Headset112 = 0x00200070, + Headset113 = 0x00200071, + Headset114 = 0x00200072, + Headset115 = 0x00200073, + Headset116 = 0x00200074, + Headset117 = 0x00200075, + Headset118 = 0x00200076, + Headset119 = 0x00200077, + Headset120 = 0x00200078, + Headset121 = 0x00200079, + Headset122 = 0x0020007A, + Headset123 = 0x0020007B, + Headset124 = 0x0020007C, + Headset125 = 0x0020007D, + Headset126 = 0x0020007E, + Headset127 = 0x0020007F, + Headset128 = 0x00200080, - /*### Headset ###*/ - Headset1 = 0x00200001, - Headset2 = 0x00200002, - Headset3 = 0x00200003, - Headset4 = 0x00200004, - Headset5 = 0x00200005, - Headset6 = 0x00200006, - Headset7 = 0x00200007, - Headset8 = 0x00200008, - Headset9 = 0x00200009, - Headset10 = 0x0020000A, - Headset11 = 0x0020000B, - Headset12 = 0x0020000C, - Headset13 = 0x0020000D, - Headset14 = 0x0020000E, - Headset15 = 0x0020000F, - Headset16 = 0x00200010, - Headset17 = 0x00200011, - Headset18 = 0x00200012, - Headset19 = 0x00200013, - Headset20 = 0x00200014, - Headset21 = 0x00200015, - Headset22 = 0x00200016, - Headset23 = 0x00200017, - Headset24 = 0x00200018, - Headset25 = 0x00200019, - Headset26 = 0x0020001A, - Headset27 = 0x0020001B, - Headset28 = 0x0020001C, - Headset29 = 0x0020001D, - Headset30 = 0x0020001E, - Headset31 = 0x0020001F, - Headset32 = 0x00200020, - Headset33 = 0x00200021, - Headset34 = 0x00200022, - Headset35 = 0x00200023, - Headset36 = 0x00200024, - Headset37 = 0x00200025, - Headset38 = 0x00200026, - Headset39 = 0x00200027, - Headset40 = 0x00200028, - Headset41 = 0x00200029, - Headset42 = 0x0020002A, - Headset43 = 0x0020002B, - Headset44 = 0x0020002C, - Headset45 = 0x0020002D, - Headset46 = 0x0020002E, - Headset47 = 0x0020002F, - Headset48 = 0x00200030, - Headset49 = 0x00200031, - Headset50 = 0x00200032, - Headset51 = 0x00200033, - Headset52 = 0x00200034, - Headset53 = 0x00200035, - Headset54 = 0x00200036, - Headset55 = 0x00200037, - Headset56 = 0x00200038, - Headset57 = 0x00200039, - Headset58 = 0x0020003A, - Headset59 = 0x0020003B, - Headset60 = 0x0020003C, - Headset61 = 0x0020003D, - Headset62 = 0x0020003E, - Headset63 = 0x0020003F, - Headset64 = 0x00200040, + /*### Mousepad ###*/ + Mousepad1 = 0x00300001, + Mousepad2 = 0x00300002, + Mousepad3 = 0x00300003, + Mousepad4 = 0x00300004, + Mousepad5 = 0x00300005, + Mousepad6 = 0x00300006, + Mousepad7 = 0x00300007, + Mousepad8 = 0x00300008, + Mousepad9 = 0x00300009, + Mousepad10 = 0x0030000A, + Mousepad11 = 0x0030000B, + Mousepad12 = 0x0030000C, + Mousepad13 = 0x0030000D, + Mousepad14 = 0x0030000E, + Mousepad15 = 0x0030000F, + Mousepad16 = 0x00300010, + Mousepad17 = 0x00300011, + Mousepad18 = 0x00300012, + Mousepad19 = 0x00300013, + Mousepad20 = 0x00300014, + Mousepad21 = 0x00300015, + Mousepad22 = 0x00300016, + Mousepad23 = 0x00300017, + Mousepad24 = 0x00300018, + Mousepad25 = 0x00300019, + Mousepad26 = 0x0030001A, + Mousepad27 = 0x0030001B, + Mousepad28 = 0x0030001C, + Mousepad29 = 0x0030001D, + Mousepad30 = 0x0030001E, + Mousepad31 = 0x0030001F, + Mousepad32 = 0x00300020, + Mousepad33 = 0x00300021, + Mousepad34 = 0x00300022, + Mousepad35 = 0x00300023, + Mousepad36 = 0x00300024, + Mousepad37 = 0x00300025, + Mousepad38 = 0x00300026, + Mousepad39 = 0x00300027, + Mousepad40 = 0x00300028, + Mousepad41 = 0x00300029, + Mousepad42 = 0x0030002A, + Mousepad43 = 0x0030002B, + Mousepad44 = 0x0030002C, + Mousepad45 = 0x0030002D, + Mousepad46 = 0x0030002E, + Mousepad47 = 0x0030002F, + Mousepad48 = 0x00300030, + Mousepad49 = 0x00300031, + Mousepad50 = 0x00300032, + Mousepad51 = 0x00300033, + Mousepad52 = 0x00300034, + Mousepad53 = 0x00300035, + Mousepad54 = 0x00300036, + Mousepad55 = 0x00300037, + Mousepad56 = 0x00300038, + Mousepad57 = 0x00300039, + Mousepad58 = 0x0030003A, + Mousepad59 = 0x0030003B, + Mousepad60 = 0x0030003C, + Mousepad61 = 0x0030003D, + Mousepad62 = 0x0030003E, + Mousepad63 = 0x0030003F, + Mousepad64 = 0x00300040, + Mousepad65 = 0x00300041, + Mousepad66 = 0x00300042, + Mousepad67 = 0x00300043, + Mousepad68 = 0x00300044, + Mousepad69 = 0x00300045, + Mousepad70 = 0x00300046, + Mousepad71 = 0x00300047, + Mousepad72 = 0x00300048, + Mousepad73 = 0x00300049, + Mousepad74 = 0x0030004A, + Mousepad75 = 0x0030004B, + Mousepad76 = 0x0030004C, + Mousepad77 = 0x0030004D, + Mousepad78 = 0x0030004E, + Mousepad79 = 0x0030004F, + Mousepad80 = 0x00300050, + Mousepad81 = 0x00300051, + Mousepad82 = 0x00300052, + Mousepad83 = 0x00300053, + Mousepad84 = 0x00300054, + Mousepad85 = 0x00300055, + Mousepad86 = 0x00300056, + Mousepad87 = 0x00300057, + Mousepad88 = 0x00300058, + Mousepad89 = 0x00300059, + Mousepad90 = 0x0030005A, + Mousepad91 = 0x0030005B, + Mousepad92 = 0x0030005C, + Mousepad93 = 0x0030005D, + Mousepad94 = 0x0030005E, + Mousepad95 = 0x0030005F, + Mousepad96 = 0x00300060, + Mousepad97 = 0x00300061, + Mousepad98 = 0x00300062, + Mousepad99 = 0x00300063, + Mousepad100 = 0x00300064, + Mousepad101 = 0x00300065, + Mousepad102 = 0x00300066, + Mousepad103 = 0x00300067, + Mousepad104 = 0x00300068, + Mousepad105 = 0x00300069, + Mousepad106 = 0x0030006A, + Mousepad107 = 0x0030006B, + Mousepad108 = 0x0030006C, + Mousepad109 = 0x0030006D, + Mousepad110 = 0x0030006E, + Mousepad111 = 0x0030006F, + Mousepad112 = 0x00300070, + Mousepad113 = 0x00300071, + Mousepad114 = 0x00300072, + Mousepad115 = 0x00300073, + Mousepad116 = 0x00300074, + Mousepad117 = 0x00300075, + Mousepad118 = 0x00300076, + Mousepad119 = 0x00300077, + Mousepad120 = 0x00300078, + Mousepad121 = 0x00300079, + Mousepad122 = 0x0030007A, + Mousepad123 = 0x0030007B, + Mousepad124 = 0x0030007C, + Mousepad125 = 0x0030007D, + Mousepad126 = 0x0030007E, + Mousepad127 = 0x0030007F, + Mousepad128 = 0x00300080, - /*### Mousepad ###*/ - Mousepad1 = 0x00300001, - Mousepad2 = 0x00300002, - Mousepad3 = 0x00300003, - Mousepad4 = 0x00300004, - Mousepad5 = 0x00300005, - Mousepad6 = 0x00300006, - Mousepad7 = 0x00300007, - Mousepad8 = 0x00300008, - Mousepad9 = 0x00300009, - Mousepad10 = 0x0030000A, - Mousepad11 = 0x0030000B, - Mousepad12 = 0x0030000C, - Mousepad13 = 0x0030000D, - Mousepad14 = 0x0030000E, - Mousepad15 = 0x0030000F, - Mousepad16 = 0x00300010, - Mousepad17 = 0x00300011, - Mousepad18 = 0x00300012, - Mousepad19 = 0x00300013, - Mousepad20 = 0x00300014, - Mousepad21 = 0x00300015, - Mousepad22 = 0x00300016, - Mousepad23 = 0x00300017, - Mousepad24 = 0x00300018, - Mousepad25 = 0x00300019, - Mousepad26 = 0x0030001A, - Mousepad27 = 0x0030001B, - Mousepad28 = 0x0030001C, - Mousepad29 = 0x0030001D, - Mousepad30 = 0x0030001E, - Mousepad31 = 0x0030001F, - Mousepad32 = 0x00300020, - Mousepad33 = 0x00300021, - Mousepad34 = 0x00300022, - Mousepad35 = 0x00300023, - Mousepad36 = 0x00300024, - Mousepad37 = 0x00300025, - Mousepad38 = 0x00300026, - Mousepad39 = 0x00300027, - Mousepad40 = 0x00300028, - Mousepad41 = 0x00300029, - Mousepad42 = 0x0030002A, - Mousepad43 = 0x0030002B, - Mousepad44 = 0x0030002C, - Mousepad45 = 0x0030002D, - Mousepad46 = 0x0030002E, - Mousepad47 = 0x0030002F, - Mousepad48 = 0x00300030, - Mousepad49 = 0x00300031, - Mousepad50 = 0x00300032, - Mousepad51 = 0x00300033, - Mousepad52 = 0x00300034, - Mousepad53 = 0x00300035, - Mousepad54 = 0x00300036, - Mousepad55 = 0x00300037, - Mousepad56 = 0x00300038, - Mousepad57 = 0x00300039, - Mousepad58 = 0x0030003A, - Mousepad59 = 0x0030003B, - Mousepad60 = 0x0030003C, - Mousepad61 = 0x0030003D, - Mousepad62 = 0x0030003E, - Mousepad63 = 0x0030003F, - Mousepad64 = 0x00300040, + /*### LedStripe ###*/ + LedStripe1 = 0x00400001, + LedStripe2 = 0x00400002, + LedStripe3 = 0x00400003, + LedStripe4 = 0x00400004, + LedStripe5 = 0x00400005, + LedStripe6 = 0x00400006, + LedStripe7 = 0x00400007, + LedStripe8 = 0x00400008, + LedStripe9 = 0x00400009, + LedStripe10 = 0x0040000A, + LedStripe11 = 0x0040000B, + LedStripe12 = 0x0040000C, + LedStripe13 = 0x0040000D, + LedStripe14 = 0x0040000E, + LedStripe15 = 0x0040000F, + LedStripe16 = 0x00400010, + LedStripe17 = 0x00400011, + LedStripe18 = 0x00400012, + LedStripe19 = 0x00400013, + LedStripe20 = 0x00400014, + LedStripe21 = 0x00400015, + LedStripe22 = 0x00400016, + LedStripe23 = 0x00400017, + LedStripe24 = 0x00400018, + LedStripe25 = 0x00400019, + LedStripe26 = 0x0040001A, + LedStripe27 = 0x0040001B, + LedStripe28 = 0x0040001C, + LedStripe29 = 0x0040001D, + LedStripe30 = 0x0040001E, + LedStripe31 = 0x0040001F, + LedStripe32 = 0x00400020, + LedStripe33 = 0x00400021, + LedStripe34 = 0x00400022, + LedStripe35 = 0x00400023, + LedStripe36 = 0x00400024, + LedStripe37 = 0x00400025, + LedStripe38 = 0x00400026, + LedStripe39 = 0x00400027, + LedStripe40 = 0x00400028, + LedStripe41 = 0x00400029, + LedStripe42 = 0x0040002A, + LedStripe43 = 0x0040002B, + LedStripe44 = 0x0040002C, + LedStripe45 = 0x0040002D, + LedStripe46 = 0x0040002E, + LedStripe47 = 0x0040002F, + LedStripe48 = 0x00400030, + LedStripe49 = 0x00400031, + LedStripe50 = 0x00400032, + LedStripe51 = 0x00400033, + LedStripe52 = 0x00400034, + LedStripe53 = 0x00400035, + LedStripe54 = 0x00400036, + LedStripe55 = 0x00400037, + LedStripe56 = 0x00400038, + LedStripe57 = 0x00400039, + LedStripe58 = 0x0040003A, + LedStripe59 = 0x0040003B, + LedStripe60 = 0x0040003C, + LedStripe61 = 0x0040003D, + LedStripe62 = 0x0040003E, + LedStripe63 = 0x0040003F, + LedStripe64 = 0x00400040, + LedStripe65 = 0x00400041, + LedStripe66 = 0x00400042, + LedStripe67 = 0x00400043, + LedStripe68 = 0x00400044, + LedStripe69 = 0x00400045, + LedStripe70 = 0x00400046, + LedStripe71 = 0x00400047, + LedStripe72 = 0x00400048, + LedStripe73 = 0x00400049, + LedStripe74 = 0x0040004A, + LedStripe75 = 0x0040004B, + LedStripe76 = 0x0040004C, + LedStripe77 = 0x0040004D, + LedStripe78 = 0x0040004E, + LedStripe79 = 0x0040004F, + LedStripe80 = 0x00400050, + LedStripe81 = 0x00400051, + LedStripe82 = 0x00400052, + LedStripe83 = 0x00400053, + LedStripe84 = 0x00400054, + LedStripe85 = 0x00400055, + LedStripe86 = 0x00400056, + LedStripe87 = 0x00400057, + LedStripe88 = 0x00400058, + LedStripe89 = 0x00400059, + LedStripe90 = 0x0040005A, + LedStripe91 = 0x0040005B, + LedStripe92 = 0x0040005C, + LedStripe93 = 0x0040005D, + LedStripe94 = 0x0040005E, + LedStripe95 = 0x0040005F, + LedStripe96 = 0x00400060, + LedStripe97 = 0x00400061, + LedStripe98 = 0x00400062, + LedStripe99 = 0x00400063, + LedStripe100 = 0x00400064, + LedStripe101 = 0x00400065, + LedStripe102 = 0x00400066, + LedStripe103 = 0x00400067, + LedStripe104 = 0x00400068, + LedStripe105 = 0x00400069, + LedStripe106 = 0x0040006A, + LedStripe107 = 0x0040006B, + LedStripe108 = 0x0040006C, + LedStripe109 = 0x0040006D, + LedStripe110 = 0x0040006E, + LedStripe111 = 0x0040006F, + LedStripe112 = 0x00400070, + LedStripe113 = 0x00400071, + LedStripe114 = 0x00400072, + LedStripe115 = 0x00400073, + LedStripe116 = 0x00400074, + LedStripe117 = 0x00400075, + LedStripe118 = 0x00400076, + LedStripe119 = 0x00400077, + LedStripe120 = 0x00400078, + LedStripe121 = 0x00400079, + LedStripe122 = 0x0040007A, + LedStripe123 = 0x0040007B, + LedStripe124 = 0x0040007C, + LedStripe125 = 0x0040007D, + LedStripe126 = 0x0040007E, + LedStripe127 = 0x0040007F, + LedStripe128 = 0x00400080, + LedStripe129 = 0x00400081, + LedStripe130 = 0x00400082, + LedStripe131 = 0x00400083, + LedStripe132 = 0x00400084, + LedStripe133 = 0x00400085, + LedStripe134 = 0x00400086, + LedStripe135 = 0x00400087, + LedStripe136 = 0x00400088, + LedStripe137 = 0x00400089, + LedStripe138 = 0x0040008A, + LedStripe139 = 0x0040008B, + LedStripe140 = 0x0040008C, + LedStripe141 = 0x0040008D, + LedStripe142 = 0x0040008E, + LedStripe143 = 0x0040008F, + LedStripe144 = 0x00400090, + LedStripe145 = 0x00400091, + LedStripe146 = 0x00400092, + LedStripe147 = 0x00400093, + LedStripe148 = 0x00400094, + LedStripe149 = 0x00400095, + LedStripe150 = 0x00400096, + LedStripe151 = 0x00400097, + LedStripe152 = 0x00400098, + LedStripe153 = 0x00400099, + LedStripe154 = 0x0040009A, + LedStripe155 = 0x0040009B, + LedStripe156 = 0x0040009C, + LedStripe157 = 0x0040009D, + LedStripe158 = 0x0040009E, + LedStripe159 = 0x0040009F, + LedStripe160 = 0x004000A0, + LedStripe161 = 0x004000A1, + LedStripe162 = 0x004000A2, + LedStripe163 = 0x004000A3, + LedStripe164 = 0x004000A4, + LedStripe165 = 0x004000A5, + LedStripe166 = 0x004000A6, + LedStripe167 = 0x004000A7, + LedStripe168 = 0x004000A8, + LedStripe169 = 0x004000A9, + LedStripe170 = 0x004000AA, + LedStripe171 = 0x004000AB, + LedStripe172 = 0x004000AC, + LedStripe173 = 0x004000AD, + LedStripe174 = 0x004000AE, + LedStripe175 = 0x004000AF, + LedStripe176 = 0x004000B0, + LedStripe177 = 0x004000B1, + LedStripe178 = 0x004000B2, + LedStripe179 = 0x004000B3, + LedStripe180 = 0x004000B4, + LedStripe181 = 0x004000B5, + LedStripe182 = 0x004000B6, + LedStripe183 = 0x004000B7, + LedStripe184 = 0x004000B8, + LedStripe185 = 0x004000B9, + LedStripe186 = 0x004000BA, + LedStripe187 = 0x004000BB, + LedStripe188 = 0x004000BC, + LedStripe189 = 0x004000BD, + LedStripe190 = 0x004000BE, + LedStripe191 = 0x004000BF, + LedStripe192 = 0x004000C0, + LedStripe193 = 0x004000C1, + LedStripe194 = 0x004000C2, + LedStripe195 = 0x004000C3, + LedStripe196 = 0x004000C4, + LedStripe197 = 0x004000C5, + LedStripe198 = 0x004000C6, + LedStripe199 = 0x004000C7, + LedStripe200 = 0x004000C8, + LedStripe201 = 0x004000C9, + LedStripe202 = 0x004000CA, + LedStripe203 = 0x004000CB, + LedStripe204 = 0x004000CC, + LedStripe205 = 0x004000CD, + LedStripe206 = 0x004000CE, + LedStripe207 = 0x004000CF, + LedStripe208 = 0x004000D0, + LedStripe209 = 0x004000D1, + LedStripe210 = 0x004000D2, + LedStripe211 = 0x004000D3, + LedStripe212 = 0x004000D4, + LedStripe213 = 0x004000D5, + LedStripe214 = 0x004000D6, + LedStripe215 = 0x004000D7, + LedStripe216 = 0x004000D8, + LedStripe217 = 0x004000D9, + LedStripe218 = 0x004000DA, + LedStripe219 = 0x004000DB, + LedStripe220 = 0x004000DC, + LedStripe221 = 0x004000DD, + LedStripe222 = 0x004000DE, + LedStripe223 = 0x004000DF, + LedStripe224 = 0x004000E0, + LedStripe225 = 0x004000E1, + LedStripe226 = 0x004000E2, + LedStripe227 = 0x004000E3, + LedStripe228 = 0x004000E4, + LedStripe229 = 0x004000E5, + LedStripe230 = 0x004000E6, + LedStripe231 = 0x004000E7, + LedStripe232 = 0x004000E8, + LedStripe233 = 0x004000E9, + LedStripe234 = 0x004000EA, + LedStripe235 = 0x004000EB, + LedStripe236 = 0x004000EC, + LedStripe237 = 0x004000ED, + LedStripe238 = 0x004000EE, + LedStripe239 = 0x004000EF, + LedStripe240 = 0x004000F0, + LedStripe241 = 0x004000F1, + LedStripe242 = 0x004000F2, + LedStripe243 = 0x004000F3, + LedStripe244 = 0x004000F4, + LedStripe245 = 0x004000F5, + LedStripe246 = 0x004000F6, + LedStripe247 = 0x004000F7, + LedStripe248 = 0x004000F8, + LedStripe249 = 0x004000F9, + LedStripe250 = 0x004000FA, + LedStripe251 = 0x004000FB, + LedStripe252 = 0x004000FC, + LedStripe253 = 0x004000FD, + LedStripe254 = 0x004000FE, + LedStripe255 = 0x004000FF, + LedStripe256 = 0x00400100, + LedStripe257 = 0x00400101, + LedStripe258 = 0x00400102, + LedStripe259 = 0x00400103, + LedStripe260 = 0x00400104, + LedStripe261 = 0x00400105, + LedStripe262 = 0x00400106, + LedStripe263 = 0x00400107, + LedStripe264 = 0x00400108, + LedStripe265 = 0x00400109, + LedStripe266 = 0x0040010A, + LedStripe267 = 0x0040010B, + LedStripe268 = 0x0040010C, + LedStripe269 = 0x0040010D, + LedStripe270 = 0x0040010E, + LedStripe271 = 0x0040010F, + LedStripe272 = 0x00400110, + LedStripe273 = 0x00400111, + LedStripe274 = 0x00400112, + LedStripe275 = 0x00400113, + LedStripe276 = 0x00400114, + LedStripe277 = 0x00400115, + LedStripe278 = 0x00400116, + LedStripe279 = 0x00400117, + LedStripe280 = 0x00400118, + LedStripe281 = 0x00400119, + LedStripe282 = 0x0040011A, + LedStripe283 = 0x0040011B, + LedStripe284 = 0x0040011C, + LedStripe285 = 0x0040011D, + LedStripe286 = 0x0040011E, + LedStripe287 = 0x0040011F, + LedStripe288 = 0x00400120, + LedStripe289 = 0x00400121, + LedStripe290 = 0x00400122, + LedStripe291 = 0x00400123, + LedStripe292 = 0x00400124, + LedStripe293 = 0x00400125, + LedStripe294 = 0x00400126, + LedStripe295 = 0x00400127, + LedStripe296 = 0x00400128, + LedStripe297 = 0x00400129, + LedStripe298 = 0x0040012A, + LedStripe299 = 0x0040012B, + LedStripe300 = 0x0040012C, + LedStripe301 = 0x0040012D, + LedStripe302 = 0x0040012E, + LedStripe303 = 0x0040012F, + LedStripe304 = 0x00400130, + LedStripe305 = 0x00400131, + LedStripe306 = 0x00400132, + LedStripe307 = 0x00400133, + LedStripe308 = 0x00400134, + LedStripe309 = 0x00400135, + LedStripe310 = 0x00400136, + LedStripe311 = 0x00400137, + LedStripe312 = 0x00400138, + LedStripe313 = 0x00400139, + LedStripe314 = 0x0040013A, + LedStripe315 = 0x0040013B, + LedStripe316 = 0x0040013C, + LedStripe317 = 0x0040013D, + LedStripe318 = 0x0040013E, + LedStripe319 = 0x0040013F, + LedStripe320 = 0x00400140, + LedStripe321 = 0x00400141, + LedStripe322 = 0x00400142, + LedStripe323 = 0x00400143, + LedStripe324 = 0x00400144, + LedStripe325 = 0x00400145, + LedStripe326 = 0x00400146, + LedStripe327 = 0x00400147, + LedStripe328 = 0x00400148, + LedStripe329 = 0x00400149, + LedStripe330 = 0x0040014A, + LedStripe331 = 0x0040014B, + LedStripe332 = 0x0040014C, + LedStripe333 = 0x0040014D, + LedStripe334 = 0x0040014E, + LedStripe335 = 0x0040014F, + LedStripe336 = 0x00400150, + LedStripe337 = 0x00400151, + LedStripe338 = 0x00400152, + LedStripe339 = 0x00400153, + LedStripe340 = 0x00400154, + LedStripe341 = 0x00400155, + LedStripe342 = 0x00400156, + LedStripe343 = 0x00400157, + LedStripe344 = 0x00400158, + LedStripe345 = 0x00400159, + LedStripe346 = 0x0040015A, + LedStripe347 = 0x0040015B, + LedStripe348 = 0x0040015C, + LedStripe349 = 0x0040015D, + LedStripe350 = 0x0040015E, + LedStripe351 = 0x0040015F, + LedStripe352 = 0x00400160, + LedStripe353 = 0x00400161, + LedStripe354 = 0x00400162, + LedStripe355 = 0x00400163, + LedStripe356 = 0x00400164, + LedStripe357 = 0x00400165, + LedStripe358 = 0x00400166, + LedStripe359 = 0x00400167, + LedStripe360 = 0x00400168, + LedStripe361 = 0x00400169, + LedStripe362 = 0x0040016A, + LedStripe363 = 0x0040016B, + LedStripe364 = 0x0040016C, + LedStripe365 = 0x0040016D, + LedStripe366 = 0x0040016E, + LedStripe367 = 0x0040016F, + LedStripe368 = 0x00400170, + LedStripe369 = 0x00400171, + LedStripe370 = 0x00400172, + LedStripe371 = 0x00400173, + LedStripe372 = 0x00400174, + LedStripe373 = 0x00400175, + LedStripe374 = 0x00400176, + LedStripe375 = 0x00400177, + LedStripe376 = 0x00400178, + LedStripe377 = 0x00400179, + LedStripe378 = 0x0040017A, + LedStripe379 = 0x0040017B, + LedStripe380 = 0x0040017C, + LedStripe381 = 0x0040017D, + LedStripe382 = 0x0040017E, + LedStripe383 = 0x0040017F, + LedStripe384 = 0x00400180, + LedStripe385 = 0x00400181, + LedStripe386 = 0x00400182, + LedStripe387 = 0x00400183, + LedStripe388 = 0x00400184, + LedStripe389 = 0x00400185, + LedStripe390 = 0x00400186, + LedStripe391 = 0x00400187, + LedStripe392 = 0x00400188, + LedStripe393 = 0x00400189, + LedStripe394 = 0x0040018A, + LedStripe395 = 0x0040018B, + LedStripe396 = 0x0040018C, + LedStripe397 = 0x0040018D, + LedStripe398 = 0x0040018E, + LedStripe399 = 0x0040018F, + LedStripe400 = 0x00400190, + LedStripe401 = 0x00400191, + LedStripe402 = 0x00400192, + LedStripe403 = 0x00400193, + LedStripe404 = 0x00400194, + LedStripe405 = 0x00400195, + LedStripe406 = 0x00400196, + LedStripe407 = 0x00400197, + LedStripe408 = 0x00400198, + LedStripe409 = 0x00400199, + LedStripe410 = 0x0040019A, + LedStripe411 = 0x0040019B, + LedStripe412 = 0x0040019C, + LedStripe413 = 0x0040019D, + LedStripe414 = 0x0040019E, + LedStripe415 = 0x0040019F, + LedStripe416 = 0x004001A0, + LedStripe417 = 0x004001A1, + LedStripe418 = 0x004001A2, + LedStripe419 = 0x004001A3, + LedStripe420 = 0x004001A4, + LedStripe421 = 0x004001A5, + LedStripe422 = 0x004001A6, + LedStripe423 = 0x004001A7, + LedStripe424 = 0x004001A8, + LedStripe425 = 0x004001A9, + LedStripe426 = 0x004001AA, + LedStripe427 = 0x004001AB, + LedStripe428 = 0x004001AC, + LedStripe429 = 0x004001AD, + LedStripe430 = 0x004001AE, + LedStripe431 = 0x004001AF, + LedStripe432 = 0x004001B0, + LedStripe433 = 0x004001B1, + LedStripe434 = 0x004001B2, + LedStripe435 = 0x004001B3, + LedStripe436 = 0x004001B4, + LedStripe437 = 0x004001B5, + LedStripe438 = 0x004001B6, + LedStripe439 = 0x004001B7, + LedStripe440 = 0x004001B8, + LedStripe441 = 0x004001B9, + LedStripe442 = 0x004001BA, + LedStripe443 = 0x004001BB, + LedStripe444 = 0x004001BC, + LedStripe445 = 0x004001BD, + LedStripe446 = 0x004001BE, + LedStripe447 = 0x004001BF, + LedStripe448 = 0x004001C0, + LedStripe449 = 0x004001C1, + LedStripe450 = 0x004001C2, + LedStripe451 = 0x004001C3, + LedStripe452 = 0x004001C4, + LedStripe453 = 0x004001C5, + LedStripe454 = 0x004001C6, + LedStripe455 = 0x004001C7, + LedStripe456 = 0x004001C8, + LedStripe457 = 0x004001C9, + LedStripe458 = 0x004001CA, + LedStripe459 = 0x004001CB, + LedStripe460 = 0x004001CC, + LedStripe461 = 0x004001CD, + LedStripe462 = 0x004001CE, + LedStripe463 = 0x004001CF, + LedStripe464 = 0x004001D0, + LedStripe465 = 0x004001D1, + LedStripe466 = 0x004001D2, + LedStripe467 = 0x004001D3, + LedStripe468 = 0x004001D4, + LedStripe469 = 0x004001D5, + LedStripe470 = 0x004001D6, + LedStripe471 = 0x004001D7, + LedStripe472 = 0x004001D8, + LedStripe473 = 0x004001D9, + LedStripe474 = 0x004001DA, + LedStripe475 = 0x004001DB, + LedStripe476 = 0x004001DC, + LedStripe477 = 0x004001DD, + LedStripe478 = 0x004001DE, + LedStripe479 = 0x004001DF, + LedStripe480 = 0x004001E0, + LedStripe481 = 0x004001E1, + LedStripe482 = 0x004001E2, + LedStripe483 = 0x004001E3, + LedStripe484 = 0x004001E4, + LedStripe485 = 0x004001E5, + LedStripe486 = 0x004001E6, + LedStripe487 = 0x004001E7, + LedStripe488 = 0x004001E8, + LedStripe489 = 0x004001E9, + LedStripe490 = 0x004001EA, + LedStripe491 = 0x004001EB, + LedStripe492 = 0x004001EC, + LedStripe493 = 0x004001ED, + LedStripe494 = 0x004001EE, + LedStripe495 = 0x004001EF, + LedStripe496 = 0x004001F0, + LedStripe497 = 0x004001F1, + LedStripe498 = 0x004001F2, + LedStripe499 = 0x004001F3, + LedStripe500 = 0x004001F4, + LedStripe501 = 0x004001F5, + LedStripe502 = 0x004001F6, + LedStripe503 = 0x004001F7, + LedStripe504 = 0x004001F8, + LedStripe505 = 0x004001F9, + LedStripe506 = 0x004001FA, + LedStripe507 = 0x004001FB, + LedStripe508 = 0x004001FC, + LedStripe509 = 0x004001FD, + LedStripe510 = 0x004001FE, + LedStripe511 = 0x004001FF, + LedStripe512 = 0x00400200, + LedStripe513 = 0x00400201, + LedStripe514 = 0x00400202, + LedStripe515 = 0x00400203, + LedStripe516 = 0x00400204, + LedStripe517 = 0x00400205, + LedStripe518 = 0x00400206, + LedStripe519 = 0x00400207, + LedStripe520 = 0x00400208, + LedStripe521 = 0x00400209, + LedStripe522 = 0x0040020A, + LedStripe523 = 0x0040020B, + LedStripe524 = 0x0040020C, + LedStripe525 = 0x0040020D, + LedStripe526 = 0x0040020E, + LedStripe527 = 0x0040020F, + LedStripe528 = 0x00400210, + LedStripe529 = 0x00400211, + LedStripe530 = 0x00400212, + LedStripe531 = 0x00400213, + LedStripe532 = 0x00400214, + LedStripe533 = 0x00400215, + LedStripe534 = 0x00400216, + LedStripe535 = 0x00400217, + LedStripe536 = 0x00400218, + LedStripe537 = 0x00400219, + LedStripe538 = 0x0040021A, + LedStripe539 = 0x0040021B, + LedStripe540 = 0x0040021C, + LedStripe541 = 0x0040021D, + LedStripe542 = 0x0040021E, + LedStripe543 = 0x0040021F, + LedStripe544 = 0x00400220, + LedStripe545 = 0x00400221, + LedStripe546 = 0x00400222, + LedStripe547 = 0x00400223, + LedStripe548 = 0x00400224, + LedStripe549 = 0x00400225, + LedStripe550 = 0x00400226, + LedStripe551 = 0x00400227, + LedStripe552 = 0x00400228, + LedStripe553 = 0x00400229, + LedStripe554 = 0x0040022A, + LedStripe555 = 0x0040022B, + LedStripe556 = 0x0040022C, + LedStripe557 = 0x0040022D, + LedStripe558 = 0x0040022E, + LedStripe559 = 0x0040022F, + LedStripe560 = 0x00400230, + LedStripe561 = 0x00400231, + LedStripe562 = 0x00400232, + LedStripe563 = 0x00400233, + LedStripe564 = 0x00400234, + LedStripe565 = 0x00400235, + LedStripe566 = 0x00400236, + LedStripe567 = 0x00400237, + LedStripe568 = 0x00400238, + LedStripe569 = 0x00400239, + LedStripe570 = 0x0040023A, + LedStripe571 = 0x0040023B, + LedStripe572 = 0x0040023C, + LedStripe573 = 0x0040023D, + LedStripe574 = 0x0040023E, + LedStripe575 = 0x0040023F, + LedStripe576 = 0x00400240, + LedStripe577 = 0x00400241, + LedStripe578 = 0x00400242, + LedStripe579 = 0x00400243, + LedStripe580 = 0x00400244, + LedStripe581 = 0x00400245, + LedStripe582 = 0x00400246, + LedStripe583 = 0x00400247, + LedStripe584 = 0x00400248, + LedStripe585 = 0x00400249, + LedStripe586 = 0x0040024A, + LedStripe587 = 0x0040024B, + LedStripe588 = 0x0040024C, + LedStripe589 = 0x0040024D, + LedStripe590 = 0x0040024E, + LedStripe591 = 0x0040024F, + LedStripe592 = 0x00400250, + LedStripe593 = 0x00400251, + LedStripe594 = 0x00400252, + LedStripe595 = 0x00400253, + LedStripe596 = 0x00400254, + LedStripe597 = 0x00400255, + LedStripe598 = 0x00400256, + LedStripe599 = 0x00400257, + LedStripe600 = 0x00400258, + LedStripe601 = 0x00400259, + LedStripe602 = 0x0040025A, + LedStripe603 = 0x0040025B, + LedStripe604 = 0x0040025C, + LedStripe605 = 0x0040025D, + LedStripe606 = 0x0040025E, + LedStripe607 = 0x0040025F, + LedStripe608 = 0x00400260, + LedStripe609 = 0x00400261, + LedStripe610 = 0x00400262, + LedStripe611 = 0x00400263, + LedStripe612 = 0x00400264, + LedStripe613 = 0x00400265, + LedStripe614 = 0x00400266, + LedStripe615 = 0x00400267, + LedStripe616 = 0x00400268, + LedStripe617 = 0x00400269, + LedStripe618 = 0x0040026A, + LedStripe619 = 0x0040026B, + LedStripe620 = 0x0040026C, + LedStripe621 = 0x0040026D, + LedStripe622 = 0x0040026E, + LedStripe623 = 0x0040026F, + LedStripe624 = 0x00400270, + LedStripe625 = 0x00400271, + LedStripe626 = 0x00400272, + LedStripe627 = 0x00400273, + LedStripe628 = 0x00400274, + LedStripe629 = 0x00400275, + LedStripe630 = 0x00400276, + LedStripe631 = 0x00400277, + LedStripe632 = 0x00400278, + LedStripe633 = 0x00400279, + LedStripe634 = 0x0040027A, + LedStripe635 = 0x0040027B, + LedStripe636 = 0x0040027C, + LedStripe637 = 0x0040027D, + LedStripe638 = 0x0040027E, + LedStripe639 = 0x0040027F, + LedStripe640 = 0x00400280, + LedStripe641 = 0x00400281, + LedStripe642 = 0x00400282, + LedStripe643 = 0x00400283, + LedStripe644 = 0x00400284, + LedStripe645 = 0x00400285, + LedStripe646 = 0x00400286, + LedStripe647 = 0x00400287, + LedStripe648 = 0x00400288, + LedStripe649 = 0x00400289, + LedStripe650 = 0x0040028A, + LedStripe651 = 0x0040028B, + LedStripe652 = 0x0040028C, + LedStripe653 = 0x0040028D, + LedStripe654 = 0x0040028E, + LedStripe655 = 0x0040028F, + LedStripe656 = 0x00400290, + LedStripe657 = 0x00400291, + LedStripe658 = 0x00400292, + LedStripe659 = 0x00400293, + LedStripe660 = 0x00400294, + LedStripe661 = 0x00400295, + LedStripe662 = 0x00400296, + LedStripe663 = 0x00400297, + LedStripe664 = 0x00400298, + LedStripe665 = 0x00400299, + LedStripe666 = 0x0040029A, + LedStripe667 = 0x0040029B, + LedStripe668 = 0x0040029C, + LedStripe669 = 0x0040029D, + LedStripe670 = 0x0040029E, + LedStripe671 = 0x0040029F, + LedStripe672 = 0x004002A0, + LedStripe673 = 0x004002A1, + LedStripe674 = 0x004002A2, + LedStripe675 = 0x004002A3, + LedStripe676 = 0x004002A4, + LedStripe677 = 0x004002A5, + LedStripe678 = 0x004002A6, + LedStripe679 = 0x004002A7, + LedStripe680 = 0x004002A8, + LedStripe681 = 0x004002A9, + LedStripe682 = 0x004002AA, + LedStripe683 = 0x004002AB, + LedStripe684 = 0x004002AC, + LedStripe685 = 0x004002AD, + LedStripe686 = 0x004002AE, + LedStripe687 = 0x004002AF, + LedStripe688 = 0x004002B0, + LedStripe689 = 0x004002B1, + LedStripe690 = 0x004002B2, + LedStripe691 = 0x004002B3, + LedStripe692 = 0x004002B4, + LedStripe693 = 0x004002B5, + LedStripe694 = 0x004002B6, + LedStripe695 = 0x004002B7, + LedStripe696 = 0x004002B8, + LedStripe697 = 0x004002B9, + LedStripe698 = 0x004002BA, + LedStripe699 = 0x004002BB, + LedStripe700 = 0x004002BC, + LedStripe701 = 0x004002BD, + LedStripe702 = 0x004002BE, + LedStripe703 = 0x004002BF, + LedStripe704 = 0x004002C0, + LedStripe705 = 0x004002C1, + LedStripe706 = 0x004002C2, + LedStripe707 = 0x004002C3, + LedStripe708 = 0x004002C4, + LedStripe709 = 0x004002C5, + LedStripe710 = 0x004002C6, + LedStripe711 = 0x004002C7, + LedStripe712 = 0x004002C8, + LedStripe713 = 0x004002C9, + LedStripe714 = 0x004002CA, + LedStripe715 = 0x004002CB, + LedStripe716 = 0x004002CC, + LedStripe717 = 0x004002CD, + LedStripe718 = 0x004002CE, + LedStripe719 = 0x004002CF, + LedStripe720 = 0x004002D0, + LedStripe721 = 0x004002D1, + LedStripe722 = 0x004002D2, + LedStripe723 = 0x004002D3, + LedStripe724 = 0x004002D4, + LedStripe725 = 0x004002D5, + LedStripe726 = 0x004002D6, + LedStripe727 = 0x004002D7, + LedStripe728 = 0x004002D8, + LedStripe729 = 0x004002D9, + LedStripe730 = 0x004002DA, + LedStripe731 = 0x004002DB, + LedStripe732 = 0x004002DC, + LedStripe733 = 0x004002DD, + LedStripe734 = 0x004002DE, + LedStripe735 = 0x004002DF, + LedStripe736 = 0x004002E0, + LedStripe737 = 0x004002E1, + LedStripe738 = 0x004002E2, + LedStripe739 = 0x004002E3, + LedStripe740 = 0x004002E4, + LedStripe741 = 0x004002E5, + LedStripe742 = 0x004002E6, + LedStripe743 = 0x004002E7, + LedStripe744 = 0x004002E8, + LedStripe745 = 0x004002E9, + LedStripe746 = 0x004002EA, + LedStripe747 = 0x004002EB, + LedStripe748 = 0x004002EC, + LedStripe749 = 0x004002ED, + LedStripe750 = 0x004002EE, + LedStripe751 = 0x004002EF, + LedStripe752 = 0x004002F0, + LedStripe753 = 0x004002F1, + LedStripe754 = 0x004002F2, + LedStripe755 = 0x004002F3, + LedStripe756 = 0x004002F4, + LedStripe757 = 0x004002F5, + LedStripe758 = 0x004002F6, + LedStripe759 = 0x004002F7, + LedStripe760 = 0x004002F8, + LedStripe761 = 0x004002F9, + LedStripe762 = 0x004002FA, + LedStripe763 = 0x004002FB, + LedStripe764 = 0x004002FC, + LedStripe765 = 0x004002FD, + LedStripe766 = 0x004002FE, + LedStripe767 = 0x004002FF, + LedStripe768 = 0x00400300, + LedStripe769 = 0x00400301, + LedStripe770 = 0x00400302, + LedStripe771 = 0x00400303, + LedStripe772 = 0x00400304, + LedStripe773 = 0x00400305, + LedStripe774 = 0x00400306, + LedStripe775 = 0x00400307, + LedStripe776 = 0x00400308, + LedStripe777 = 0x00400309, + LedStripe778 = 0x0040030A, + LedStripe779 = 0x0040030B, + LedStripe780 = 0x0040030C, + LedStripe781 = 0x0040030D, + LedStripe782 = 0x0040030E, + LedStripe783 = 0x0040030F, + LedStripe784 = 0x00400310, + LedStripe785 = 0x00400311, + LedStripe786 = 0x00400312, + LedStripe787 = 0x00400313, + LedStripe788 = 0x00400314, + LedStripe789 = 0x00400315, + LedStripe790 = 0x00400316, + LedStripe791 = 0x00400317, + LedStripe792 = 0x00400318, + LedStripe793 = 0x00400319, + LedStripe794 = 0x0040031A, + LedStripe795 = 0x0040031B, + LedStripe796 = 0x0040031C, + LedStripe797 = 0x0040031D, + LedStripe798 = 0x0040031E, + LedStripe799 = 0x0040031F, + LedStripe800 = 0x00400320, + LedStripe801 = 0x00400321, + LedStripe802 = 0x00400322, + LedStripe803 = 0x00400323, + LedStripe804 = 0x00400324, + LedStripe805 = 0x00400325, + LedStripe806 = 0x00400326, + LedStripe807 = 0x00400327, + LedStripe808 = 0x00400328, + LedStripe809 = 0x00400329, + LedStripe810 = 0x0040032A, + LedStripe811 = 0x0040032B, + LedStripe812 = 0x0040032C, + LedStripe813 = 0x0040032D, + LedStripe814 = 0x0040032E, + LedStripe815 = 0x0040032F, + LedStripe816 = 0x00400330, + LedStripe817 = 0x00400331, + LedStripe818 = 0x00400332, + LedStripe819 = 0x00400333, + LedStripe820 = 0x00400334, + LedStripe821 = 0x00400335, + LedStripe822 = 0x00400336, + LedStripe823 = 0x00400337, + LedStripe824 = 0x00400338, + LedStripe825 = 0x00400339, + LedStripe826 = 0x0040033A, + LedStripe827 = 0x0040033B, + LedStripe828 = 0x0040033C, + LedStripe829 = 0x0040033D, + LedStripe830 = 0x0040033E, + LedStripe831 = 0x0040033F, + LedStripe832 = 0x00400340, + LedStripe833 = 0x00400341, + LedStripe834 = 0x00400342, + LedStripe835 = 0x00400343, + LedStripe836 = 0x00400344, + LedStripe837 = 0x00400345, + LedStripe838 = 0x00400346, + LedStripe839 = 0x00400347, + LedStripe840 = 0x00400348, + LedStripe841 = 0x00400349, + LedStripe842 = 0x0040034A, + LedStripe843 = 0x0040034B, + LedStripe844 = 0x0040034C, + LedStripe845 = 0x0040034D, + LedStripe846 = 0x0040034E, + LedStripe847 = 0x0040034F, + LedStripe848 = 0x00400350, + LedStripe849 = 0x00400351, + LedStripe850 = 0x00400352, + LedStripe851 = 0x00400353, + LedStripe852 = 0x00400354, + LedStripe853 = 0x00400355, + LedStripe854 = 0x00400356, + LedStripe855 = 0x00400357, + LedStripe856 = 0x00400358, + LedStripe857 = 0x00400359, + LedStripe858 = 0x0040035A, + LedStripe859 = 0x0040035B, + LedStripe860 = 0x0040035C, + LedStripe861 = 0x0040035D, + LedStripe862 = 0x0040035E, + LedStripe863 = 0x0040035F, + LedStripe864 = 0x00400360, + LedStripe865 = 0x00400361, + LedStripe866 = 0x00400362, + LedStripe867 = 0x00400363, + LedStripe868 = 0x00400364, + LedStripe869 = 0x00400365, + LedStripe870 = 0x00400366, + LedStripe871 = 0x00400367, + LedStripe872 = 0x00400368, + LedStripe873 = 0x00400369, + LedStripe874 = 0x0040036A, + LedStripe875 = 0x0040036B, + LedStripe876 = 0x0040036C, + LedStripe877 = 0x0040036D, + LedStripe878 = 0x0040036E, + LedStripe879 = 0x0040036F, + LedStripe880 = 0x00400370, + LedStripe881 = 0x00400371, + LedStripe882 = 0x00400372, + LedStripe883 = 0x00400373, + LedStripe884 = 0x00400374, + LedStripe885 = 0x00400375, + LedStripe886 = 0x00400376, + LedStripe887 = 0x00400377, + LedStripe888 = 0x00400378, + LedStripe889 = 0x00400379, + LedStripe890 = 0x0040037A, + LedStripe891 = 0x0040037B, + LedStripe892 = 0x0040037C, + LedStripe893 = 0x0040037D, + LedStripe894 = 0x0040037E, + LedStripe895 = 0x0040037F, + LedStripe896 = 0x00400380, + LedStripe897 = 0x00400381, + LedStripe898 = 0x00400382, + LedStripe899 = 0x00400383, + LedStripe900 = 0x00400384, + LedStripe901 = 0x00400385, + LedStripe902 = 0x00400386, + LedStripe903 = 0x00400387, + LedStripe904 = 0x00400388, + LedStripe905 = 0x00400389, + LedStripe906 = 0x0040038A, + LedStripe907 = 0x0040038B, + LedStripe908 = 0x0040038C, + LedStripe909 = 0x0040038D, + LedStripe910 = 0x0040038E, + LedStripe911 = 0x0040038F, + LedStripe912 = 0x00400390, + LedStripe913 = 0x00400391, + LedStripe914 = 0x00400392, + LedStripe915 = 0x00400393, + LedStripe916 = 0x00400394, + LedStripe917 = 0x00400395, + LedStripe918 = 0x00400396, + LedStripe919 = 0x00400397, + LedStripe920 = 0x00400398, + LedStripe921 = 0x00400399, + LedStripe922 = 0x0040039A, + LedStripe923 = 0x0040039B, + LedStripe924 = 0x0040039C, + LedStripe925 = 0x0040039D, + LedStripe926 = 0x0040039E, + LedStripe927 = 0x0040039F, + LedStripe928 = 0x004003A0, + LedStripe929 = 0x004003A1, + LedStripe930 = 0x004003A2, + LedStripe931 = 0x004003A3, + LedStripe932 = 0x004003A4, + LedStripe933 = 0x004003A5, + LedStripe934 = 0x004003A6, + LedStripe935 = 0x004003A7, + LedStripe936 = 0x004003A8, + LedStripe937 = 0x004003A9, + LedStripe938 = 0x004003AA, + LedStripe939 = 0x004003AB, + LedStripe940 = 0x004003AC, + LedStripe941 = 0x004003AD, + LedStripe942 = 0x004003AE, + LedStripe943 = 0x004003AF, + LedStripe944 = 0x004003B0, + LedStripe945 = 0x004003B1, + LedStripe946 = 0x004003B2, + LedStripe947 = 0x004003B3, + LedStripe948 = 0x004003B4, + LedStripe949 = 0x004003B5, + LedStripe950 = 0x004003B6, + LedStripe951 = 0x004003B7, + LedStripe952 = 0x004003B8, + LedStripe953 = 0x004003B9, + LedStripe954 = 0x004003BA, + LedStripe955 = 0x004003BB, + LedStripe956 = 0x004003BC, + LedStripe957 = 0x004003BD, + LedStripe958 = 0x004003BE, + LedStripe959 = 0x004003BF, + LedStripe960 = 0x004003C0, + LedStripe961 = 0x004003C1, + LedStripe962 = 0x004003C2, + LedStripe963 = 0x004003C3, + LedStripe964 = 0x004003C4, + LedStripe965 = 0x004003C5, + LedStripe966 = 0x004003C6, + LedStripe967 = 0x004003C7, + LedStripe968 = 0x004003C8, + LedStripe969 = 0x004003C9, + LedStripe970 = 0x004003CA, + LedStripe971 = 0x004003CB, + LedStripe972 = 0x004003CC, + LedStripe973 = 0x004003CD, + LedStripe974 = 0x004003CE, + LedStripe975 = 0x004003CF, + LedStripe976 = 0x004003D0, + LedStripe977 = 0x004003D1, + LedStripe978 = 0x004003D2, + LedStripe979 = 0x004003D3, + LedStripe980 = 0x004003D4, + LedStripe981 = 0x004003D5, + LedStripe982 = 0x004003D6, + LedStripe983 = 0x004003D7, + LedStripe984 = 0x004003D8, + LedStripe985 = 0x004003D9, + LedStripe986 = 0x004003DA, + LedStripe987 = 0x004003DB, + LedStripe988 = 0x004003DC, + LedStripe989 = 0x004003DD, + LedStripe990 = 0x004003DE, + LedStripe991 = 0x004003DF, + LedStripe992 = 0x004003E0, + LedStripe993 = 0x004003E1, + LedStripe994 = 0x004003E2, + LedStripe995 = 0x004003E3, + LedStripe996 = 0x004003E4, + LedStripe997 = 0x004003E5, + LedStripe998 = 0x004003E6, + LedStripe999 = 0x004003E7, + LedStripe1000 = 0x004003E8, + LedStripe1001 = 0x004003E9, + LedStripe1002 = 0x004003EA, + LedStripe1003 = 0x004003EB, + LedStripe1004 = 0x004003EC, + LedStripe1005 = 0x004003ED, + LedStripe1006 = 0x004003EE, + LedStripe1007 = 0x004003EF, + LedStripe1008 = 0x004003F0, + LedStripe1009 = 0x004003F1, + LedStripe1010 = 0x004003F2, + LedStripe1011 = 0x004003F3, + LedStripe1012 = 0x004003F4, + LedStripe1013 = 0x004003F5, + LedStripe1014 = 0x004003F6, + LedStripe1015 = 0x004003F7, + LedStripe1016 = 0x004003F8, + LedStripe1017 = 0x004003F9, + LedStripe1018 = 0x004003FA, + LedStripe1019 = 0x004003FB, + LedStripe1020 = 0x004003FC, + LedStripe1021 = 0x004003FD, + LedStripe1022 = 0x004003FE, + LedStripe1023 = 0x004003FF, + LedStripe1024 = 0x00400400, + LedStripe1025 = 0x00400401, + LedStripe1026 = 0x00400402, + LedStripe1027 = 0x00400403, + LedStripe1028 = 0x00400404, + LedStripe1029 = 0x00400405, + LedStripe1030 = 0x00400406, + LedStripe1031 = 0x00400407, + LedStripe1032 = 0x00400408, + LedStripe1033 = 0x00400409, + LedStripe1034 = 0x0040040A, + LedStripe1035 = 0x0040040B, + LedStripe1036 = 0x0040040C, + LedStripe1037 = 0x0040040D, + LedStripe1038 = 0x0040040E, + LedStripe1039 = 0x0040040F, + LedStripe1040 = 0x00400410, + LedStripe1041 = 0x00400411, + LedStripe1042 = 0x00400412, + LedStripe1043 = 0x00400413, + LedStripe1044 = 0x00400414, + LedStripe1045 = 0x00400415, + LedStripe1046 = 0x00400416, + LedStripe1047 = 0x00400417, + LedStripe1048 = 0x00400418, + LedStripe1049 = 0x00400419, + LedStripe1050 = 0x0040041A, + LedStripe1051 = 0x0040041B, + LedStripe1052 = 0x0040041C, + LedStripe1053 = 0x0040041D, + LedStripe1054 = 0x0040041E, + LedStripe1055 = 0x0040041F, + LedStripe1056 = 0x00400420, + LedStripe1057 = 0x00400421, + LedStripe1058 = 0x00400422, + LedStripe1059 = 0x00400423, + LedStripe1060 = 0x00400424, + LedStripe1061 = 0x00400425, + LedStripe1062 = 0x00400426, + LedStripe1063 = 0x00400427, + LedStripe1064 = 0x00400428, + LedStripe1065 = 0x00400429, + LedStripe1066 = 0x0040042A, + LedStripe1067 = 0x0040042B, + LedStripe1068 = 0x0040042C, + LedStripe1069 = 0x0040042D, + LedStripe1070 = 0x0040042E, + LedStripe1071 = 0x0040042F, + LedStripe1072 = 0x00400430, + LedStripe1073 = 0x00400431, + LedStripe1074 = 0x00400432, + LedStripe1075 = 0x00400433, + LedStripe1076 = 0x00400434, + LedStripe1077 = 0x00400435, + LedStripe1078 = 0x00400436, + LedStripe1079 = 0x00400437, + LedStripe1080 = 0x00400438, + LedStripe1081 = 0x00400439, + LedStripe1082 = 0x0040043A, + LedStripe1083 = 0x0040043B, + LedStripe1084 = 0x0040043C, + LedStripe1085 = 0x0040043D, + LedStripe1086 = 0x0040043E, + LedStripe1087 = 0x0040043F, + LedStripe1088 = 0x00400440, + LedStripe1089 = 0x00400441, + LedStripe1090 = 0x00400442, + LedStripe1091 = 0x00400443, + LedStripe1092 = 0x00400444, + LedStripe1093 = 0x00400445, + LedStripe1094 = 0x00400446, + LedStripe1095 = 0x00400447, + LedStripe1096 = 0x00400448, + LedStripe1097 = 0x00400449, + LedStripe1098 = 0x0040044A, + LedStripe1099 = 0x0040044B, + LedStripe1100 = 0x0040044C, + LedStripe1101 = 0x0040044D, + LedStripe1102 = 0x0040044E, + LedStripe1103 = 0x0040044F, + LedStripe1104 = 0x00400450, + LedStripe1105 = 0x00400451, + LedStripe1106 = 0x00400452, + LedStripe1107 = 0x00400453, + LedStripe1108 = 0x00400454, + LedStripe1109 = 0x00400455, + LedStripe1110 = 0x00400456, + LedStripe1111 = 0x00400457, + LedStripe1112 = 0x00400458, + LedStripe1113 = 0x00400459, + LedStripe1114 = 0x0040045A, + LedStripe1115 = 0x0040045B, + LedStripe1116 = 0x0040045C, + LedStripe1117 = 0x0040045D, + LedStripe1118 = 0x0040045E, + LedStripe1119 = 0x0040045F, + LedStripe1120 = 0x00400460, + LedStripe1121 = 0x00400461, + LedStripe1122 = 0x00400462, + LedStripe1123 = 0x00400463, + LedStripe1124 = 0x00400464, + LedStripe1125 = 0x00400465, + LedStripe1126 = 0x00400466, + LedStripe1127 = 0x00400467, + LedStripe1128 = 0x00400468, + LedStripe1129 = 0x00400469, + LedStripe1130 = 0x0040046A, + LedStripe1131 = 0x0040046B, + LedStripe1132 = 0x0040046C, + LedStripe1133 = 0x0040046D, + LedStripe1134 = 0x0040046E, + LedStripe1135 = 0x0040046F, + LedStripe1136 = 0x00400470, + LedStripe1137 = 0x00400471, + LedStripe1138 = 0x00400472, + LedStripe1139 = 0x00400473, + LedStripe1140 = 0x00400474, + LedStripe1141 = 0x00400475, + LedStripe1142 = 0x00400476, + LedStripe1143 = 0x00400477, + LedStripe1144 = 0x00400478, + LedStripe1145 = 0x00400479, + LedStripe1146 = 0x0040047A, + LedStripe1147 = 0x0040047B, + LedStripe1148 = 0x0040047C, + LedStripe1149 = 0x0040047D, + LedStripe1150 = 0x0040047E, + LedStripe1151 = 0x0040047F, + LedStripe1152 = 0x00400480, + LedStripe1153 = 0x00400481, + LedStripe1154 = 0x00400482, + LedStripe1155 = 0x00400483, + LedStripe1156 = 0x00400484, + LedStripe1157 = 0x00400485, + LedStripe1158 = 0x00400486, + LedStripe1159 = 0x00400487, + LedStripe1160 = 0x00400488, + LedStripe1161 = 0x00400489, + LedStripe1162 = 0x0040048A, + LedStripe1163 = 0x0040048B, + LedStripe1164 = 0x0040048C, + LedStripe1165 = 0x0040048D, + LedStripe1166 = 0x0040048E, + LedStripe1167 = 0x0040048F, + LedStripe1168 = 0x00400490, + LedStripe1169 = 0x00400491, + LedStripe1170 = 0x00400492, + LedStripe1171 = 0x00400493, + LedStripe1172 = 0x00400494, + LedStripe1173 = 0x00400495, + LedStripe1174 = 0x00400496, + LedStripe1175 = 0x00400497, + LedStripe1176 = 0x00400498, + LedStripe1177 = 0x00400499, + LedStripe1178 = 0x0040049A, + LedStripe1179 = 0x0040049B, + LedStripe1180 = 0x0040049C, + LedStripe1181 = 0x0040049D, + LedStripe1182 = 0x0040049E, + LedStripe1183 = 0x0040049F, + LedStripe1184 = 0x004004A0, + LedStripe1185 = 0x004004A1, + LedStripe1186 = 0x004004A2, + LedStripe1187 = 0x004004A3, + LedStripe1188 = 0x004004A4, + LedStripe1189 = 0x004004A5, + LedStripe1190 = 0x004004A6, + LedStripe1191 = 0x004004A7, + LedStripe1192 = 0x004004A8, + LedStripe1193 = 0x004004A9, + LedStripe1194 = 0x004004AA, + LedStripe1195 = 0x004004AB, + LedStripe1196 = 0x004004AC, + LedStripe1197 = 0x004004AD, + LedStripe1198 = 0x004004AE, + LedStripe1199 = 0x004004AF, + LedStripe1200 = 0x004004B0, + LedStripe1201 = 0x004004B1, + LedStripe1202 = 0x004004B2, + LedStripe1203 = 0x004004B3, + LedStripe1204 = 0x004004B4, + LedStripe1205 = 0x004004B5, + LedStripe1206 = 0x004004B6, + LedStripe1207 = 0x004004B7, + LedStripe1208 = 0x004004B8, + LedStripe1209 = 0x004004B9, + LedStripe1210 = 0x004004BA, + LedStripe1211 = 0x004004BB, + LedStripe1212 = 0x004004BC, + LedStripe1213 = 0x004004BD, + LedStripe1214 = 0x004004BE, + LedStripe1215 = 0x004004BF, + LedStripe1216 = 0x004004C0, + LedStripe1217 = 0x004004C1, + LedStripe1218 = 0x004004C2, + LedStripe1219 = 0x004004C3, + LedStripe1220 = 0x004004C4, + LedStripe1221 = 0x004004C5, + LedStripe1222 = 0x004004C6, + LedStripe1223 = 0x004004C7, + LedStripe1224 = 0x004004C8, + LedStripe1225 = 0x004004C9, + LedStripe1226 = 0x004004CA, + LedStripe1227 = 0x004004CB, + LedStripe1228 = 0x004004CC, + LedStripe1229 = 0x004004CD, + LedStripe1230 = 0x004004CE, + LedStripe1231 = 0x004004CF, + LedStripe1232 = 0x004004D0, + LedStripe1233 = 0x004004D1, + LedStripe1234 = 0x004004D2, + LedStripe1235 = 0x004004D3, + LedStripe1236 = 0x004004D4, + LedStripe1237 = 0x004004D5, + LedStripe1238 = 0x004004D6, + LedStripe1239 = 0x004004D7, + LedStripe1240 = 0x004004D8, + LedStripe1241 = 0x004004D9, + LedStripe1242 = 0x004004DA, + LedStripe1243 = 0x004004DB, + LedStripe1244 = 0x004004DC, + LedStripe1245 = 0x004004DD, + LedStripe1246 = 0x004004DE, + LedStripe1247 = 0x004004DF, + LedStripe1248 = 0x004004E0, + LedStripe1249 = 0x004004E1, + LedStripe1250 = 0x004004E2, + LedStripe1251 = 0x004004E3, + LedStripe1252 = 0x004004E4, + LedStripe1253 = 0x004004E5, + LedStripe1254 = 0x004004E6, + LedStripe1255 = 0x004004E7, + LedStripe1256 = 0x004004E8, + LedStripe1257 = 0x004004E9, + LedStripe1258 = 0x004004EA, + LedStripe1259 = 0x004004EB, + LedStripe1260 = 0x004004EC, + LedStripe1261 = 0x004004ED, + LedStripe1262 = 0x004004EE, + LedStripe1263 = 0x004004EF, + LedStripe1264 = 0x004004F0, + LedStripe1265 = 0x004004F1, + LedStripe1266 = 0x004004F2, + LedStripe1267 = 0x004004F3, + LedStripe1268 = 0x004004F4, + LedStripe1269 = 0x004004F5, + LedStripe1270 = 0x004004F6, + LedStripe1271 = 0x004004F7, + LedStripe1272 = 0x004004F8, + LedStripe1273 = 0x004004F9, + LedStripe1274 = 0x004004FA, + LedStripe1275 = 0x004004FB, + LedStripe1276 = 0x004004FC, + LedStripe1277 = 0x004004FD, + LedStripe1278 = 0x004004FE, + LedStripe1279 = 0x004004FF, + LedStripe1280 = 0x00400500, + LedStripe1281 = 0x00400501, + LedStripe1282 = 0x00400502, + LedStripe1283 = 0x00400503, + LedStripe1284 = 0x00400504, + LedStripe1285 = 0x00400505, + LedStripe1286 = 0x00400506, + LedStripe1287 = 0x00400507, + LedStripe1288 = 0x00400508, + LedStripe1289 = 0x00400509, + LedStripe1290 = 0x0040050A, + LedStripe1291 = 0x0040050B, + LedStripe1292 = 0x0040050C, + LedStripe1293 = 0x0040050D, + LedStripe1294 = 0x0040050E, + LedStripe1295 = 0x0040050F, + LedStripe1296 = 0x00400510, + LedStripe1297 = 0x00400511, + LedStripe1298 = 0x00400512, + LedStripe1299 = 0x00400513, + LedStripe1300 = 0x00400514, + LedStripe1301 = 0x00400515, + LedStripe1302 = 0x00400516, + LedStripe1303 = 0x00400517, + LedStripe1304 = 0x00400518, + LedStripe1305 = 0x00400519, + LedStripe1306 = 0x0040051A, + LedStripe1307 = 0x0040051B, + LedStripe1308 = 0x0040051C, + LedStripe1309 = 0x0040051D, + LedStripe1310 = 0x0040051E, + LedStripe1311 = 0x0040051F, + LedStripe1312 = 0x00400520, + LedStripe1313 = 0x00400521, + LedStripe1314 = 0x00400522, + LedStripe1315 = 0x00400523, + LedStripe1316 = 0x00400524, + LedStripe1317 = 0x00400525, + LedStripe1318 = 0x00400526, + LedStripe1319 = 0x00400527, + LedStripe1320 = 0x00400528, + LedStripe1321 = 0x00400529, + LedStripe1322 = 0x0040052A, + LedStripe1323 = 0x0040052B, + LedStripe1324 = 0x0040052C, + LedStripe1325 = 0x0040052D, + LedStripe1326 = 0x0040052E, + LedStripe1327 = 0x0040052F, + LedStripe1328 = 0x00400530, + LedStripe1329 = 0x00400531, + LedStripe1330 = 0x00400532, + LedStripe1331 = 0x00400533, + LedStripe1332 = 0x00400534, + LedStripe1333 = 0x00400535, + LedStripe1334 = 0x00400536, + LedStripe1335 = 0x00400537, + LedStripe1336 = 0x00400538, + LedStripe1337 = 0x00400539, + LedStripe1338 = 0x0040053A, + LedStripe1339 = 0x0040053B, + LedStripe1340 = 0x0040053C, + LedStripe1341 = 0x0040053D, + LedStripe1342 = 0x0040053E, + LedStripe1343 = 0x0040053F, + LedStripe1344 = 0x00400540, + LedStripe1345 = 0x00400541, + LedStripe1346 = 0x00400542, + LedStripe1347 = 0x00400543, + LedStripe1348 = 0x00400544, + LedStripe1349 = 0x00400545, + LedStripe1350 = 0x00400546, + LedStripe1351 = 0x00400547, + LedStripe1352 = 0x00400548, + LedStripe1353 = 0x00400549, + LedStripe1354 = 0x0040054A, + LedStripe1355 = 0x0040054B, + LedStripe1356 = 0x0040054C, + LedStripe1357 = 0x0040054D, + LedStripe1358 = 0x0040054E, + LedStripe1359 = 0x0040054F, + LedStripe1360 = 0x00400550, + LedStripe1361 = 0x00400551, + LedStripe1362 = 0x00400552, + LedStripe1363 = 0x00400553, + LedStripe1364 = 0x00400554, + LedStripe1365 = 0x00400555, + LedStripe1366 = 0x00400556, + LedStripe1367 = 0x00400557, + LedStripe1368 = 0x00400558, + LedStripe1369 = 0x00400559, + LedStripe1370 = 0x0040055A, + LedStripe1371 = 0x0040055B, + LedStripe1372 = 0x0040055C, + LedStripe1373 = 0x0040055D, + LedStripe1374 = 0x0040055E, + LedStripe1375 = 0x0040055F, + LedStripe1376 = 0x00400560, + LedStripe1377 = 0x00400561, + LedStripe1378 = 0x00400562, + LedStripe1379 = 0x00400563, + LedStripe1380 = 0x00400564, + LedStripe1381 = 0x00400565, + LedStripe1382 = 0x00400566, + LedStripe1383 = 0x00400567, + LedStripe1384 = 0x00400568, + LedStripe1385 = 0x00400569, + LedStripe1386 = 0x0040056A, + LedStripe1387 = 0x0040056B, + LedStripe1388 = 0x0040056C, + LedStripe1389 = 0x0040056D, + LedStripe1390 = 0x0040056E, + LedStripe1391 = 0x0040056F, + LedStripe1392 = 0x00400570, + LedStripe1393 = 0x00400571, + LedStripe1394 = 0x00400572, + LedStripe1395 = 0x00400573, + LedStripe1396 = 0x00400574, + LedStripe1397 = 0x00400575, + LedStripe1398 = 0x00400576, + LedStripe1399 = 0x00400577, + LedStripe1400 = 0x00400578, + LedStripe1401 = 0x00400579, + LedStripe1402 = 0x0040057A, + LedStripe1403 = 0x0040057B, + LedStripe1404 = 0x0040057C, + LedStripe1405 = 0x0040057D, + LedStripe1406 = 0x0040057E, + LedStripe1407 = 0x0040057F, + LedStripe1408 = 0x00400580, + LedStripe1409 = 0x00400581, + LedStripe1410 = 0x00400582, + LedStripe1411 = 0x00400583, + LedStripe1412 = 0x00400584, + LedStripe1413 = 0x00400585, + LedStripe1414 = 0x00400586, + LedStripe1415 = 0x00400587, + LedStripe1416 = 0x00400588, + LedStripe1417 = 0x00400589, + LedStripe1418 = 0x0040058A, + LedStripe1419 = 0x0040058B, + LedStripe1420 = 0x0040058C, + LedStripe1421 = 0x0040058D, + LedStripe1422 = 0x0040058E, + LedStripe1423 = 0x0040058F, + LedStripe1424 = 0x00400590, + LedStripe1425 = 0x00400591, + LedStripe1426 = 0x00400592, + LedStripe1427 = 0x00400593, + LedStripe1428 = 0x00400594, + LedStripe1429 = 0x00400595, + LedStripe1430 = 0x00400596, + LedStripe1431 = 0x00400597, + LedStripe1432 = 0x00400598, + LedStripe1433 = 0x00400599, + LedStripe1434 = 0x0040059A, + LedStripe1435 = 0x0040059B, + LedStripe1436 = 0x0040059C, + LedStripe1437 = 0x0040059D, + LedStripe1438 = 0x0040059E, + LedStripe1439 = 0x0040059F, + LedStripe1440 = 0x004005A0, + LedStripe1441 = 0x004005A1, + LedStripe1442 = 0x004005A2, + LedStripe1443 = 0x004005A3, + LedStripe1444 = 0x004005A4, + LedStripe1445 = 0x004005A5, + LedStripe1446 = 0x004005A6, + LedStripe1447 = 0x004005A7, + LedStripe1448 = 0x004005A8, + LedStripe1449 = 0x004005A9, + LedStripe1450 = 0x004005AA, + LedStripe1451 = 0x004005AB, + LedStripe1452 = 0x004005AC, + LedStripe1453 = 0x004005AD, + LedStripe1454 = 0x004005AE, + LedStripe1455 = 0x004005AF, + LedStripe1456 = 0x004005B0, + LedStripe1457 = 0x004005B1, + LedStripe1458 = 0x004005B2, + LedStripe1459 = 0x004005B3, + LedStripe1460 = 0x004005B4, + LedStripe1461 = 0x004005B5, + LedStripe1462 = 0x004005B6, + LedStripe1463 = 0x004005B7, + LedStripe1464 = 0x004005B8, + LedStripe1465 = 0x004005B9, + LedStripe1466 = 0x004005BA, + LedStripe1467 = 0x004005BB, + LedStripe1468 = 0x004005BC, + LedStripe1469 = 0x004005BD, + LedStripe1470 = 0x004005BE, + LedStripe1471 = 0x004005BF, + LedStripe1472 = 0x004005C0, + LedStripe1473 = 0x004005C1, + LedStripe1474 = 0x004005C2, + LedStripe1475 = 0x004005C3, + LedStripe1476 = 0x004005C4, + LedStripe1477 = 0x004005C5, + LedStripe1478 = 0x004005C6, + LedStripe1479 = 0x004005C7, + LedStripe1480 = 0x004005C8, + LedStripe1481 = 0x004005C9, + LedStripe1482 = 0x004005CA, + LedStripe1483 = 0x004005CB, + LedStripe1484 = 0x004005CC, + LedStripe1485 = 0x004005CD, + LedStripe1486 = 0x004005CE, + LedStripe1487 = 0x004005CF, + LedStripe1488 = 0x004005D0, + LedStripe1489 = 0x004005D1, + LedStripe1490 = 0x004005D2, + LedStripe1491 = 0x004005D3, + LedStripe1492 = 0x004005D4, + LedStripe1493 = 0x004005D5, + LedStripe1494 = 0x004005D6, + LedStripe1495 = 0x004005D7, + LedStripe1496 = 0x004005D8, + LedStripe1497 = 0x004005D9, + LedStripe1498 = 0x004005DA, + LedStripe1499 = 0x004005DB, + LedStripe1500 = 0x004005DC, + LedStripe1501 = 0x004005DD, + LedStripe1502 = 0x004005DE, + LedStripe1503 = 0x004005DF, + LedStripe1504 = 0x004005E0, + LedStripe1505 = 0x004005E1, + LedStripe1506 = 0x004005E2, + LedStripe1507 = 0x004005E3, + LedStripe1508 = 0x004005E4, + LedStripe1509 = 0x004005E5, + LedStripe1510 = 0x004005E6, + LedStripe1511 = 0x004005E7, + LedStripe1512 = 0x004005E8, + LedStripe1513 = 0x004005E9, + LedStripe1514 = 0x004005EA, + LedStripe1515 = 0x004005EB, + LedStripe1516 = 0x004005EC, + LedStripe1517 = 0x004005ED, + LedStripe1518 = 0x004005EE, + LedStripe1519 = 0x004005EF, + LedStripe1520 = 0x004005F0, + LedStripe1521 = 0x004005F1, + LedStripe1522 = 0x004005F2, + LedStripe1523 = 0x004005F3, + LedStripe1524 = 0x004005F4, + LedStripe1525 = 0x004005F5, + LedStripe1526 = 0x004005F6, + LedStripe1527 = 0x004005F7, + LedStripe1528 = 0x004005F8, + LedStripe1529 = 0x004005F9, + LedStripe1530 = 0x004005FA, + LedStripe1531 = 0x004005FB, + LedStripe1532 = 0x004005FC, + LedStripe1533 = 0x004005FD, + LedStripe1534 = 0x004005FE, + LedStripe1535 = 0x004005FF, + LedStripe1536 = 0x00400600, + LedStripe1537 = 0x00400601, + LedStripe1538 = 0x00400602, + LedStripe1539 = 0x00400603, + LedStripe1540 = 0x00400604, + LedStripe1541 = 0x00400605, + LedStripe1542 = 0x00400606, + LedStripe1543 = 0x00400607, + LedStripe1544 = 0x00400608, + LedStripe1545 = 0x00400609, + LedStripe1546 = 0x0040060A, + LedStripe1547 = 0x0040060B, + LedStripe1548 = 0x0040060C, + LedStripe1549 = 0x0040060D, + LedStripe1550 = 0x0040060E, + LedStripe1551 = 0x0040060F, + LedStripe1552 = 0x00400610, + LedStripe1553 = 0x00400611, + LedStripe1554 = 0x00400612, + LedStripe1555 = 0x00400613, + LedStripe1556 = 0x00400614, + LedStripe1557 = 0x00400615, + LedStripe1558 = 0x00400616, + LedStripe1559 = 0x00400617, + LedStripe1560 = 0x00400618, + LedStripe1561 = 0x00400619, + LedStripe1562 = 0x0040061A, + LedStripe1563 = 0x0040061B, + LedStripe1564 = 0x0040061C, + LedStripe1565 = 0x0040061D, + LedStripe1566 = 0x0040061E, + LedStripe1567 = 0x0040061F, + LedStripe1568 = 0x00400620, + LedStripe1569 = 0x00400621, + LedStripe1570 = 0x00400622, + LedStripe1571 = 0x00400623, + LedStripe1572 = 0x00400624, + LedStripe1573 = 0x00400625, + LedStripe1574 = 0x00400626, + LedStripe1575 = 0x00400627, + LedStripe1576 = 0x00400628, + LedStripe1577 = 0x00400629, + LedStripe1578 = 0x0040062A, + LedStripe1579 = 0x0040062B, + LedStripe1580 = 0x0040062C, + LedStripe1581 = 0x0040062D, + LedStripe1582 = 0x0040062E, + LedStripe1583 = 0x0040062F, + LedStripe1584 = 0x00400630, + LedStripe1585 = 0x00400631, + LedStripe1586 = 0x00400632, + LedStripe1587 = 0x00400633, + LedStripe1588 = 0x00400634, + LedStripe1589 = 0x00400635, + LedStripe1590 = 0x00400636, + LedStripe1591 = 0x00400637, + LedStripe1592 = 0x00400638, + LedStripe1593 = 0x00400639, + LedStripe1594 = 0x0040063A, + LedStripe1595 = 0x0040063B, + LedStripe1596 = 0x0040063C, + LedStripe1597 = 0x0040063D, + LedStripe1598 = 0x0040063E, + LedStripe1599 = 0x0040063F, + LedStripe1600 = 0x00400640, + LedStripe1601 = 0x00400641, + LedStripe1602 = 0x00400642, + LedStripe1603 = 0x00400643, + LedStripe1604 = 0x00400644, + LedStripe1605 = 0x00400645, + LedStripe1606 = 0x00400646, + LedStripe1607 = 0x00400647, + LedStripe1608 = 0x00400648, + LedStripe1609 = 0x00400649, + LedStripe1610 = 0x0040064A, + LedStripe1611 = 0x0040064B, + LedStripe1612 = 0x0040064C, + LedStripe1613 = 0x0040064D, + LedStripe1614 = 0x0040064E, + LedStripe1615 = 0x0040064F, + LedStripe1616 = 0x00400650, + LedStripe1617 = 0x00400651, + LedStripe1618 = 0x00400652, + LedStripe1619 = 0x00400653, + LedStripe1620 = 0x00400654, + LedStripe1621 = 0x00400655, + LedStripe1622 = 0x00400656, + LedStripe1623 = 0x00400657, + LedStripe1624 = 0x00400658, + LedStripe1625 = 0x00400659, + LedStripe1626 = 0x0040065A, + LedStripe1627 = 0x0040065B, + LedStripe1628 = 0x0040065C, + LedStripe1629 = 0x0040065D, + LedStripe1630 = 0x0040065E, + LedStripe1631 = 0x0040065F, + LedStripe1632 = 0x00400660, + LedStripe1633 = 0x00400661, + LedStripe1634 = 0x00400662, + LedStripe1635 = 0x00400663, + LedStripe1636 = 0x00400664, + LedStripe1637 = 0x00400665, + LedStripe1638 = 0x00400666, + LedStripe1639 = 0x00400667, + LedStripe1640 = 0x00400668, + LedStripe1641 = 0x00400669, + LedStripe1642 = 0x0040066A, + LedStripe1643 = 0x0040066B, + LedStripe1644 = 0x0040066C, + LedStripe1645 = 0x0040066D, + LedStripe1646 = 0x0040066E, + LedStripe1647 = 0x0040066F, + LedStripe1648 = 0x00400670, + LedStripe1649 = 0x00400671, + LedStripe1650 = 0x00400672, + LedStripe1651 = 0x00400673, + LedStripe1652 = 0x00400674, + LedStripe1653 = 0x00400675, + LedStripe1654 = 0x00400676, + LedStripe1655 = 0x00400677, + LedStripe1656 = 0x00400678, + LedStripe1657 = 0x00400679, + LedStripe1658 = 0x0040067A, + LedStripe1659 = 0x0040067B, + LedStripe1660 = 0x0040067C, + LedStripe1661 = 0x0040067D, + LedStripe1662 = 0x0040067E, + LedStripe1663 = 0x0040067F, + LedStripe1664 = 0x00400680, + LedStripe1665 = 0x00400681, + LedStripe1666 = 0x00400682, + LedStripe1667 = 0x00400683, + LedStripe1668 = 0x00400684, + LedStripe1669 = 0x00400685, + LedStripe1670 = 0x00400686, + LedStripe1671 = 0x00400687, + LedStripe1672 = 0x00400688, + LedStripe1673 = 0x00400689, + LedStripe1674 = 0x0040068A, + LedStripe1675 = 0x0040068B, + LedStripe1676 = 0x0040068C, + LedStripe1677 = 0x0040068D, + LedStripe1678 = 0x0040068E, + LedStripe1679 = 0x0040068F, + LedStripe1680 = 0x00400690, + LedStripe1681 = 0x00400691, + LedStripe1682 = 0x00400692, + LedStripe1683 = 0x00400693, + LedStripe1684 = 0x00400694, + LedStripe1685 = 0x00400695, + LedStripe1686 = 0x00400696, + LedStripe1687 = 0x00400697, + LedStripe1688 = 0x00400698, + LedStripe1689 = 0x00400699, + LedStripe1690 = 0x0040069A, + LedStripe1691 = 0x0040069B, + LedStripe1692 = 0x0040069C, + LedStripe1693 = 0x0040069D, + LedStripe1694 = 0x0040069E, + LedStripe1695 = 0x0040069F, + LedStripe1696 = 0x004006A0, + LedStripe1697 = 0x004006A1, + LedStripe1698 = 0x004006A2, + LedStripe1699 = 0x004006A3, + LedStripe1700 = 0x004006A4, + LedStripe1701 = 0x004006A5, + LedStripe1702 = 0x004006A6, + LedStripe1703 = 0x004006A7, + LedStripe1704 = 0x004006A8, + LedStripe1705 = 0x004006A9, + LedStripe1706 = 0x004006AA, + LedStripe1707 = 0x004006AB, + LedStripe1708 = 0x004006AC, + LedStripe1709 = 0x004006AD, + LedStripe1710 = 0x004006AE, + LedStripe1711 = 0x004006AF, + LedStripe1712 = 0x004006B0, + LedStripe1713 = 0x004006B1, + LedStripe1714 = 0x004006B2, + LedStripe1715 = 0x004006B3, + LedStripe1716 = 0x004006B4, + LedStripe1717 = 0x004006B5, + LedStripe1718 = 0x004006B6, + LedStripe1719 = 0x004006B7, + LedStripe1720 = 0x004006B8, + LedStripe1721 = 0x004006B9, + LedStripe1722 = 0x004006BA, + LedStripe1723 = 0x004006BB, + LedStripe1724 = 0x004006BC, + LedStripe1725 = 0x004006BD, + LedStripe1726 = 0x004006BE, + LedStripe1727 = 0x004006BF, + LedStripe1728 = 0x004006C0, + LedStripe1729 = 0x004006C1, + LedStripe1730 = 0x004006C2, + LedStripe1731 = 0x004006C3, + LedStripe1732 = 0x004006C4, + LedStripe1733 = 0x004006C5, + LedStripe1734 = 0x004006C6, + LedStripe1735 = 0x004006C7, + LedStripe1736 = 0x004006C8, + LedStripe1737 = 0x004006C9, + LedStripe1738 = 0x004006CA, + LedStripe1739 = 0x004006CB, + LedStripe1740 = 0x004006CC, + LedStripe1741 = 0x004006CD, + LedStripe1742 = 0x004006CE, + LedStripe1743 = 0x004006CF, + LedStripe1744 = 0x004006D0, + LedStripe1745 = 0x004006D1, + LedStripe1746 = 0x004006D2, + LedStripe1747 = 0x004006D3, + LedStripe1748 = 0x004006D4, + LedStripe1749 = 0x004006D5, + LedStripe1750 = 0x004006D6, + LedStripe1751 = 0x004006D7, + LedStripe1752 = 0x004006D8, + LedStripe1753 = 0x004006D9, + LedStripe1754 = 0x004006DA, + LedStripe1755 = 0x004006DB, + LedStripe1756 = 0x004006DC, + LedStripe1757 = 0x004006DD, + LedStripe1758 = 0x004006DE, + LedStripe1759 = 0x004006DF, + LedStripe1760 = 0x004006E0, + LedStripe1761 = 0x004006E1, + LedStripe1762 = 0x004006E2, + LedStripe1763 = 0x004006E3, + LedStripe1764 = 0x004006E4, + LedStripe1765 = 0x004006E5, + LedStripe1766 = 0x004006E6, + LedStripe1767 = 0x004006E7, + LedStripe1768 = 0x004006E8, + LedStripe1769 = 0x004006E9, + LedStripe1770 = 0x004006EA, + LedStripe1771 = 0x004006EB, + LedStripe1772 = 0x004006EC, + LedStripe1773 = 0x004006ED, + LedStripe1774 = 0x004006EE, + LedStripe1775 = 0x004006EF, + LedStripe1776 = 0x004006F0, + LedStripe1777 = 0x004006F1, + LedStripe1778 = 0x004006F2, + LedStripe1779 = 0x004006F3, + LedStripe1780 = 0x004006F4, + LedStripe1781 = 0x004006F5, + LedStripe1782 = 0x004006F6, + LedStripe1783 = 0x004006F7, + LedStripe1784 = 0x004006F8, + LedStripe1785 = 0x004006F9, + LedStripe1786 = 0x004006FA, + LedStripe1787 = 0x004006FB, + LedStripe1788 = 0x004006FC, + LedStripe1789 = 0x004006FD, + LedStripe1790 = 0x004006FE, + LedStripe1791 = 0x004006FF, + LedStripe1792 = 0x00400700, + LedStripe1793 = 0x00400701, + LedStripe1794 = 0x00400702, + LedStripe1795 = 0x00400703, + LedStripe1796 = 0x00400704, + LedStripe1797 = 0x00400705, + LedStripe1798 = 0x00400706, + LedStripe1799 = 0x00400707, + LedStripe1800 = 0x00400708, + LedStripe1801 = 0x00400709, + LedStripe1802 = 0x0040070A, + LedStripe1803 = 0x0040070B, + LedStripe1804 = 0x0040070C, + LedStripe1805 = 0x0040070D, + LedStripe1806 = 0x0040070E, + LedStripe1807 = 0x0040070F, + LedStripe1808 = 0x00400710, + LedStripe1809 = 0x00400711, + LedStripe1810 = 0x00400712, + LedStripe1811 = 0x00400713, + LedStripe1812 = 0x00400714, + LedStripe1813 = 0x00400715, + LedStripe1814 = 0x00400716, + LedStripe1815 = 0x00400717, + LedStripe1816 = 0x00400718, + LedStripe1817 = 0x00400719, + LedStripe1818 = 0x0040071A, + LedStripe1819 = 0x0040071B, + LedStripe1820 = 0x0040071C, + LedStripe1821 = 0x0040071D, + LedStripe1822 = 0x0040071E, + LedStripe1823 = 0x0040071F, + LedStripe1824 = 0x00400720, + LedStripe1825 = 0x00400721, + LedStripe1826 = 0x00400722, + LedStripe1827 = 0x00400723, + LedStripe1828 = 0x00400724, + LedStripe1829 = 0x00400725, + LedStripe1830 = 0x00400726, + LedStripe1831 = 0x00400727, + LedStripe1832 = 0x00400728, + LedStripe1833 = 0x00400729, + LedStripe1834 = 0x0040072A, + LedStripe1835 = 0x0040072B, + LedStripe1836 = 0x0040072C, + LedStripe1837 = 0x0040072D, + LedStripe1838 = 0x0040072E, + LedStripe1839 = 0x0040072F, + LedStripe1840 = 0x00400730, + LedStripe1841 = 0x00400731, + LedStripe1842 = 0x00400732, + LedStripe1843 = 0x00400733, + LedStripe1844 = 0x00400734, + LedStripe1845 = 0x00400735, + LedStripe1846 = 0x00400736, + LedStripe1847 = 0x00400737, + LedStripe1848 = 0x00400738, + LedStripe1849 = 0x00400739, + LedStripe1850 = 0x0040073A, + LedStripe1851 = 0x0040073B, + LedStripe1852 = 0x0040073C, + LedStripe1853 = 0x0040073D, + LedStripe1854 = 0x0040073E, + LedStripe1855 = 0x0040073F, + LedStripe1856 = 0x00400740, + LedStripe1857 = 0x00400741, + LedStripe1858 = 0x00400742, + LedStripe1859 = 0x00400743, + LedStripe1860 = 0x00400744, + LedStripe1861 = 0x00400745, + LedStripe1862 = 0x00400746, + LedStripe1863 = 0x00400747, + LedStripe1864 = 0x00400748, + LedStripe1865 = 0x00400749, + LedStripe1866 = 0x0040074A, + LedStripe1867 = 0x0040074B, + LedStripe1868 = 0x0040074C, + LedStripe1869 = 0x0040074D, + LedStripe1870 = 0x0040074E, + LedStripe1871 = 0x0040074F, + LedStripe1872 = 0x00400750, + LedStripe1873 = 0x00400751, + LedStripe1874 = 0x00400752, + LedStripe1875 = 0x00400753, + LedStripe1876 = 0x00400754, + LedStripe1877 = 0x00400755, + LedStripe1878 = 0x00400756, + LedStripe1879 = 0x00400757, + LedStripe1880 = 0x00400758, + LedStripe1881 = 0x00400759, + LedStripe1882 = 0x0040075A, + LedStripe1883 = 0x0040075B, + LedStripe1884 = 0x0040075C, + LedStripe1885 = 0x0040075D, + LedStripe1886 = 0x0040075E, + LedStripe1887 = 0x0040075F, + LedStripe1888 = 0x00400760, + LedStripe1889 = 0x00400761, + LedStripe1890 = 0x00400762, + LedStripe1891 = 0x00400763, + LedStripe1892 = 0x00400764, + LedStripe1893 = 0x00400765, + LedStripe1894 = 0x00400766, + LedStripe1895 = 0x00400767, + LedStripe1896 = 0x00400768, + LedStripe1897 = 0x00400769, + LedStripe1898 = 0x0040076A, + LedStripe1899 = 0x0040076B, + LedStripe1900 = 0x0040076C, + LedStripe1901 = 0x0040076D, + LedStripe1902 = 0x0040076E, + LedStripe1903 = 0x0040076F, + LedStripe1904 = 0x00400770, + LedStripe1905 = 0x00400771, + LedStripe1906 = 0x00400772, + LedStripe1907 = 0x00400773, + LedStripe1908 = 0x00400774, + LedStripe1909 = 0x00400775, + LedStripe1910 = 0x00400776, + LedStripe1911 = 0x00400777, + LedStripe1912 = 0x00400778, + LedStripe1913 = 0x00400779, + LedStripe1914 = 0x0040077A, + LedStripe1915 = 0x0040077B, + LedStripe1916 = 0x0040077C, + LedStripe1917 = 0x0040077D, + LedStripe1918 = 0x0040077E, + LedStripe1919 = 0x0040077F, + LedStripe1920 = 0x00400780, + LedStripe1921 = 0x00400781, + LedStripe1922 = 0x00400782, + LedStripe1923 = 0x00400783, + LedStripe1924 = 0x00400784, + LedStripe1925 = 0x00400785, + LedStripe1926 = 0x00400786, + LedStripe1927 = 0x00400787, + LedStripe1928 = 0x00400788, + LedStripe1929 = 0x00400789, + LedStripe1930 = 0x0040078A, + LedStripe1931 = 0x0040078B, + LedStripe1932 = 0x0040078C, + LedStripe1933 = 0x0040078D, + LedStripe1934 = 0x0040078E, + LedStripe1935 = 0x0040078F, + LedStripe1936 = 0x00400790, + LedStripe1937 = 0x00400791, + LedStripe1938 = 0x00400792, + LedStripe1939 = 0x00400793, + LedStripe1940 = 0x00400794, + LedStripe1941 = 0x00400795, + LedStripe1942 = 0x00400796, + LedStripe1943 = 0x00400797, + LedStripe1944 = 0x00400798, + LedStripe1945 = 0x00400799, + LedStripe1946 = 0x0040079A, + LedStripe1947 = 0x0040079B, + LedStripe1948 = 0x0040079C, + LedStripe1949 = 0x0040079D, + LedStripe1950 = 0x0040079E, + LedStripe1951 = 0x0040079F, + LedStripe1952 = 0x004007A0, + LedStripe1953 = 0x004007A1, + LedStripe1954 = 0x004007A2, + LedStripe1955 = 0x004007A3, + LedStripe1956 = 0x004007A4, + LedStripe1957 = 0x004007A5, + LedStripe1958 = 0x004007A6, + LedStripe1959 = 0x004007A7, + LedStripe1960 = 0x004007A8, + LedStripe1961 = 0x004007A9, + LedStripe1962 = 0x004007AA, + LedStripe1963 = 0x004007AB, + LedStripe1964 = 0x004007AC, + LedStripe1965 = 0x004007AD, + LedStripe1966 = 0x004007AE, + LedStripe1967 = 0x004007AF, + LedStripe1968 = 0x004007B0, + LedStripe1969 = 0x004007B1, + LedStripe1970 = 0x004007B2, + LedStripe1971 = 0x004007B3, + LedStripe1972 = 0x004007B4, + LedStripe1973 = 0x004007B5, + LedStripe1974 = 0x004007B6, + LedStripe1975 = 0x004007B7, + LedStripe1976 = 0x004007B8, + LedStripe1977 = 0x004007B9, + LedStripe1978 = 0x004007BA, + LedStripe1979 = 0x004007BB, + LedStripe1980 = 0x004007BC, + LedStripe1981 = 0x004007BD, + LedStripe1982 = 0x004007BE, + LedStripe1983 = 0x004007BF, + LedStripe1984 = 0x004007C0, + LedStripe1985 = 0x004007C1, + LedStripe1986 = 0x004007C2, + LedStripe1987 = 0x004007C3, + LedStripe1988 = 0x004007C4, + LedStripe1989 = 0x004007C5, + LedStripe1990 = 0x004007C6, + LedStripe1991 = 0x004007C7, + LedStripe1992 = 0x004007C8, + LedStripe1993 = 0x004007C9, + LedStripe1994 = 0x004007CA, + LedStripe1995 = 0x004007CB, + LedStripe1996 = 0x004007CC, + LedStripe1997 = 0x004007CD, + LedStripe1998 = 0x004007CE, + LedStripe1999 = 0x004007CF, + LedStripe2000 = 0x004007D0, + LedStripe2001 = 0x004007D1, + LedStripe2002 = 0x004007D2, + LedStripe2003 = 0x004007D3, + LedStripe2004 = 0x004007D4, + LedStripe2005 = 0x004007D5, + LedStripe2006 = 0x004007D6, + LedStripe2007 = 0x004007D7, + LedStripe2008 = 0x004007D8, + LedStripe2009 = 0x004007D9, + LedStripe2010 = 0x004007DA, + LedStripe2011 = 0x004007DB, + LedStripe2012 = 0x004007DC, + LedStripe2013 = 0x004007DD, + LedStripe2014 = 0x004007DE, + LedStripe2015 = 0x004007DF, + LedStripe2016 = 0x004007E0, + LedStripe2017 = 0x004007E1, + LedStripe2018 = 0x004007E2, + LedStripe2019 = 0x004007E3, + LedStripe2020 = 0x004007E4, + LedStripe2021 = 0x004007E5, + LedStripe2022 = 0x004007E6, + LedStripe2023 = 0x004007E7, + LedStripe2024 = 0x004007E8, + LedStripe2025 = 0x004007E9, + LedStripe2026 = 0x004007EA, + LedStripe2027 = 0x004007EB, + LedStripe2028 = 0x004007EC, + LedStripe2029 = 0x004007ED, + LedStripe2030 = 0x004007EE, + LedStripe2031 = 0x004007EF, + LedStripe2032 = 0x004007F0, + LedStripe2033 = 0x004007F1, + LedStripe2034 = 0x004007F2, + LedStripe2035 = 0x004007F3, + LedStripe2036 = 0x004007F4, + LedStripe2037 = 0x004007F5, + LedStripe2038 = 0x004007F6, + LedStripe2039 = 0x004007F7, + LedStripe2040 = 0x004007F8, + LedStripe2041 = 0x004007F9, + LedStripe2042 = 0x004007FA, + LedStripe2043 = 0x004007FB, + LedStripe2044 = 0x004007FC, + LedStripe2045 = 0x004007FD, + LedStripe2046 = 0x004007FE, + LedStripe2047 = 0x004007FF, + LedStripe2048 = 0x00400800, - /*### LedStripe ###*/ - LedStripe1 = 0x00400001, - LedStripe2 = 0x00400002, - LedStripe3 = 0x00400003, - LedStripe4 = 0x00400004, - LedStripe5 = 0x00400005, - LedStripe6 = 0x00400006, - LedStripe7 = 0x00400007, - LedStripe8 = 0x00400008, - LedStripe9 = 0x00400009, - LedStripe10 = 0x0040000A, - LedStripe11 = 0x0040000B, - LedStripe12 = 0x0040000C, - LedStripe13 = 0x0040000D, - LedStripe14 = 0x0040000E, - LedStripe15 = 0x0040000F, - LedStripe16 = 0x00400010, - LedStripe17 = 0x00400011, - LedStripe18 = 0x00400012, - LedStripe19 = 0x00400013, - LedStripe20 = 0x00400014, - LedStripe21 = 0x00400015, - LedStripe22 = 0x00400016, - LedStripe23 = 0x00400017, - LedStripe24 = 0x00400018, - LedStripe25 = 0x00400019, - LedStripe26 = 0x0040001A, - LedStripe27 = 0x0040001B, - LedStripe28 = 0x0040001C, - LedStripe29 = 0x0040001D, - LedStripe30 = 0x0040001E, - LedStripe31 = 0x0040001F, - LedStripe32 = 0x00400020, - LedStripe33 = 0x00400021, - LedStripe34 = 0x00400022, - LedStripe35 = 0x00400023, - LedStripe36 = 0x00400024, - LedStripe37 = 0x00400025, - LedStripe38 = 0x00400026, - LedStripe39 = 0x00400027, - LedStripe40 = 0x00400028, - LedStripe41 = 0x00400029, - LedStripe42 = 0x0040002A, - LedStripe43 = 0x0040002B, - LedStripe44 = 0x0040002C, - LedStripe45 = 0x0040002D, - LedStripe46 = 0x0040002E, - LedStripe47 = 0x0040002F, - LedStripe48 = 0x00400030, - LedStripe49 = 0x00400031, - LedStripe50 = 0x00400032, - LedStripe51 = 0x00400033, - LedStripe52 = 0x00400034, - LedStripe53 = 0x00400035, - LedStripe54 = 0x00400036, - LedStripe55 = 0x00400037, - LedStripe56 = 0x00400038, - LedStripe57 = 0x00400039, - LedStripe58 = 0x0040003A, - LedStripe59 = 0x0040003B, - LedStripe60 = 0x0040003C, - LedStripe61 = 0x0040003D, - LedStripe62 = 0x0040003E, - LedStripe63 = 0x0040003F, - LedStripe64 = 0x00400040, - LedStripe65 = 0x00400041, - LedStripe66 = 0x00400042, - LedStripe67 = 0x00400043, - LedStripe68 = 0x00400044, - LedStripe69 = 0x00400045, - LedStripe70 = 0x00400046, - LedStripe71 = 0x00400047, - LedStripe72 = 0x00400048, - LedStripe73 = 0x00400049, - LedStripe74 = 0x0040004A, - LedStripe75 = 0x0040004B, - LedStripe76 = 0x0040004C, - LedStripe77 = 0x0040004D, - LedStripe78 = 0x0040004E, - LedStripe79 = 0x0040004F, - LedStripe80 = 0x00400050, - LedStripe81 = 0x00400051, - LedStripe82 = 0x00400052, - LedStripe83 = 0x00400053, - LedStripe84 = 0x00400054, - LedStripe85 = 0x00400055, - LedStripe86 = 0x00400056, - LedStripe87 = 0x00400057, - LedStripe88 = 0x00400058, - LedStripe89 = 0x00400059, - LedStripe90 = 0x0040005A, - LedStripe91 = 0x0040005B, - LedStripe92 = 0x0040005C, - LedStripe93 = 0x0040005D, - LedStripe94 = 0x0040005E, - LedStripe95 = 0x0040005F, - LedStripe96 = 0x00400060, - LedStripe97 = 0x00400061, - LedStripe98 = 0x00400062, - LedStripe99 = 0x00400063, - LedStripe100 = 0x00400064, - LedStripe101 = 0x00400065, - LedStripe102 = 0x00400066, - LedStripe103 = 0x00400067, - LedStripe104 = 0x00400068, - LedStripe105 = 0x00400069, - LedStripe106 = 0x0040006A, - LedStripe107 = 0x0040006B, - LedStripe108 = 0x0040006C, - LedStripe109 = 0x0040006D, - LedStripe110 = 0x0040006E, - LedStripe111 = 0x0040006F, - LedStripe112 = 0x00400070, - LedStripe113 = 0x00400071, - LedStripe114 = 0x00400072, - LedStripe115 = 0x00400073, - LedStripe116 = 0x00400074, - LedStripe117 = 0x00400075, - LedStripe118 = 0x00400076, - LedStripe119 = 0x00400077, - LedStripe120 = 0x00400078, - LedStripe121 = 0x00400079, - LedStripe122 = 0x0040007A, - LedStripe123 = 0x0040007B, - LedStripe124 = 0x0040007C, - LedStripe125 = 0x0040007D, - LedStripe126 = 0x0040007E, - LedStripe127 = 0x0040007F, - LedStripe128 = 0x00400080, + /*### LedMatrix ###*/ + LedMatrix1 = 0x00500001, + LedMatrix2 = 0x00500002, + LedMatrix3 = 0x00500003, + LedMatrix4 = 0x00500004, + LedMatrix5 = 0x00500005, + LedMatrix6 = 0x00500006, + LedMatrix7 = 0x00500007, + LedMatrix8 = 0x00500008, + LedMatrix9 = 0x00500009, + LedMatrix10 = 0x0050000A, + LedMatrix11 = 0x0050000B, + LedMatrix12 = 0x0050000C, + LedMatrix13 = 0x0050000D, + LedMatrix14 = 0x0050000E, + LedMatrix15 = 0x0050000F, + LedMatrix16 = 0x00500010, + LedMatrix17 = 0x00500011, + LedMatrix18 = 0x00500012, + LedMatrix19 = 0x00500013, + LedMatrix20 = 0x00500014, + LedMatrix21 = 0x00500015, + LedMatrix22 = 0x00500016, + LedMatrix23 = 0x00500017, + LedMatrix24 = 0x00500018, + LedMatrix25 = 0x00500019, + LedMatrix26 = 0x0050001A, + LedMatrix27 = 0x0050001B, + LedMatrix28 = 0x0050001C, + LedMatrix29 = 0x0050001D, + LedMatrix30 = 0x0050001E, + LedMatrix31 = 0x0050001F, + LedMatrix32 = 0x00500020, + LedMatrix33 = 0x00500021, + LedMatrix34 = 0x00500022, + LedMatrix35 = 0x00500023, + LedMatrix36 = 0x00500024, + LedMatrix37 = 0x00500025, + LedMatrix38 = 0x00500026, + LedMatrix39 = 0x00500027, + LedMatrix40 = 0x00500028, + LedMatrix41 = 0x00500029, + LedMatrix42 = 0x0050002A, + LedMatrix43 = 0x0050002B, + LedMatrix44 = 0x0050002C, + LedMatrix45 = 0x0050002D, + LedMatrix46 = 0x0050002E, + LedMatrix47 = 0x0050002F, + LedMatrix48 = 0x00500030, + LedMatrix49 = 0x00500031, + LedMatrix50 = 0x00500032, + LedMatrix51 = 0x00500033, + LedMatrix52 = 0x00500034, + LedMatrix53 = 0x00500035, + LedMatrix54 = 0x00500036, + LedMatrix55 = 0x00500037, + LedMatrix56 = 0x00500038, + LedMatrix57 = 0x00500039, + LedMatrix58 = 0x0050003A, + LedMatrix59 = 0x0050003B, + LedMatrix60 = 0x0050003C, + LedMatrix61 = 0x0050003D, + LedMatrix62 = 0x0050003E, + LedMatrix63 = 0x0050003F, + LedMatrix64 = 0x00500040, + LedMatrix65 = 0x00500041, + LedMatrix66 = 0x00500042, + LedMatrix67 = 0x00500043, + LedMatrix68 = 0x00500044, + LedMatrix69 = 0x00500045, + LedMatrix70 = 0x00500046, + LedMatrix71 = 0x00500047, + LedMatrix72 = 0x00500048, + LedMatrix73 = 0x00500049, + LedMatrix74 = 0x0050004A, + LedMatrix75 = 0x0050004B, + LedMatrix76 = 0x0050004C, + LedMatrix77 = 0x0050004D, + LedMatrix78 = 0x0050004E, + LedMatrix79 = 0x0050004F, + LedMatrix80 = 0x00500050, + LedMatrix81 = 0x00500051, + LedMatrix82 = 0x00500052, + LedMatrix83 = 0x00500053, + LedMatrix84 = 0x00500054, + LedMatrix85 = 0x00500055, + LedMatrix86 = 0x00500056, + LedMatrix87 = 0x00500057, + LedMatrix88 = 0x00500058, + LedMatrix89 = 0x00500059, + LedMatrix90 = 0x0050005A, + LedMatrix91 = 0x0050005B, + LedMatrix92 = 0x0050005C, + LedMatrix93 = 0x0050005D, + LedMatrix94 = 0x0050005E, + LedMatrix95 = 0x0050005F, + LedMatrix96 = 0x00500060, + LedMatrix97 = 0x00500061, + LedMatrix98 = 0x00500062, + LedMatrix99 = 0x00500063, + LedMatrix100 = 0x00500064, + LedMatrix101 = 0x00500065, + LedMatrix102 = 0x00500066, + LedMatrix103 = 0x00500067, + LedMatrix104 = 0x00500068, + LedMatrix105 = 0x00500069, + LedMatrix106 = 0x0050006A, + LedMatrix107 = 0x0050006B, + LedMatrix108 = 0x0050006C, + LedMatrix109 = 0x0050006D, + LedMatrix110 = 0x0050006E, + LedMatrix111 = 0x0050006F, + LedMatrix112 = 0x00500070, + LedMatrix113 = 0x00500071, + LedMatrix114 = 0x00500072, + LedMatrix115 = 0x00500073, + LedMatrix116 = 0x00500074, + LedMatrix117 = 0x00500075, + LedMatrix118 = 0x00500076, + LedMatrix119 = 0x00500077, + LedMatrix120 = 0x00500078, + LedMatrix121 = 0x00500079, + LedMatrix122 = 0x0050007A, + LedMatrix123 = 0x0050007B, + LedMatrix124 = 0x0050007C, + LedMatrix125 = 0x0050007D, + LedMatrix126 = 0x0050007E, + LedMatrix127 = 0x0050007F, + LedMatrix128 = 0x00500080, + LedMatrix129 = 0x00500081, + LedMatrix130 = 0x00500082, + LedMatrix131 = 0x00500083, + LedMatrix132 = 0x00500084, + LedMatrix133 = 0x00500085, + LedMatrix134 = 0x00500086, + LedMatrix135 = 0x00500087, + LedMatrix136 = 0x00500088, + LedMatrix137 = 0x00500089, + LedMatrix138 = 0x0050008A, + LedMatrix139 = 0x0050008B, + LedMatrix140 = 0x0050008C, + LedMatrix141 = 0x0050008D, + LedMatrix142 = 0x0050008E, + LedMatrix143 = 0x0050008F, + LedMatrix144 = 0x00500090, + LedMatrix145 = 0x00500091, + LedMatrix146 = 0x00500092, + LedMatrix147 = 0x00500093, + LedMatrix148 = 0x00500094, + LedMatrix149 = 0x00500095, + LedMatrix150 = 0x00500096, + LedMatrix151 = 0x00500097, + LedMatrix152 = 0x00500098, + LedMatrix153 = 0x00500099, + LedMatrix154 = 0x0050009A, + LedMatrix155 = 0x0050009B, + LedMatrix156 = 0x0050009C, + LedMatrix157 = 0x0050009D, + LedMatrix158 = 0x0050009E, + LedMatrix159 = 0x0050009F, + LedMatrix160 = 0x005000A0, + LedMatrix161 = 0x005000A1, + LedMatrix162 = 0x005000A2, + LedMatrix163 = 0x005000A3, + LedMatrix164 = 0x005000A4, + LedMatrix165 = 0x005000A5, + LedMatrix166 = 0x005000A6, + LedMatrix167 = 0x005000A7, + LedMatrix168 = 0x005000A8, + LedMatrix169 = 0x005000A9, + LedMatrix170 = 0x005000AA, + LedMatrix171 = 0x005000AB, + LedMatrix172 = 0x005000AC, + LedMatrix173 = 0x005000AD, + LedMatrix174 = 0x005000AE, + LedMatrix175 = 0x005000AF, + LedMatrix176 = 0x005000B0, + LedMatrix177 = 0x005000B1, + LedMatrix178 = 0x005000B2, + LedMatrix179 = 0x005000B3, + LedMatrix180 = 0x005000B4, + LedMatrix181 = 0x005000B5, + LedMatrix182 = 0x005000B6, + LedMatrix183 = 0x005000B7, + LedMatrix184 = 0x005000B8, + LedMatrix185 = 0x005000B9, + LedMatrix186 = 0x005000BA, + LedMatrix187 = 0x005000BB, + LedMatrix188 = 0x005000BC, + LedMatrix189 = 0x005000BD, + LedMatrix190 = 0x005000BE, + LedMatrix191 = 0x005000BF, + LedMatrix192 = 0x005000C0, + LedMatrix193 = 0x005000C1, + LedMatrix194 = 0x005000C2, + LedMatrix195 = 0x005000C3, + LedMatrix196 = 0x005000C4, + LedMatrix197 = 0x005000C5, + LedMatrix198 = 0x005000C6, + LedMatrix199 = 0x005000C7, + LedMatrix200 = 0x005000C8, + LedMatrix201 = 0x005000C9, + LedMatrix202 = 0x005000CA, + LedMatrix203 = 0x005000CB, + LedMatrix204 = 0x005000CC, + LedMatrix205 = 0x005000CD, + LedMatrix206 = 0x005000CE, + LedMatrix207 = 0x005000CF, + LedMatrix208 = 0x005000D0, + LedMatrix209 = 0x005000D1, + LedMatrix210 = 0x005000D2, + LedMatrix211 = 0x005000D3, + LedMatrix212 = 0x005000D4, + LedMatrix213 = 0x005000D5, + LedMatrix214 = 0x005000D6, + LedMatrix215 = 0x005000D7, + LedMatrix216 = 0x005000D8, + LedMatrix217 = 0x005000D9, + LedMatrix218 = 0x005000DA, + LedMatrix219 = 0x005000DB, + LedMatrix220 = 0x005000DC, + LedMatrix221 = 0x005000DD, + LedMatrix222 = 0x005000DE, + LedMatrix223 = 0x005000DF, + LedMatrix224 = 0x005000E0, + LedMatrix225 = 0x005000E1, + LedMatrix226 = 0x005000E2, + LedMatrix227 = 0x005000E3, + LedMatrix228 = 0x005000E4, + LedMatrix229 = 0x005000E5, + LedMatrix230 = 0x005000E6, + LedMatrix231 = 0x005000E7, + LedMatrix232 = 0x005000E8, + LedMatrix233 = 0x005000E9, + LedMatrix234 = 0x005000EA, + LedMatrix235 = 0x005000EB, + LedMatrix236 = 0x005000EC, + LedMatrix237 = 0x005000ED, + LedMatrix238 = 0x005000EE, + LedMatrix239 = 0x005000EF, + LedMatrix240 = 0x005000F0, + LedMatrix241 = 0x005000F1, + LedMatrix242 = 0x005000F2, + LedMatrix243 = 0x005000F3, + LedMatrix244 = 0x005000F4, + LedMatrix245 = 0x005000F5, + LedMatrix246 = 0x005000F6, + LedMatrix247 = 0x005000F7, + LedMatrix248 = 0x005000F8, + LedMatrix249 = 0x005000F9, + LedMatrix250 = 0x005000FA, + LedMatrix251 = 0x005000FB, + LedMatrix252 = 0x005000FC, + LedMatrix253 = 0x005000FD, + LedMatrix254 = 0x005000FE, + LedMatrix255 = 0x005000FF, + LedMatrix256 = 0x00500100, + LedMatrix257 = 0x00500101, + LedMatrix258 = 0x00500102, + LedMatrix259 = 0x00500103, + LedMatrix260 = 0x00500104, + LedMatrix261 = 0x00500105, + LedMatrix262 = 0x00500106, + LedMatrix263 = 0x00500107, + LedMatrix264 = 0x00500108, + LedMatrix265 = 0x00500109, + LedMatrix266 = 0x0050010A, + LedMatrix267 = 0x0050010B, + LedMatrix268 = 0x0050010C, + LedMatrix269 = 0x0050010D, + LedMatrix270 = 0x0050010E, + LedMatrix271 = 0x0050010F, + LedMatrix272 = 0x00500110, + LedMatrix273 = 0x00500111, + LedMatrix274 = 0x00500112, + LedMatrix275 = 0x00500113, + LedMatrix276 = 0x00500114, + LedMatrix277 = 0x00500115, + LedMatrix278 = 0x00500116, + LedMatrix279 = 0x00500117, + LedMatrix280 = 0x00500118, + LedMatrix281 = 0x00500119, + LedMatrix282 = 0x0050011A, + LedMatrix283 = 0x0050011B, + LedMatrix284 = 0x0050011C, + LedMatrix285 = 0x0050011D, + LedMatrix286 = 0x0050011E, + LedMatrix287 = 0x0050011F, + LedMatrix288 = 0x00500120, + LedMatrix289 = 0x00500121, + LedMatrix290 = 0x00500122, + LedMatrix291 = 0x00500123, + LedMatrix292 = 0x00500124, + LedMatrix293 = 0x00500125, + LedMatrix294 = 0x00500126, + LedMatrix295 = 0x00500127, + LedMatrix296 = 0x00500128, + LedMatrix297 = 0x00500129, + LedMatrix298 = 0x0050012A, + LedMatrix299 = 0x0050012B, + LedMatrix300 = 0x0050012C, + LedMatrix301 = 0x0050012D, + LedMatrix302 = 0x0050012E, + LedMatrix303 = 0x0050012F, + LedMatrix304 = 0x00500130, + LedMatrix305 = 0x00500131, + LedMatrix306 = 0x00500132, + LedMatrix307 = 0x00500133, + LedMatrix308 = 0x00500134, + LedMatrix309 = 0x00500135, + LedMatrix310 = 0x00500136, + LedMatrix311 = 0x00500137, + LedMatrix312 = 0x00500138, + LedMatrix313 = 0x00500139, + LedMatrix314 = 0x0050013A, + LedMatrix315 = 0x0050013B, + LedMatrix316 = 0x0050013C, + LedMatrix317 = 0x0050013D, + LedMatrix318 = 0x0050013E, + LedMatrix319 = 0x0050013F, + LedMatrix320 = 0x00500140, + LedMatrix321 = 0x00500141, + LedMatrix322 = 0x00500142, + LedMatrix323 = 0x00500143, + LedMatrix324 = 0x00500144, + LedMatrix325 = 0x00500145, + LedMatrix326 = 0x00500146, + LedMatrix327 = 0x00500147, + LedMatrix328 = 0x00500148, + LedMatrix329 = 0x00500149, + LedMatrix330 = 0x0050014A, + LedMatrix331 = 0x0050014B, + LedMatrix332 = 0x0050014C, + LedMatrix333 = 0x0050014D, + LedMatrix334 = 0x0050014E, + LedMatrix335 = 0x0050014F, + LedMatrix336 = 0x00500150, + LedMatrix337 = 0x00500151, + LedMatrix338 = 0x00500152, + LedMatrix339 = 0x00500153, + LedMatrix340 = 0x00500154, + LedMatrix341 = 0x00500155, + LedMatrix342 = 0x00500156, + LedMatrix343 = 0x00500157, + LedMatrix344 = 0x00500158, + LedMatrix345 = 0x00500159, + LedMatrix346 = 0x0050015A, + LedMatrix347 = 0x0050015B, + LedMatrix348 = 0x0050015C, + LedMatrix349 = 0x0050015D, + LedMatrix350 = 0x0050015E, + LedMatrix351 = 0x0050015F, + LedMatrix352 = 0x00500160, + LedMatrix353 = 0x00500161, + LedMatrix354 = 0x00500162, + LedMatrix355 = 0x00500163, + LedMatrix356 = 0x00500164, + LedMatrix357 = 0x00500165, + LedMatrix358 = 0x00500166, + LedMatrix359 = 0x00500167, + LedMatrix360 = 0x00500168, + LedMatrix361 = 0x00500169, + LedMatrix362 = 0x0050016A, + LedMatrix363 = 0x0050016B, + LedMatrix364 = 0x0050016C, + LedMatrix365 = 0x0050016D, + LedMatrix366 = 0x0050016E, + LedMatrix367 = 0x0050016F, + LedMatrix368 = 0x00500170, + LedMatrix369 = 0x00500171, + LedMatrix370 = 0x00500172, + LedMatrix371 = 0x00500173, + LedMatrix372 = 0x00500174, + LedMatrix373 = 0x00500175, + LedMatrix374 = 0x00500176, + LedMatrix375 = 0x00500177, + LedMatrix376 = 0x00500178, + LedMatrix377 = 0x00500179, + LedMatrix378 = 0x0050017A, + LedMatrix379 = 0x0050017B, + LedMatrix380 = 0x0050017C, + LedMatrix381 = 0x0050017D, + LedMatrix382 = 0x0050017E, + LedMatrix383 = 0x0050017F, + LedMatrix384 = 0x00500180, + LedMatrix385 = 0x00500181, + LedMatrix386 = 0x00500182, + LedMatrix387 = 0x00500183, + LedMatrix388 = 0x00500184, + LedMatrix389 = 0x00500185, + LedMatrix390 = 0x00500186, + LedMatrix391 = 0x00500187, + LedMatrix392 = 0x00500188, + LedMatrix393 = 0x00500189, + LedMatrix394 = 0x0050018A, + LedMatrix395 = 0x0050018B, + LedMatrix396 = 0x0050018C, + LedMatrix397 = 0x0050018D, + LedMatrix398 = 0x0050018E, + LedMatrix399 = 0x0050018F, + LedMatrix400 = 0x00500190, + LedMatrix401 = 0x00500191, + LedMatrix402 = 0x00500192, + LedMatrix403 = 0x00500193, + LedMatrix404 = 0x00500194, + LedMatrix405 = 0x00500195, + LedMatrix406 = 0x00500196, + LedMatrix407 = 0x00500197, + LedMatrix408 = 0x00500198, + LedMatrix409 = 0x00500199, + LedMatrix410 = 0x0050019A, + LedMatrix411 = 0x0050019B, + LedMatrix412 = 0x0050019C, + LedMatrix413 = 0x0050019D, + LedMatrix414 = 0x0050019E, + LedMatrix415 = 0x0050019F, + LedMatrix416 = 0x005001A0, + LedMatrix417 = 0x005001A1, + LedMatrix418 = 0x005001A2, + LedMatrix419 = 0x005001A3, + LedMatrix420 = 0x005001A4, + LedMatrix421 = 0x005001A5, + LedMatrix422 = 0x005001A6, + LedMatrix423 = 0x005001A7, + LedMatrix424 = 0x005001A8, + LedMatrix425 = 0x005001A9, + LedMatrix426 = 0x005001AA, + LedMatrix427 = 0x005001AB, + LedMatrix428 = 0x005001AC, + LedMatrix429 = 0x005001AD, + LedMatrix430 = 0x005001AE, + LedMatrix431 = 0x005001AF, + LedMatrix432 = 0x005001B0, + LedMatrix433 = 0x005001B1, + LedMatrix434 = 0x005001B2, + LedMatrix435 = 0x005001B3, + LedMatrix436 = 0x005001B4, + LedMatrix437 = 0x005001B5, + LedMatrix438 = 0x005001B6, + LedMatrix439 = 0x005001B7, + LedMatrix440 = 0x005001B8, + LedMatrix441 = 0x005001B9, + LedMatrix442 = 0x005001BA, + LedMatrix443 = 0x005001BB, + LedMatrix444 = 0x005001BC, + LedMatrix445 = 0x005001BD, + LedMatrix446 = 0x005001BE, + LedMatrix447 = 0x005001BF, + LedMatrix448 = 0x005001C0, + LedMatrix449 = 0x005001C1, + LedMatrix450 = 0x005001C2, + LedMatrix451 = 0x005001C3, + LedMatrix452 = 0x005001C4, + LedMatrix453 = 0x005001C5, + LedMatrix454 = 0x005001C6, + LedMatrix455 = 0x005001C7, + LedMatrix456 = 0x005001C8, + LedMatrix457 = 0x005001C9, + LedMatrix458 = 0x005001CA, + LedMatrix459 = 0x005001CB, + LedMatrix460 = 0x005001CC, + LedMatrix461 = 0x005001CD, + LedMatrix462 = 0x005001CE, + LedMatrix463 = 0x005001CF, + LedMatrix464 = 0x005001D0, + LedMatrix465 = 0x005001D1, + LedMatrix466 = 0x005001D2, + LedMatrix467 = 0x005001D3, + LedMatrix468 = 0x005001D4, + LedMatrix469 = 0x005001D5, + LedMatrix470 = 0x005001D6, + LedMatrix471 = 0x005001D7, + LedMatrix472 = 0x005001D8, + LedMatrix473 = 0x005001D9, + LedMatrix474 = 0x005001DA, + LedMatrix475 = 0x005001DB, + LedMatrix476 = 0x005001DC, + LedMatrix477 = 0x005001DD, + LedMatrix478 = 0x005001DE, + LedMatrix479 = 0x005001DF, + LedMatrix480 = 0x005001E0, + LedMatrix481 = 0x005001E1, + LedMatrix482 = 0x005001E2, + LedMatrix483 = 0x005001E3, + LedMatrix484 = 0x005001E4, + LedMatrix485 = 0x005001E5, + LedMatrix486 = 0x005001E6, + LedMatrix487 = 0x005001E7, + LedMatrix488 = 0x005001E8, + LedMatrix489 = 0x005001E9, + LedMatrix490 = 0x005001EA, + LedMatrix491 = 0x005001EB, + LedMatrix492 = 0x005001EC, + LedMatrix493 = 0x005001ED, + LedMatrix494 = 0x005001EE, + LedMatrix495 = 0x005001EF, + LedMatrix496 = 0x005001F0, + LedMatrix497 = 0x005001F1, + LedMatrix498 = 0x005001F2, + LedMatrix499 = 0x005001F3, + LedMatrix500 = 0x005001F4, + LedMatrix501 = 0x005001F5, + LedMatrix502 = 0x005001F6, + LedMatrix503 = 0x005001F7, + LedMatrix504 = 0x005001F8, + LedMatrix505 = 0x005001F9, + LedMatrix506 = 0x005001FA, + LedMatrix507 = 0x005001FB, + LedMatrix508 = 0x005001FC, + LedMatrix509 = 0x005001FD, + LedMatrix510 = 0x005001FE, + LedMatrix511 = 0x005001FF, + LedMatrix512 = 0x00500200, + LedMatrix513 = 0x00500201, + LedMatrix514 = 0x00500202, + LedMatrix515 = 0x00500203, + LedMatrix516 = 0x00500204, + LedMatrix517 = 0x00500205, + LedMatrix518 = 0x00500206, + LedMatrix519 = 0x00500207, + LedMatrix520 = 0x00500208, + LedMatrix521 = 0x00500209, + LedMatrix522 = 0x0050020A, + LedMatrix523 = 0x0050020B, + LedMatrix524 = 0x0050020C, + LedMatrix525 = 0x0050020D, + LedMatrix526 = 0x0050020E, + LedMatrix527 = 0x0050020F, + LedMatrix528 = 0x00500210, + LedMatrix529 = 0x00500211, + LedMatrix530 = 0x00500212, + LedMatrix531 = 0x00500213, + LedMatrix532 = 0x00500214, + LedMatrix533 = 0x00500215, + LedMatrix534 = 0x00500216, + LedMatrix535 = 0x00500217, + LedMatrix536 = 0x00500218, + LedMatrix537 = 0x00500219, + LedMatrix538 = 0x0050021A, + LedMatrix539 = 0x0050021B, + LedMatrix540 = 0x0050021C, + LedMatrix541 = 0x0050021D, + LedMatrix542 = 0x0050021E, + LedMatrix543 = 0x0050021F, + LedMatrix544 = 0x00500220, + LedMatrix545 = 0x00500221, + LedMatrix546 = 0x00500222, + LedMatrix547 = 0x00500223, + LedMatrix548 = 0x00500224, + LedMatrix549 = 0x00500225, + LedMatrix550 = 0x00500226, + LedMatrix551 = 0x00500227, + LedMatrix552 = 0x00500228, + LedMatrix553 = 0x00500229, + LedMatrix554 = 0x0050022A, + LedMatrix555 = 0x0050022B, + LedMatrix556 = 0x0050022C, + LedMatrix557 = 0x0050022D, + LedMatrix558 = 0x0050022E, + LedMatrix559 = 0x0050022F, + LedMatrix560 = 0x00500230, + LedMatrix561 = 0x00500231, + LedMatrix562 = 0x00500232, + LedMatrix563 = 0x00500233, + LedMatrix564 = 0x00500234, + LedMatrix565 = 0x00500235, + LedMatrix566 = 0x00500236, + LedMatrix567 = 0x00500237, + LedMatrix568 = 0x00500238, + LedMatrix569 = 0x00500239, + LedMatrix570 = 0x0050023A, + LedMatrix571 = 0x0050023B, + LedMatrix572 = 0x0050023C, + LedMatrix573 = 0x0050023D, + LedMatrix574 = 0x0050023E, + LedMatrix575 = 0x0050023F, + LedMatrix576 = 0x00500240, + LedMatrix577 = 0x00500241, + LedMatrix578 = 0x00500242, + LedMatrix579 = 0x00500243, + LedMatrix580 = 0x00500244, + LedMatrix581 = 0x00500245, + LedMatrix582 = 0x00500246, + LedMatrix583 = 0x00500247, + LedMatrix584 = 0x00500248, + LedMatrix585 = 0x00500249, + LedMatrix586 = 0x0050024A, + LedMatrix587 = 0x0050024B, + LedMatrix588 = 0x0050024C, + LedMatrix589 = 0x0050024D, + LedMatrix590 = 0x0050024E, + LedMatrix591 = 0x0050024F, + LedMatrix592 = 0x00500250, + LedMatrix593 = 0x00500251, + LedMatrix594 = 0x00500252, + LedMatrix595 = 0x00500253, + LedMatrix596 = 0x00500254, + LedMatrix597 = 0x00500255, + LedMatrix598 = 0x00500256, + LedMatrix599 = 0x00500257, + LedMatrix600 = 0x00500258, + LedMatrix601 = 0x00500259, + LedMatrix602 = 0x0050025A, + LedMatrix603 = 0x0050025B, + LedMatrix604 = 0x0050025C, + LedMatrix605 = 0x0050025D, + LedMatrix606 = 0x0050025E, + LedMatrix607 = 0x0050025F, + LedMatrix608 = 0x00500260, + LedMatrix609 = 0x00500261, + LedMatrix610 = 0x00500262, + LedMatrix611 = 0x00500263, + LedMatrix612 = 0x00500264, + LedMatrix613 = 0x00500265, + LedMatrix614 = 0x00500266, + LedMatrix615 = 0x00500267, + LedMatrix616 = 0x00500268, + LedMatrix617 = 0x00500269, + LedMatrix618 = 0x0050026A, + LedMatrix619 = 0x0050026B, + LedMatrix620 = 0x0050026C, + LedMatrix621 = 0x0050026D, + LedMatrix622 = 0x0050026E, + LedMatrix623 = 0x0050026F, + LedMatrix624 = 0x00500270, + LedMatrix625 = 0x00500271, + LedMatrix626 = 0x00500272, + LedMatrix627 = 0x00500273, + LedMatrix628 = 0x00500274, + LedMatrix629 = 0x00500275, + LedMatrix630 = 0x00500276, + LedMatrix631 = 0x00500277, + LedMatrix632 = 0x00500278, + LedMatrix633 = 0x00500279, + LedMatrix634 = 0x0050027A, + LedMatrix635 = 0x0050027B, + LedMatrix636 = 0x0050027C, + LedMatrix637 = 0x0050027D, + LedMatrix638 = 0x0050027E, + LedMatrix639 = 0x0050027F, + LedMatrix640 = 0x00500280, + LedMatrix641 = 0x00500281, + LedMatrix642 = 0x00500282, + LedMatrix643 = 0x00500283, + LedMatrix644 = 0x00500284, + LedMatrix645 = 0x00500285, + LedMatrix646 = 0x00500286, + LedMatrix647 = 0x00500287, + LedMatrix648 = 0x00500288, + LedMatrix649 = 0x00500289, + LedMatrix650 = 0x0050028A, + LedMatrix651 = 0x0050028B, + LedMatrix652 = 0x0050028C, + LedMatrix653 = 0x0050028D, + LedMatrix654 = 0x0050028E, + LedMatrix655 = 0x0050028F, + LedMatrix656 = 0x00500290, + LedMatrix657 = 0x00500291, + LedMatrix658 = 0x00500292, + LedMatrix659 = 0x00500293, + LedMatrix660 = 0x00500294, + LedMatrix661 = 0x00500295, + LedMatrix662 = 0x00500296, + LedMatrix663 = 0x00500297, + LedMatrix664 = 0x00500298, + LedMatrix665 = 0x00500299, + LedMatrix666 = 0x0050029A, + LedMatrix667 = 0x0050029B, + LedMatrix668 = 0x0050029C, + LedMatrix669 = 0x0050029D, + LedMatrix670 = 0x0050029E, + LedMatrix671 = 0x0050029F, + LedMatrix672 = 0x005002A0, + LedMatrix673 = 0x005002A1, + LedMatrix674 = 0x005002A2, + LedMatrix675 = 0x005002A3, + LedMatrix676 = 0x005002A4, + LedMatrix677 = 0x005002A5, + LedMatrix678 = 0x005002A6, + LedMatrix679 = 0x005002A7, + LedMatrix680 = 0x005002A8, + LedMatrix681 = 0x005002A9, + LedMatrix682 = 0x005002AA, + LedMatrix683 = 0x005002AB, + LedMatrix684 = 0x005002AC, + LedMatrix685 = 0x005002AD, + LedMatrix686 = 0x005002AE, + LedMatrix687 = 0x005002AF, + LedMatrix688 = 0x005002B0, + LedMatrix689 = 0x005002B1, + LedMatrix690 = 0x005002B2, + LedMatrix691 = 0x005002B3, + LedMatrix692 = 0x005002B4, + LedMatrix693 = 0x005002B5, + LedMatrix694 = 0x005002B6, + LedMatrix695 = 0x005002B7, + LedMatrix696 = 0x005002B8, + LedMatrix697 = 0x005002B9, + LedMatrix698 = 0x005002BA, + LedMatrix699 = 0x005002BB, + LedMatrix700 = 0x005002BC, + LedMatrix701 = 0x005002BD, + LedMatrix702 = 0x005002BE, + LedMatrix703 = 0x005002BF, + LedMatrix704 = 0x005002C0, + LedMatrix705 = 0x005002C1, + LedMatrix706 = 0x005002C2, + LedMatrix707 = 0x005002C3, + LedMatrix708 = 0x005002C4, + LedMatrix709 = 0x005002C5, + LedMatrix710 = 0x005002C6, + LedMatrix711 = 0x005002C7, + LedMatrix712 = 0x005002C8, + LedMatrix713 = 0x005002C9, + LedMatrix714 = 0x005002CA, + LedMatrix715 = 0x005002CB, + LedMatrix716 = 0x005002CC, + LedMatrix717 = 0x005002CD, + LedMatrix718 = 0x005002CE, + LedMatrix719 = 0x005002CF, + LedMatrix720 = 0x005002D0, + LedMatrix721 = 0x005002D1, + LedMatrix722 = 0x005002D2, + LedMatrix723 = 0x005002D3, + LedMatrix724 = 0x005002D4, + LedMatrix725 = 0x005002D5, + LedMatrix726 = 0x005002D6, + LedMatrix727 = 0x005002D7, + LedMatrix728 = 0x005002D8, + LedMatrix729 = 0x005002D9, + LedMatrix730 = 0x005002DA, + LedMatrix731 = 0x005002DB, + LedMatrix732 = 0x005002DC, + LedMatrix733 = 0x005002DD, + LedMatrix734 = 0x005002DE, + LedMatrix735 = 0x005002DF, + LedMatrix736 = 0x005002E0, + LedMatrix737 = 0x005002E1, + LedMatrix738 = 0x005002E2, + LedMatrix739 = 0x005002E3, + LedMatrix740 = 0x005002E4, + LedMatrix741 = 0x005002E5, + LedMatrix742 = 0x005002E6, + LedMatrix743 = 0x005002E7, + LedMatrix744 = 0x005002E8, + LedMatrix745 = 0x005002E9, + LedMatrix746 = 0x005002EA, + LedMatrix747 = 0x005002EB, + LedMatrix748 = 0x005002EC, + LedMatrix749 = 0x005002ED, + LedMatrix750 = 0x005002EE, + LedMatrix751 = 0x005002EF, + LedMatrix752 = 0x005002F0, + LedMatrix753 = 0x005002F1, + LedMatrix754 = 0x005002F2, + LedMatrix755 = 0x005002F3, + LedMatrix756 = 0x005002F4, + LedMatrix757 = 0x005002F5, + LedMatrix758 = 0x005002F6, + LedMatrix759 = 0x005002F7, + LedMatrix760 = 0x005002F8, + LedMatrix761 = 0x005002F9, + LedMatrix762 = 0x005002FA, + LedMatrix763 = 0x005002FB, + LedMatrix764 = 0x005002FC, + LedMatrix765 = 0x005002FD, + LedMatrix766 = 0x005002FE, + LedMatrix767 = 0x005002FF, + LedMatrix768 = 0x00500300, + LedMatrix769 = 0x00500301, + LedMatrix770 = 0x00500302, + LedMatrix771 = 0x00500303, + LedMatrix772 = 0x00500304, + LedMatrix773 = 0x00500305, + LedMatrix774 = 0x00500306, + LedMatrix775 = 0x00500307, + LedMatrix776 = 0x00500308, + LedMatrix777 = 0x00500309, + LedMatrix778 = 0x0050030A, + LedMatrix779 = 0x0050030B, + LedMatrix780 = 0x0050030C, + LedMatrix781 = 0x0050030D, + LedMatrix782 = 0x0050030E, + LedMatrix783 = 0x0050030F, + LedMatrix784 = 0x00500310, + LedMatrix785 = 0x00500311, + LedMatrix786 = 0x00500312, + LedMatrix787 = 0x00500313, + LedMatrix788 = 0x00500314, + LedMatrix789 = 0x00500315, + LedMatrix790 = 0x00500316, + LedMatrix791 = 0x00500317, + LedMatrix792 = 0x00500318, + LedMatrix793 = 0x00500319, + LedMatrix794 = 0x0050031A, + LedMatrix795 = 0x0050031B, + LedMatrix796 = 0x0050031C, + LedMatrix797 = 0x0050031D, + LedMatrix798 = 0x0050031E, + LedMatrix799 = 0x0050031F, + LedMatrix800 = 0x00500320, + LedMatrix801 = 0x00500321, + LedMatrix802 = 0x00500322, + LedMatrix803 = 0x00500323, + LedMatrix804 = 0x00500324, + LedMatrix805 = 0x00500325, + LedMatrix806 = 0x00500326, + LedMatrix807 = 0x00500327, + LedMatrix808 = 0x00500328, + LedMatrix809 = 0x00500329, + LedMatrix810 = 0x0050032A, + LedMatrix811 = 0x0050032B, + LedMatrix812 = 0x0050032C, + LedMatrix813 = 0x0050032D, + LedMatrix814 = 0x0050032E, + LedMatrix815 = 0x0050032F, + LedMatrix816 = 0x00500330, + LedMatrix817 = 0x00500331, + LedMatrix818 = 0x00500332, + LedMatrix819 = 0x00500333, + LedMatrix820 = 0x00500334, + LedMatrix821 = 0x00500335, + LedMatrix822 = 0x00500336, + LedMatrix823 = 0x00500337, + LedMatrix824 = 0x00500338, + LedMatrix825 = 0x00500339, + LedMatrix826 = 0x0050033A, + LedMatrix827 = 0x0050033B, + LedMatrix828 = 0x0050033C, + LedMatrix829 = 0x0050033D, + LedMatrix830 = 0x0050033E, + LedMatrix831 = 0x0050033F, + LedMatrix832 = 0x00500340, + LedMatrix833 = 0x00500341, + LedMatrix834 = 0x00500342, + LedMatrix835 = 0x00500343, + LedMatrix836 = 0x00500344, + LedMatrix837 = 0x00500345, + LedMatrix838 = 0x00500346, + LedMatrix839 = 0x00500347, + LedMatrix840 = 0x00500348, + LedMatrix841 = 0x00500349, + LedMatrix842 = 0x0050034A, + LedMatrix843 = 0x0050034B, + LedMatrix844 = 0x0050034C, + LedMatrix845 = 0x0050034D, + LedMatrix846 = 0x0050034E, + LedMatrix847 = 0x0050034F, + LedMatrix848 = 0x00500350, + LedMatrix849 = 0x00500351, + LedMatrix850 = 0x00500352, + LedMatrix851 = 0x00500353, + LedMatrix852 = 0x00500354, + LedMatrix853 = 0x00500355, + LedMatrix854 = 0x00500356, + LedMatrix855 = 0x00500357, + LedMatrix856 = 0x00500358, + LedMatrix857 = 0x00500359, + LedMatrix858 = 0x0050035A, + LedMatrix859 = 0x0050035B, + LedMatrix860 = 0x0050035C, + LedMatrix861 = 0x0050035D, + LedMatrix862 = 0x0050035E, + LedMatrix863 = 0x0050035F, + LedMatrix864 = 0x00500360, + LedMatrix865 = 0x00500361, + LedMatrix866 = 0x00500362, + LedMatrix867 = 0x00500363, + LedMatrix868 = 0x00500364, + LedMatrix869 = 0x00500365, + LedMatrix870 = 0x00500366, + LedMatrix871 = 0x00500367, + LedMatrix872 = 0x00500368, + LedMatrix873 = 0x00500369, + LedMatrix874 = 0x0050036A, + LedMatrix875 = 0x0050036B, + LedMatrix876 = 0x0050036C, + LedMatrix877 = 0x0050036D, + LedMatrix878 = 0x0050036E, + LedMatrix879 = 0x0050036F, + LedMatrix880 = 0x00500370, + LedMatrix881 = 0x00500371, + LedMatrix882 = 0x00500372, + LedMatrix883 = 0x00500373, + LedMatrix884 = 0x00500374, + LedMatrix885 = 0x00500375, + LedMatrix886 = 0x00500376, + LedMatrix887 = 0x00500377, + LedMatrix888 = 0x00500378, + LedMatrix889 = 0x00500379, + LedMatrix890 = 0x0050037A, + LedMatrix891 = 0x0050037B, + LedMatrix892 = 0x0050037C, + LedMatrix893 = 0x0050037D, + LedMatrix894 = 0x0050037E, + LedMatrix895 = 0x0050037F, + LedMatrix896 = 0x00500380, + LedMatrix897 = 0x00500381, + LedMatrix898 = 0x00500382, + LedMatrix899 = 0x00500383, + LedMatrix900 = 0x00500384, + LedMatrix901 = 0x00500385, + LedMatrix902 = 0x00500386, + LedMatrix903 = 0x00500387, + LedMatrix904 = 0x00500388, + LedMatrix905 = 0x00500389, + LedMatrix906 = 0x0050038A, + LedMatrix907 = 0x0050038B, + LedMatrix908 = 0x0050038C, + LedMatrix909 = 0x0050038D, + LedMatrix910 = 0x0050038E, + LedMatrix911 = 0x0050038F, + LedMatrix912 = 0x00500390, + LedMatrix913 = 0x00500391, + LedMatrix914 = 0x00500392, + LedMatrix915 = 0x00500393, + LedMatrix916 = 0x00500394, + LedMatrix917 = 0x00500395, + LedMatrix918 = 0x00500396, + LedMatrix919 = 0x00500397, + LedMatrix920 = 0x00500398, + LedMatrix921 = 0x00500399, + LedMatrix922 = 0x0050039A, + LedMatrix923 = 0x0050039B, + LedMatrix924 = 0x0050039C, + LedMatrix925 = 0x0050039D, + LedMatrix926 = 0x0050039E, + LedMatrix927 = 0x0050039F, + LedMatrix928 = 0x005003A0, + LedMatrix929 = 0x005003A1, + LedMatrix930 = 0x005003A2, + LedMatrix931 = 0x005003A3, + LedMatrix932 = 0x005003A4, + LedMatrix933 = 0x005003A5, + LedMatrix934 = 0x005003A6, + LedMatrix935 = 0x005003A7, + LedMatrix936 = 0x005003A8, + LedMatrix937 = 0x005003A9, + LedMatrix938 = 0x005003AA, + LedMatrix939 = 0x005003AB, + LedMatrix940 = 0x005003AC, + LedMatrix941 = 0x005003AD, + LedMatrix942 = 0x005003AE, + LedMatrix943 = 0x005003AF, + LedMatrix944 = 0x005003B0, + LedMatrix945 = 0x005003B1, + LedMatrix946 = 0x005003B2, + LedMatrix947 = 0x005003B3, + LedMatrix948 = 0x005003B4, + LedMatrix949 = 0x005003B5, + LedMatrix950 = 0x005003B6, + LedMatrix951 = 0x005003B7, + LedMatrix952 = 0x005003B8, + LedMatrix953 = 0x005003B9, + LedMatrix954 = 0x005003BA, + LedMatrix955 = 0x005003BB, + LedMatrix956 = 0x005003BC, + LedMatrix957 = 0x005003BD, + LedMatrix958 = 0x005003BE, + LedMatrix959 = 0x005003BF, + LedMatrix960 = 0x005003C0, + LedMatrix961 = 0x005003C1, + LedMatrix962 = 0x005003C2, + LedMatrix963 = 0x005003C3, + LedMatrix964 = 0x005003C4, + LedMatrix965 = 0x005003C5, + LedMatrix966 = 0x005003C6, + LedMatrix967 = 0x005003C7, + LedMatrix968 = 0x005003C8, + LedMatrix969 = 0x005003C9, + LedMatrix970 = 0x005003CA, + LedMatrix971 = 0x005003CB, + LedMatrix972 = 0x005003CC, + LedMatrix973 = 0x005003CD, + LedMatrix974 = 0x005003CE, + LedMatrix975 = 0x005003CF, + LedMatrix976 = 0x005003D0, + LedMatrix977 = 0x005003D1, + LedMatrix978 = 0x005003D2, + LedMatrix979 = 0x005003D3, + LedMatrix980 = 0x005003D4, + LedMatrix981 = 0x005003D5, + LedMatrix982 = 0x005003D6, + LedMatrix983 = 0x005003D7, + LedMatrix984 = 0x005003D8, + LedMatrix985 = 0x005003D9, + LedMatrix986 = 0x005003DA, + LedMatrix987 = 0x005003DB, + LedMatrix988 = 0x005003DC, + LedMatrix989 = 0x005003DD, + LedMatrix990 = 0x005003DE, + LedMatrix991 = 0x005003DF, + LedMatrix992 = 0x005003E0, + LedMatrix993 = 0x005003E1, + LedMatrix994 = 0x005003E2, + LedMatrix995 = 0x005003E3, + LedMatrix996 = 0x005003E4, + LedMatrix997 = 0x005003E5, + LedMatrix998 = 0x005003E6, + LedMatrix999 = 0x005003E7, + LedMatrix1000 = 0x005003E8, + LedMatrix1001 = 0x005003E9, + LedMatrix1002 = 0x005003EA, + LedMatrix1003 = 0x005003EB, + LedMatrix1004 = 0x005003EC, + LedMatrix1005 = 0x005003ED, + LedMatrix1006 = 0x005003EE, + LedMatrix1007 = 0x005003EF, + LedMatrix1008 = 0x005003F0, + LedMatrix1009 = 0x005003F1, + LedMatrix1010 = 0x005003F2, + LedMatrix1011 = 0x005003F3, + LedMatrix1012 = 0x005003F4, + LedMatrix1013 = 0x005003F5, + LedMatrix1014 = 0x005003F6, + LedMatrix1015 = 0x005003F7, + LedMatrix1016 = 0x005003F8, + LedMatrix1017 = 0x005003F9, + LedMatrix1018 = 0x005003FA, + LedMatrix1019 = 0x005003FB, + LedMatrix1020 = 0x005003FC, + LedMatrix1021 = 0x005003FD, + LedMatrix1022 = 0x005003FE, + LedMatrix1023 = 0x005003FF, + LedMatrix1024 = 0x00500400, + LedMatrix1025 = 0x00500401, + LedMatrix1026 = 0x00500402, + LedMatrix1027 = 0x00500403, + LedMatrix1028 = 0x00500404, + LedMatrix1029 = 0x00500405, + LedMatrix1030 = 0x00500406, + LedMatrix1031 = 0x00500407, + LedMatrix1032 = 0x00500408, + LedMatrix1033 = 0x00500409, + LedMatrix1034 = 0x0050040A, + LedMatrix1035 = 0x0050040B, + LedMatrix1036 = 0x0050040C, + LedMatrix1037 = 0x0050040D, + LedMatrix1038 = 0x0050040E, + LedMatrix1039 = 0x0050040F, + LedMatrix1040 = 0x00500410, + LedMatrix1041 = 0x00500411, + LedMatrix1042 = 0x00500412, + LedMatrix1043 = 0x00500413, + LedMatrix1044 = 0x00500414, + LedMatrix1045 = 0x00500415, + LedMatrix1046 = 0x00500416, + LedMatrix1047 = 0x00500417, + LedMatrix1048 = 0x00500418, + LedMatrix1049 = 0x00500419, + LedMatrix1050 = 0x0050041A, + LedMatrix1051 = 0x0050041B, + LedMatrix1052 = 0x0050041C, + LedMatrix1053 = 0x0050041D, + LedMatrix1054 = 0x0050041E, + LedMatrix1055 = 0x0050041F, + LedMatrix1056 = 0x00500420, + LedMatrix1057 = 0x00500421, + LedMatrix1058 = 0x00500422, + LedMatrix1059 = 0x00500423, + LedMatrix1060 = 0x00500424, + LedMatrix1061 = 0x00500425, + LedMatrix1062 = 0x00500426, + LedMatrix1063 = 0x00500427, + LedMatrix1064 = 0x00500428, + LedMatrix1065 = 0x00500429, + LedMatrix1066 = 0x0050042A, + LedMatrix1067 = 0x0050042B, + LedMatrix1068 = 0x0050042C, + LedMatrix1069 = 0x0050042D, + LedMatrix1070 = 0x0050042E, + LedMatrix1071 = 0x0050042F, + LedMatrix1072 = 0x00500430, + LedMatrix1073 = 0x00500431, + LedMatrix1074 = 0x00500432, + LedMatrix1075 = 0x00500433, + LedMatrix1076 = 0x00500434, + LedMatrix1077 = 0x00500435, + LedMatrix1078 = 0x00500436, + LedMatrix1079 = 0x00500437, + LedMatrix1080 = 0x00500438, + LedMatrix1081 = 0x00500439, + LedMatrix1082 = 0x0050043A, + LedMatrix1083 = 0x0050043B, + LedMatrix1084 = 0x0050043C, + LedMatrix1085 = 0x0050043D, + LedMatrix1086 = 0x0050043E, + LedMatrix1087 = 0x0050043F, + LedMatrix1088 = 0x00500440, + LedMatrix1089 = 0x00500441, + LedMatrix1090 = 0x00500442, + LedMatrix1091 = 0x00500443, + LedMatrix1092 = 0x00500444, + LedMatrix1093 = 0x00500445, + LedMatrix1094 = 0x00500446, + LedMatrix1095 = 0x00500447, + LedMatrix1096 = 0x00500448, + LedMatrix1097 = 0x00500449, + LedMatrix1098 = 0x0050044A, + LedMatrix1099 = 0x0050044B, + LedMatrix1100 = 0x0050044C, + LedMatrix1101 = 0x0050044D, + LedMatrix1102 = 0x0050044E, + LedMatrix1103 = 0x0050044F, + LedMatrix1104 = 0x00500450, + LedMatrix1105 = 0x00500451, + LedMatrix1106 = 0x00500452, + LedMatrix1107 = 0x00500453, + LedMatrix1108 = 0x00500454, + LedMatrix1109 = 0x00500455, + LedMatrix1110 = 0x00500456, + LedMatrix1111 = 0x00500457, + LedMatrix1112 = 0x00500458, + LedMatrix1113 = 0x00500459, + LedMatrix1114 = 0x0050045A, + LedMatrix1115 = 0x0050045B, + LedMatrix1116 = 0x0050045C, + LedMatrix1117 = 0x0050045D, + LedMatrix1118 = 0x0050045E, + LedMatrix1119 = 0x0050045F, + LedMatrix1120 = 0x00500460, + LedMatrix1121 = 0x00500461, + LedMatrix1122 = 0x00500462, + LedMatrix1123 = 0x00500463, + LedMatrix1124 = 0x00500464, + LedMatrix1125 = 0x00500465, + LedMatrix1126 = 0x00500466, + LedMatrix1127 = 0x00500467, + LedMatrix1128 = 0x00500468, + LedMatrix1129 = 0x00500469, + LedMatrix1130 = 0x0050046A, + LedMatrix1131 = 0x0050046B, + LedMatrix1132 = 0x0050046C, + LedMatrix1133 = 0x0050046D, + LedMatrix1134 = 0x0050046E, + LedMatrix1135 = 0x0050046F, + LedMatrix1136 = 0x00500470, + LedMatrix1137 = 0x00500471, + LedMatrix1138 = 0x00500472, + LedMatrix1139 = 0x00500473, + LedMatrix1140 = 0x00500474, + LedMatrix1141 = 0x00500475, + LedMatrix1142 = 0x00500476, + LedMatrix1143 = 0x00500477, + LedMatrix1144 = 0x00500478, + LedMatrix1145 = 0x00500479, + LedMatrix1146 = 0x0050047A, + LedMatrix1147 = 0x0050047B, + LedMatrix1148 = 0x0050047C, + LedMatrix1149 = 0x0050047D, + LedMatrix1150 = 0x0050047E, + LedMatrix1151 = 0x0050047F, + LedMatrix1152 = 0x00500480, + LedMatrix1153 = 0x00500481, + LedMatrix1154 = 0x00500482, + LedMatrix1155 = 0x00500483, + LedMatrix1156 = 0x00500484, + LedMatrix1157 = 0x00500485, + LedMatrix1158 = 0x00500486, + LedMatrix1159 = 0x00500487, + LedMatrix1160 = 0x00500488, + LedMatrix1161 = 0x00500489, + LedMatrix1162 = 0x0050048A, + LedMatrix1163 = 0x0050048B, + LedMatrix1164 = 0x0050048C, + LedMatrix1165 = 0x0050048D, + LedMatrix1166 = 0x0050048E, + LedMatrix1167 = 0x0050048F, + LedMatrix1168 = 0x00500490, + LedMatrix1169 = 0x00500491, + LedMatrix1170 = 0x00500492, + LedMatrix1171 = 0x00500493, + LedMatrix1172 = 0x00500494, + LedMatrix1173 = 0x00500495, + LedMatrix1174 = 0x00500496, + LedMatrix1175 = 0x00500497, + LedMatrix1176 = 0x00500498, + LedMatrix1177 = 0x00500499, + LedMatrix1178 = 0x0050049A, + LedMatrix1179 = 0x0050049B, + LedMatrix1180 = 0x0050049C, + LedMatrix1181 = 0x0050049D, + LedMatrix1182 = 0x0050049E, + LedMatrix1183 = 0x0050049F, + LedMatrix1184 = 0x005004A0, + LedMatrix1185 = 0x005004A1, + LedMatrix1186 = 0x005004A2, + LedMatrix1187 = 0x005004A3, + LedMatrix1188 = 0x005004A4, + LedMatrix1189 = 0x005004A5, + LedMatrix1190 = 0x005004A6, + LedMatrix1191 = 0x005004A7, + LedMatrix1192 = 0x005004A8, + LedMatrix1193 = 0x005004A9, + LedMatrix1194 = 0x005004AA, + LedMatrix1195 = 0x005004AB, + LedMatrix1196 = 0x005004AC, + LedMatrix1197 = 0x005004AD, + LedMatrix1198 = 0x005004AE, + LedMatrix1199 = 0x005004AF, + LedMatrix1200 = 0x005004B0, + LedMatrix1201 = 0x005004B1, + LedMatrix1202 = 0x005004B2, + LedMatrix1203 = 0x005004B3, + LedMatrix1204 = 0x005004B4, + LedMatrix1205 = 0x005004B5, + LedMatrix1206 = 0x005004B6, + LedMatrix1207 = 0x005004B7, + LedMatrix1208 = 0x005004B8, + LedMatrix1209 = 0x005004B9, + LedMatrix1210 = 0x005004BA, + LedMatrix1211 = 0x005004BB, + LedMatrix1212 = 0x005004BC, + LedMatrix1213 = 0x005004BD, + LedMatrix1214 = 0x005004BE, + LedMatrix1215 = 0x005004BF, + LedMatrix1216 = 0x005004C0, + LedMatrix1217 = 0x005004C1, + LedMatrix1218 = 0x005004C2, + LedMatrix1219 = 0x005004C3, + LedMatrix1220 = 0x005004C4, + LedMatrix1221 = 0x005004C5, + LedMatrix1222 = 0x005004C6, + LedMatrix1223 = 0x005004C7, + LedMatrix1224 = 0x005004C8, + LedMatrix1225 = 0x005004C9, + LedMatrix1226 = 0x005004CA, + LedMatrix1227 = 0x005004CB, + LedMatrix1228 = 0x005004CC, + LedMatrix1229 = 0x005004CD, + LedMatrix1230 = 0x005004CE, + LedMatrix1231 = 0x005004CF, + LedMatrix1232 = 0x005004D0, + LedMatrix1233 = 0x005004D1, + LedMatrix1234 = 0x005004D2, + LedMatrix1235 = 0x005004D3, + LedMatrix1236 = 0x005004D4, + LedMatrix1237 = 0x005004D5, + LedMatrix1238 = 0x005004D6, + LedMatrix1239 = 0x005004D7, + LedMatrix1240 = 0x005004D8, + LedMatrix1241 = 0x005004D9, + LedMatrix1242 = 0x005004DA, + LedMatrix1243 = 0x005004DB, + LedMatrix1244 = 0x005004DC, + LedMatrix1245 = 0x005004DD, + LedMatrix1246 = 0x005004DE, + LedMatrix1247 = 0x005004DF, + LedMatrix1248 = 0x005004E0, + LedMatrix1249 = 0x005004E1, + LedMatrix1250 = 0x005004E2, + LedMatrix1251 = 0x005004E3, + LedMatrix1252 = 0x005004E4, + LedMatrix1253 = 0x005004E5, + LedMatrix1254 = 0x005004E6, + LedMatrix1255 = 0x005004E7, + LedMatrix1256 = 0x005004E8, + LedMatrix1257 = 0x005004E9, + LedMatrix1258 = 0x005004EA, + LedMatrix1259 = 0x005004EB, + LedMatrix1260 = 0x005004EC, + LedMatrix1261 = 0x005004ED, + LedMatrix1262 = 0x005004EE, + LedMatrix1263 = 0x005004EF, + LedMatrix1264 = 0x005004F0, + LedMatrix1265 = 0x005004F1, + LedMatrix1266 = 0x005004F2, + LedMatrix1267 = 0x005004F3, + LedMatrix1268 = 0x005004F4, + LedMatrix1269 = 0x005004F5, + LedMatrix1270 = 0x005004F6, + LedMatrix1271 = 0x005004F7, + LedMatrix1272 = 0x005004F8, + LedMatrix1273 = 0x005004F9, + LedMatrix1274 = 0x005004FA, + LedMatrix1275 = 0x005004FB, + LedMatrix1276 = 0x005004FC, + LedMatrix1277 = 0x005004FD, + LedMatrix1278 = 0x005004FE, + LedMatrix1279 = 0x005004FF, + LedMatrix1280 = 0x00500500, + LedMatrix1281 = 0x00500501, + LedMatrix1282 = 0x00500502, + LedMatrix1283 = 0x00500503, + LedMatrix1284 = 0x00500504, + LedMatrix1285 = 0x00500505, + LedMatrix1286 = 0x00500506, + LedMatrix1287 = 0x00500507, + LedMatrix1288 = 0x00500508, + LedMatrix1289 = 0x00500509, + LedMatrix1290 = 0x0050050A, + LedMatrix1291 = 0x0050050B, + LedMatrix1292 = 0x0050050C, + LedMatrix1293 = 0x0050050D, + LedMatrix1294 = 0x0050050E, + LedMatrix1295 = 0x0050050F, + LedMatrix1296 = 0x00500510, + LedMatrix1297 = 0x00500511, + LedMatrix1298 = 0x00500512, + LedMatrix1299 = 0x00500513, + LedMatrix1300 = 0x00500514, + LedMatrix1301 = 0x00500515, + LedMatrix1302 = 0x00500516, + LedMatrix1303 = 0x00500517, + LedMatrix1304 = 0x00500518, + LedMatrix1305 = 0x00500519, + LedMatrix1306 = 0x0050051A, + LedMatrix1307 = 0x0050051B, + LedMatrix1308 = 0x0050051C, + LedMatrix1309 = 0x0050051D, + LedMatrix1310 = 0x0050051E, + LedMatrix1311 = 0x0050051F, + LedMatrix1312 = 0x00500520, + LedMatrix1313 = 0x00500521, + LedMatrix1314 = 0x00500522, + LedMatrix1315 = 0x00500523, + LedMatrix1316 = 0x00500524, + LedMatrix1317 = 0x00500525, + LedMatrix1318 = 0x00500526, + LedMatrix1319 = 0x00500527, + LedMatrix1320 = 0x00500528, + LedMatrix1321 = 0x00500529, + LedMatrix1322 = 0x0050052A, + LedMatrix1323 = 0x0050052B, + LedMatrix1324 = 0x0050052C, + LedMatrix1325 = 0x0050052D, + LedMatrix1326 = 0x0050052E, + LedMatrix1327 = 0x0050052F, + LedMatrix1328 = 0x00500530, + LedMatrix1329 = 0x00500531, + LedMatrix1330 = 0x00500532, + LedMatrix1331 = 0x00500533, + LedMatrix1332 = 0x00500534, + LedMatrix1333 = 0x00500535, + LedMatrix1334 = 0x00500536, + LedMatrix1335 = 0x00500537, + LedMatrix1336 = 0x00500538, + LedMatrix1337 = 0x00500539, + LedMatrix1338 = 0x0050053A, + LedMatrix1339 = 0x0050053B, + LedMatrix1340 = 0x0050053C, + LedMatrix1341 = 0x0050053D, + LedMatrix1342 = 0x0050053E, + LedMatrix1343 = 0x0050053F, + LedMatrix1344 = 0x00500540, + LedMatrix1345 = 0x00500541, + LedMatrix1346 = 0x00500542, + LedMatrix1347 = 0x00500543, + LedMatrix1348 = 0x00500544, + LedMatrix1349 = 0x00500545, + LedMatrix1350 = 0x00500546, + LedMatrix1351 = 0x00500547, + LedMatrix1352 = 0x00500548, + LedMatrix1353 = 0x00500549, + LedMatrix1354 = 0x0050054A, + LedMatrix1355 = 0x0050054B, + LedMatrix1356 = 0x0050054C, + LedMatrix1357 = 0x0050054D, + LedMatrix1358 = 0x0050054E, + LedMatrix1359 = 0x0050054F, + LedMatrix1360 = 0x00500550, + LedMatrix1361 = 0x00500551, + LedMatrix1362 = 0x00500552, + LedMatrix1363 = 0x00500553, + LedMatrix1364 = 0x00500554, + LedMatrix1365 = 0x00500555, + LedMatrix1366 = 0x00500556, + LedMatrix1367 = 0x00500557, + LedMatrix1368 = 0x00500558, + LedMatrix1369 = 0x00500559, + LedMatrix1370 = 0x0050055A, + LedMatrix1371 = 0x0050055B, + LedMatrix1372 = 0x0050055C, + LedMatrix1373 = 0x0050055D, + LedMatrix1374 = 0x0050055E, + LedMatrix1375 = 0x0050055F, + LedMatrix1376 = 0x00500560, + LedMatrix1377 = 0x00500561, + LedMatrix1378 = 0x00500562, + LedMatrix1379 = 0x00500563, + LedMatrix1380 = 0x00500564, + LedMatrix1381 = 0x00500565, + LedMatrix1382 = 0x00500566, + LedMatrix1383 = 0x00500567, + LedMatrix1384 = 0x00500568, + LedMatrix1385 = 0x00500569, + LedMatrix1386 = 0x0050056A, + LedMatrix1387 = 0x0050056B, + LedMatrix1388 = 0x0050056C, + LedMatrix1389 = 0x0050056D, + LedMatrix1390 = 0x0050056E, + LedMatrix1391 = 0x0050056F, + LedMatrix1392 = 0x00500570, + LedMatrix1393 = 0x00500571, + LedMatrix1394 = 0x00500572, + LedMatrix1395 = 0x00500573, + LedMatrix1396 = 0x00500574, + LedMatrix1397 = 0x00500575, + LedMatrix1398 = 0x00500576, + LedMatrix1399 = 0x00500577, + LedMatrix1400 = 0x00500578, + LedMatrix1401 = 0x00500579, + LedMatrix1402 = 0x0050057A, + LedMatrix1403 = 0x0050057B, + LedMatrix1404 = 0x0050057C, + LedMatrix1405 = 0x0050057D, + LedMatrix1406 = 0x0050057E, + LedMatrix1407 = 0x0050057F, + LedMatrix1408 = 0x00500580, + LedMatrix1409 = 0x00500581, + LedMatrix1410 = 0x00500582, + LedMatrix1411 = 0x00500583, + LedMatrix1412 = 0x00500584, + LedMatrix1413 = 0x00500585, + LedMatrix1414 = 0x00500586, + LedMatrix1415 = 0x00500587, + LedMatrix1416 = 0x00500588, + LedMatrix1417 = 0x00500589, + LedMatrix1418 = 0x0050058A, + LedMatrix1419 = 0x0050058B, + LedMatrix1420 = 0x0050058C, + LedMatrix1421 = 0x0050058D, + LedMatrix1422 = 0x0050058E, + LedMatrix1423 = 0x0050058F, + LedMatrix1424 = 0x00500590, + LedMatrix1425 = 0x00500591, + LedMatrix1426 = 0x00500592, + LedMatrix1427 = 0x00500593, + LedMatrix1428 = 0x00500594, + LedMatrix1429 = 0x00500595, + LedMatrix1430 = 0x00500596, + LedMatrix1431 = 0x00500597, + LedMatrix1432 = 0x00500598, + LedMatrix1433 = 0x00500599, + LedMatrix1434 = 0x0050059A, + LedMatrix1435 = 0x0050059B, + LedMatrix1436 = 0x0050059C, + LedMatrix1437 = 0x0050059D, + LedMatrix1438 = 0x0050059E, + LedMatrix1439 = 0x0050059F, + LedMatrix1440 = 0x005005A0, + LedMatrix1441 = 0x005005A1, + LedMatrix1442 = 0x005005A2, + LedMatrix1443 = 0x005005A3, + LedMatrix1444 = 0x005005A4, + LedMatrix1445 = 0x005005A5, + LedMatrix1446 = 0x005005A6, + LedMatrix1447 = 0x005005A7, + LedMatrix1448 = 0x005005A8, + LedMatrix1449 = 0x005005A9, + LedMatrix1450 = 0x005005AA, + LedMatrix1451 = 0x005005AB, + LedMatrix1452 = 0x005005AC, + LedMatrix1453 = 0x005005AD, + LedMatrix1454 = 0x005005AE, + LedMatrix1455 = 0x005005AF, + LedMatrix1456 = 0x005005B0, + LedMatrix1457 = 0x005005B1, + LedMatrix1458 = 0x005005B2, + LedMatrix1459 = 0x005005B3, + LedMatrix1460 = 0x005005B4, + LedMatrix1461 = 0x005005B5, + LedMatrix1462 = 0x005005B6, + LedMatrix1463 = 0x005005B7, + LedMatrix1464 = 0x005005B8, + LedMatrix1465 = 0x005005B9, + LedMatrix1466 = 0x005005BA, + LedMatrix1467 = 0x005005BB, + LedMatrix1468 = 0x005005BC, + LedMatrix1469 = 0x005005BD, + LedMatrix1470 = 0x005005BE, + LedMatrix1471 = 0x005005BF, + LedMatrix1472 = 0x005005C0, + LedMatrix1473 = 0x005005C1, + LedMatrix1474 = 0x005005C2, + LedMatrix1475 = 0x005005C3, + LedMatrix1476 = 0x005005C4, + LedMatrix1477 = 0x005005C5, + LedMatrix1478 = 0x005005C6, + LedMatrix1479 = 0x005005C7, + LedMatrix1480 = 0x005005C8, + LedMatrix1481 = 0x005005C9, + LedMatrix1482 = 0x005005CA, + LedMatrix1483 = 0x005005CB, + LedMatrix1484 = 0x005005CC, + LedMatrix1485 = 0x005005CD, + LedMatrix1486 = 0x005005CE, + LedMatrix1487 = 0x005005CF, + LedMatrix1488 = 0x005005D0, + LedMatrix1489 = 0x005005D1, + LedMatrix1490 = 0x005005D2, + LedMatrix1491 = 0x005005D3, + LedMatrix1492 = 0x005005D4, + LedMatrix1493 = 0x005005D5, + LedMatrix1494 = 0x005005D6, + LedMatrix1495 = 0x005005D7, + LedMatrix1496 = 0x005005D8, + LedMatrix1497 = 0x005005D9, + LedMatrix1498 = 0x005005DA, + LedMatrix1499 = 0x005005DB, + LedMatrix1500 = 0x005005DC, + LedMatrix1501 = 0x005005DD, + LedMatrix1502 = 0x005005DE, + LedMatrix1503 = 0x005005DF, + LedMatrix1504 = 0x005005E0, + LedMatrix1505 = 0x005005E1, + LedMatrix1506 = 0x005005E2, + LedMatrix1507 = 0x005005E3, + LedMatrix1508 = 0x005005E4, + LedMatrix1509 = 0x005005E5, + LedMatrix1510 = 0x005005E6, + LedMatrix1511 = 0x005005E7, + LedMatrix1512 = 0x005005E8, + LedMatrix1513 = 0x005005E9, + LedMatrix1514 = 0x005005EA, + LedMatrix1515 = 0x005005EB, + LedMatrix1516 = 0x005005EC, + LedMatrix1517 = 0x005005ED, + LedMatrix1518 = 0x005005EE, + LedMatrix1519 = 0x005005EF, + LedMatrix1520 = 0x005005F0, + LedMatrix1521 = 0x005005F1, + LedMatrix1522 = 0x005005F2, + LedMatrix1523 = 0x005005F3, + LedMatrix1524 = 0x005005F4, + LedMatrix1525 = 0x005005F5, + LedMatrix1526 = 0x005005F6, + LedMatrix1527 = 0x005005F7, + LedMatrix1528 = 0x005005F8, + LedMatrix1529 = 0x005005F9, + LedMatrix1530 = 0x005005FA, + LedMatrix1531 = 0x005005FB, + LedMatrix1532 = 0x005005FC, + LedMatrix1533 = 0x005005FD, + LedMatrix1534 = 0x005005FE, + LedMatrix1535 = 0x005005FF, + LedMatrix1536 = 0x00500600, + LedMatrix1537 = 0x00500601, + LedMatrix1538 = 0x00500602, + LedMatrix1539 = 0x00500603, + LedMatrix1540 = 0x00500604, + LedMatrix1541 = 0x00500605, + LedMatrix1542 = 0x00500606, + LedMatrix1543 = 0x00500607, + LedMatrix1544 = 0x00500608, + LedMatrix1545 = 0x00500609, + LedMatrix1546 = 0x0050060A, + LedMatrix1547 = 0x0050060B, + LedMatrix1548 = 0x0050060C, + LedMatrix1549 = 0x0050060D, + LedMatrix1550 = 0x0050060E, + LedMatrix1551 = 0x0050060F, + LedMatrix1552 = 0x00500610, + LedMatrix1553 = 0x00500611, + LedMatrix1554 = 0x00500612, + LedMatrix1555 = 0x00500613, + LedMatrix1556 = 0x00500614, + LedMatrix1557 = 0x00500615, + LedMatrix1558 = 0x00500616, + LedMatrix1559 = 0x00500617, + LedMatrix1560 = 0x00500618, + LedMatrix1561 = 0x00500619, + LedMatrix1562 = 0x0050061A, + LedMatrix1563 = 0x0050061B, + LedMatrix1564 = 0x0050061C, + LedMatrix1565 = 0x0050061D, + LedMatrix1566 = 0x0050061E, + LedMatrix1567 = 0x0050061F, + LedMatrix1568 = 0x00500620, + LedMatrix1569 = 0x00500621, + LedMatrix1570 = 0x00500622, + LedMatrix1571 = 0x00500623, + LedMatrix1572 = 0x00500624, + LedMatrix1573 = 0x00500625, + LedMatrix1574 = 0x00500626, + LedMatrix1575 = 0x00500627, + LedMatrix1576 = 0x00500628, + LedMatrix1577 = 0x00500629, + LedMatrix1578 = 0x0050062A, + LedMatrix1579 = 0x0050062B, + LedMatrix1580 = 0x0050062C, + LedMatrix1581 = 0x0050062D, + LedMatrix1582 = 0x0050062E, + LedMatrix1583 = 0x0050062F, + LedMatrix1584 = 0x00500630, + LedMatrix1585 = 0x00500631, + LedMatrix1586 = 0x00500632, + LedMatrix1587 = 0x00500633, + LedMatrix1588 = 0x00500634, + LedMatrix1589 = 0x00500635, + LedMatrix1590 = 0x00500636, + LedMatrix1591 = 0x00500637, + LedMatrix1592 = 0x00500638, + LedMatrix1593 = 0x00500639, + LedMatrix1594 = 0x0050063A, + LedMatrix1595 = 0x0050063B, + LedMatrix1596 = 0x0050063C, + LedMatrix1597 = 0x0050063D, + LedMatrix1598 = 0x0050063E, + LedMatrix1599 = 0x0050063F, + LedMatrix1600 = 0x00500640, + LedMatrix1601 = 0x00500641, + LedMatrix1602 = 0x00500642, + LedMatrix1603 = 0x00500643, + LedMatrix1604 = 0x00500644, + LedMatrix1605 = 0x00500645, + LedMatrix1606 = 0x00500646, + LedMatrix1607 = 0x00500647, + LedMatrix1608 = 0x00500648, + LedMatrix1609 = 0x00500649, + LedMatrix1610 = 0x0050064A, + LedMatrix1611 = 0x0050064B, + LedMatrix1612 = 0x0050064C, + LedMatrix1613 = 0x0050064D, + LedMatrix1614 = 0x0050064E, + LedMatrix1615 = 0x0050064F, + LedMatrix1616 = 0x00500650, + LedMatrix1617 = 0x00500651, + LedMatrix1618 = 0x00500652, + LedMatrix1619 = 0x00500653, + LedMatrix1620 = 0x00500654, + LedMatrix1621 = 0x00500655, + LedMatrix1622 = 0x00500656, + LedMatrix1623 = 0x00500657, + LedMatrix1624 = 0x00500658, + LedMatrix1625 = 0x00500659, + LedMatrix1626 = 0x0050065A, + LedMatrix1627 = 0x0050065B, + LedMatrix1628 = 0x0050065C, + LedMatrix1629 = 0x0050065D, + LedMatrix1630 = 0x0050065E, + LedMatrix1631 = 0x0050065F, + LedMatrix1632 = 0x00500660, + LedMatrix1633 = 0x00500661, + LedMatrix1634 = 0x00500662, + LedMatrix1635 = 0x00500663, + LedMatrix1636 = 0x00500664, + LedMatrix1637 = 0x00500665, + LedMatrix1638 = 0x00500666, + LedMatrix1639 = 0x00500667, + LedMatrix1640 = 0x00500668, + LedMatrix1641 = 0x00500669, + LedMatrix1642 = 0x0050066A, + LedMatrix1643 = 0x0050066B, + LedMatrix1644 = 0x0050066C, + LedMatrix1645 = 0x0050066D, + LedMatrix1646 = 0x0050066E, + LedMatrix1647 = 0x0050066F, + LedMatrix1648 = 0x00500670, + LedMatrix1649 = 0x00500671, + LedMatrix1650 = 0x00500672, + LedMatrix1651 = 0x00500673, + LedMatrix1652 = 0x00500674, + LedMatrix1653 = 0x00500675, + LedMatrix1654 = 0x00500676, + LedMatrix1655 = 0x00500677, + LedMatrix1656 = 0x00500678, + LedMatrix1657 = 0x00500679, + LedMatrix1658 = 0x0050067A, + LedMatrix1659 = 0x0050067B, + LedMatrix1660 = 0x0050067C, + LedMatrix1661 = 0x0050067D, + LedMatrix1662 = 0x0050067E, + LedMatrix1663 = 0x0050067F, + LedMatrix1664 = 0x00500680, + LedMatrix1665 = 0x00500681, + LedMatrix1666 = 0x00500682, + LedMatrix1667 = 0x00500683, + LedMatrix1668 = 0x00500684, + LedMatrix1669 = 0x00500685, + LedMatrix1670 = 0x00500686, + LedMatrix1671 = 0x00500687, + LedMatrix1672 = 0x00500688, + LedMatrix1673 = 0x00500689, + LedMatrix1674 = 0x0050068A, + LedMatrix1675 = 0x0050068B, + LedMatrix1676 = 0x0050068C, + LedMatrix1677 = 0x0050068D, + LedMatrix1678 = 0x0050068E, + LedMatrix1679 = 0x0050068F, + LedMatrix1680 = 0x00500690, + LedMatrix1681 = 0x00500691, + LedMatrix1682 = 0x00500692, + LedMatrix1683 = 0x00500693, + LedMatrix1684 = 0x00500694, + LedMatrix1685 = 0x00500695, + LedMatrix1686 = 0x00500696, + LedMatrix1687 = 0x00500697, + LedMatrix1688 = 0x00500698, + LedMatrix1689 = 0x00500699, + LedMatrix1690 = 0x0050069A, + LedMatrix1691 = 0x0050069B, + LedMatrix1692 = 0x0050069C, + LedMatrix1693 = 0x0050069D, + LedMatrix1694 = 0x0050069E, + LedMatrix1695 = 0x0050069F, + LedMatrix1696 = 0x005006A0, + LedMatrix1697 = 0x005006A1, + LedMatrix1698 = 0x005006A2, + LedMatrix1699 = 0x005006A3, + LedMatrix1700 = 0x005006A4, + LedMatrix1701 = 0x005006A5, + LedMatrix1702 = 0x005006A6, + LedMatrix1703 = 0x005006A7, + LedMatrix1704 = 0x005006A8, + LedMatrix1705 = 0x005006A9, + LedMatrix1706 = 0x005006AA, + LedMatrix1707 = 0x005006AB, + LedMatrix1708 = 0x005006AC, + LedMatrix1709 = 0x005006AD, + LedMatrix1710 = 0x005006AE, + LedMatrix1711 = 0x005006AF, + LedMatrix1712 = 0x005006B0, + LedMatrix1713 = 0x005006B1, + LedMatrix1714 = 0x005006B2, + LedMatrix1715 = 0x005006B3, + LedMatrix1716 = 0x005006B4, + LedMatrix1717 = 0x005006B5, + LedMatrix1718 = 0x005006B6, + LedMatrix1719 = 0x005006B7, + LedMatrix1720 = 0x005006B8, + LedMatrix1721 = 0x005006B9, + LedMatrix1722 = 0x005006BA, + LedMatrix1723 = 0x005006BB, + LedMatrix1724 = 0x005006BC, + LedMatrix1725 = 0x005006BD, + LedMatrix1726 = 0x005006BE, + LedMatrix1727 = 0x005006BF, + LedMatrix1728 = 0x005006C0, + LedMatrix1729 = 0x005006C1, + LedMatrix1730 = 0x005006C2, + LedMatrix1731 = 0x005006C3, + LedMatrix1732 = 0x005006C4, + LedMatrix1733 = 0x005006C5, + LedMatrix1734 = 0x005006C6, + LedMatrix1735 = 0x005006C7, + LedMatrix1736 = 0x005006C8, + LedMatrix1737 = 0x005006C9, + LedMatrix1738 = 0x005006CA, + LedMatrix1739 = 0x005006CB, + LedMatrix1740 = 0x005006CC, + LedMatrix1741 = 0x005006CD, + LedMatrix1742 = 0x005006CE, + LedMatrix1743 = 0x005006CF, + LedMatrix1744 = 0x005006D0, + LedMatrix1745 = 0x005006D1, + LedMatrix1746 = 0x005006D2, + LedMatrix1747 = 0x005006D3, + LedMatrix1748 = 0x005006D4, + LedMatrix1749 = 0x005006D5, + LedMatrix1750 = 0x005006D6, + LedMatrix1751 = 0x005006D7, + LedMatrix1752 = 0x005006D8, + LedMatrix1753 = 0x005006D9, + LedMatrix1754 = 0x005006DA, + LedMatrix1755 = 0x005006DB, + LedMatrix1756 = 0x005006DC, + LedMatrix1757 = 0x005006DD, + LedMatrix1758 = 0x005006DE, + LedMatrix1759 = 0x005006DF, + LedMatrix1760 = 0x005006E0, + LedMatrix1761 = 0x005006E1, + LedMatrix1762 = 0x005006E2, + LedMatrix1763 = 0x005006E3, + LedMatrix1764 = 0x005006E4, + LedMatrix1765 = 0x005006E5, + LedMatrix1766 = 0x005006E6, + LedMatrix1767 = 0x005006E7, + LedMatrix1768 = 0x005006E8, + LedMatrix1769 = 0x005006E9, + LedMatrix1770 = 0x005006EA, + LedMatrix1771 = 0x005006EB, + LedMatrix1772 = 0x005006EC, + LedMatrix1773 = 0x005006ED, + LedMatrix1774 = 0x005006EE, + LedMatrix1775 = 0x005006EF, + LedMatrix1776 = 0x005006F0, + LedMatrix1777 = 0x005006F1, + LedMatrix1778 = 0x005006F2, + LedMatrix1779 = 0x005006F3, + LedMatrix1780 = 0x005006F4, + LedMatrix1781 = 0x005006F5, + LedMatrix1782 = 0x005006F6, + LedMatrix1783 = 0x005006F7, + LedMatrix1784 = 0x005006F8, + LedMatrix1785 = 0x005006F9, + LedMatrix1786 = 0x005006FA, + LedMatrix1787 = 0x005006FB, + LedMatrix1788 = 0x005006FC, + LedMatrix1789 = 0x005006FD, + LedMatrix1790 = 0x005006FE, + LedMatrix1791 = 0x005006FF, + LedMatrix1792 = 0x00500700, + LedMatrix1793 = 0x00500701, + LedMatrix1794 = 0x00500702, + LedMatrix1795 = 0x00500703, + LedMatrix1796 = 0x00500704, + LedMatrix1797 = 0x00500705, + LedMatrix1798 = 0x00500706, + LedMatrix1799 = 0x00500707, + LedMatrix1800 = 0x00500708, + LedMatrix1801 = 0x00500709, + LedMatrix1802 = 0x0050070A, + LedMatrix1803 = 0x0050070B, + LedMatrix1804 = 0x0050070C, + LedMatrix1805 = 0x0050070D, + LedMatrix1806 = 0x0050070E, + LedMatrix1807 = 0x0050070F, + LedMatrix1808 = 0x00500710, + LedMatrix1809 = 0x00500711, + LedMatrix1810 = 0x00500712, + LedMatrix1811 = 0x00500713, + LedMatrix1812 = 0x00500714, + LedMatrix1813 = 0x00500715, + LedMatrix1814 = 0x00500716, + LedMatrix1815 = 0x00500717, + LedMatrix1816 = 0x00500718, + LedMatrix1817 = 0x00500719, + LedMatrix1818 = 0x0050071A, + LedMatrix1819 = 0x0050071B, + LedMatrix1820 = 0x0050071C, + LedMatrix1821 = 0x0050071D, + LedMatrix1822 = 0x0050071E, + LedMatrix1823 = 0x0050071F, + LedMatrix1824 = 0x00500720, + LedMatrix1825 = 0x00500721, + LedMatrix1826 = 0x00500722, + LedMatrix1827 = 0x00500723, + LedMatrix1828 = 0x00500724, + LedMatrix1829 = 0x00500725, + LedMatrix1830 = 0x00500726, + LedMatrix1831 = 0x00500727, + LedMatrix1832 = 0x00500728, + LedMatrix1833 = 0x00500729, + LedMatrix1834 = 0x0050072A, + LedMatrix1835 = 0x0050072B, + LedMatrix1836 = 0x0050072C, + LedMatrix1837 = 0x0050072D, + LedMatrix1838 = 0x0050072E, + LedMatrix1839 = 0x0050072F, + LedMatrix1840 = 0x00500730, + LedMatrix1841 = 0x00500731, + LedMatrix1842 = 0x00500732, + LedMatrix1843 = 0x00500733, + LedMatrix1844 = 0x00500734, + LedMatrix1845 = 0x00500735, + LedMatrix1846 = 0x00500736, + LedMatrix1847 = 0x00500737, + LedMatrix1848 = 0x00500738, + LedMatrix1849 = 0x00500739, + LedMatrix1850 = 0x0050073A, + LedMatrix1851 = 0x0050073B, + LedMatrix1852 = 0x0050073C, + LedMatrix1853 = 0x0050073D, + LedMatrix1854 = 0x0050073E, + LedMatrix1855 = 0x0050073F, + LedMatrix1856 = 0x00500740, + LedMatrix1857 = 0x00500741, + LedMatrix1858 = 0x00500742, + LedMatrix1859 = 0x00500743, + LedMatrix1860 = 0x00500744, + LedMatrix1861 = 0x00500745, + LedMatrix1862 = 0x00500746, + LedMatrix1863 = 0x00500747, + LedMatrix1864 = 0x00500748, + LedMatrix1865 = 0x00500749, + LedMatrix1866 = 0x0050074A, + LedMatrix1867 = 0x0050074B, + LedMatrix1868 = 0x0050074C, + LedMatrix1869 = 0x0050074D, + LedMatrix1870 = 0x0050074E, + LedMatrix1871 = 0x0050074F, + LedMatrix1872 = 0x00500750, + LedMatrix1873 = 0x00500751, + LedMatrix1874 = 0x00500752, + LedMatrix1875 = 0x00500753, + LedMatrix1876 = 0x00500754, + LedMatrix1877 = 0x00500755, + LedMatrix1878 = 0x00500756, + LedMatrix1879 = 0x00500757, + LedMatrix1880 = 0x00500758, + LedMatrix1881 = 0x00500759, + LedMatrix1882 = 0x0050075A, + LedMatrix1883 = 0x0050075B, + LedMatrix1884 = 0x0050075C, + LedMatrix1885 = 0x0050075D, + LedMatrix1886 = 0x0050075E, + LedMatrix1887 = 0x0050075F, + LedMatrix1888 = 0x00500760, + LedMatrix1889 = 0x00500761, + LedMatrix1890 = 0x00500762, + LedMatrix1891 = 0x00500763, + LedMatrix1892 = 0x00500764, + LedMatrix1893 = 0x00500765, + LedMatrix1894 = 0x00500766, + LedMatrix1895 = 0x00500767, + LedMatrix1896 = 0x00500768, + LedMatrix1897 = 0x00500769, + LedMatrix1898 = 0x0050076A, + LedMatrix1899 = 0x0050076B, + LedMatrix1900 = 0x0050076C, + LedMatrix1901 = 0x0050076D, + LedMatrix1902 = 0x0050076E, + LedMatrix1903 = 0x0050076F, + LedMatrix1904 = 0x00500770, + LedMatrix1905 = 0x00500771, + LedMatrix1906 = 0x00500772, + LedMatrix1907 = 0x00500773, + LedMatrix1908 = 0x00500774, + LedMatrix1909 = 0x00500775, + LedMatrix1910 = 0x00500776, + LedMatrix1911 = 0x00500777, + LedMatrix1912 = 0x00500778, + LedMatrix1913 = 0x00500779, + LedMatrix1914 = 0x0050077A, + LedMatrix1915 = 0x0050077B, + LedMatrix1916 = 0x0050077C, + LedMatrix1917 = 0x0050077D, + LedMatrix1918 = 0x0050077E, + LedMatrix1919 = 0x0050077F, + LedMatrix1920 = 0x00500780, + LedMatrix1921 = 0x00500781, + LedMatrix1922 = 0x00500782, + LedMatrix1923 = 0x00500783, + LedMatrix1924 = 0x00500784, + LedMatrix1925 = 0x00500785, + LedMatrix1926 = 0x00500786, + LedMatrix1927 = 0x00500787, + LedMatrix1928 = 0x00500788, + LedMatrix1929 = 0x00500789, + LedMatrix1930 = 0x0050078A, + LedMatrix1931 = 0x0050078B, + LedMatrix1932 = 0x0050078C, + LedMatrix1933 = 0x0050078D, + LedMatrix1934 = 0x0050078E, + LedMatrix1935 = 0x0050078F, + LedMatrix1936 = 0x00500790, + LedMatrix1937 = 0x00500791, + LedMatrix1938 = 0x00500792, + LedMatrix1939 = 0x00500793, + LedMatrix1940 = 0x00500794, + LedMatrix1941 = 0x00500795, + LedMatrix1942 = 0x00500796, + LedMatrix1943 = 0x00500797, + LedMatrix1944 = 0x00500798, + LedMatrix1945 = 0x00500799, + LedMatrix1946 = 0x0050079A, + LedMatrix1947 = 0x0050079B, + LedMatrix1948 = 0x0050079C, + LedMatrix1949 = 0x0050079D, + LedMatrix1950 = 0x0050079E, + LedMatrix1951 = 0x0050079F, + LedMatrix1952 = 0x005007A0, + LedMatrix1953 = 0x005007A1, + LedMatrix1954 = 0x005007A2, + LedMatrix1955 = 0x005007A3, + LedMatrix1956 = 0x005007A4, + LedMatrix1957 = 0x005007A5, + LedMatrix1958 = 0x005007A6, + LedMatrix1959 = 0x005007A7, + LedMatrix1960 = 0x005007A8, + LedMatrix1961 = 0x005007A9, + LedMatrix1962 = 0x005007AA, + LedMatrix1963 = 0x005007AB, + LedMatrix1964 = 0x005007AC, + LedMatrix1965 = 0x005007AD, + LedMatrix1966 = 0x005007AE, + LedMatrix1967 = 0x005007AF, + LedMatrix1968 = 0x005007B0, + LedMatrix1969 = 0x005007B1, + LedMatrix1970 = 0x005007B2, + LedMatrix1971 = 0x005007B3, + LedMatrix1972 = 0x005007B4, + LedMatrix1973 = 0x005007B5, + LedMatrix1974 = 0x005007B6, + LedMatrix1975 = 0x005007B7, + LedMatrix1976 = 0x005007B8, + LedMatrix1977 = 0x005007B9, + LedMatrix1978 = 0x005007BA, + LedMatrix1979 = 0x005007BB, + LedMatrix1980 = 0x005007BC, + LedMatrix1981 = 0x005007BD, + LedMatrix1982 = 0x005007BE, + LedMatrix1983 = 0x005007BF, + LedMatrix1984 = 0x005007C0, + LedMatrix1985 = 0x005007C1, + LedMatrix1986 = 0x005007C2, + LedMatrix1987 = 0x005007C3, + LedMatrix1988 = 0x005007C4, + LedMatrix1989 = 0x005007C5, + LedMatrix1990 = 0x005007C6, + LedMatrix1991 = 0x005007C7, + LedMatrix1992 = 0x005007C8, + LedMatrix1993 = 0x005007C9, + LedMatrix1994 = 0x005007CA, + LedMatrix1995 = 0x005007CB, + LedMatrix1996 = 0x005007CC, + LedMatrix1997 = 0x005007CD, + LedMatrix1998 = 0x005007CE, + LedMatrix1999 = 0x005007CF, + LedMatrix2000 = 0x005007D0, + LedMatrix2001 = 0x005007D1, + LedMatrix2002 = 0x005007D2, + LedMatrix2003 = 0x005007D3, + LedMatrix2004 = 0x005007D4, + LedMatrix2005 = 0x005007D5, + LedMatrix2006 = 0x005007D6, + LedMatrix2007 = 0x005007D7, + LedMatrix2008 = 0x005007D8, + LedMatrix2009 = 0x005007D9, + LedMatrix2010 = 0x005007DA, + LedMatrix2011 = 0x005007DB, + LedMatrix2012 = 0x005007DC, + LedMatrix2013 = 0x005007DD, + LedMatrix2014 = 0x005007DE, + LedMatrix2015 = 0x005007DF, + LedMatrix2016 = 0x005007E0, + LedMatrix2017 = 0x005007E1, + LedMatrix2018 = 0x005007E2, + LedMatrix2019 = 0x005007E3, + LedMatrix2020 = 0x005007E4, + LedMatrix2021 = 0x005007E5, + LedMatrix2022 = 0x005007E6, + LedMatrix2023 = 0x005007E7, + LedMatrix2024 = 0x005007E8, + LedMatrix2025 = 0x005007E9, + LedMatrix2026 = 0x005007EA, + LedMatrix2027 = 0x005007EB, + LedMatrix2028 = 0x005007EC, + LedMatrix2029 = 0x005007ED, + LedMatrix2030 = 0x005007EE, + LedMatrix2031 = 0x005007EF, + LedMatrix2032 = 0x005007F0, + LedMatrix2033 = 0x005007F1, + LedMatrix2034 = 0x005007F2, + LedMatrix2035 = 0x005007F3, + LedMatrix2036 = 0x005007F4, + LedMatrix2037 = 0x005007F5, + LedMatrix2038 = 0x005007F6, + LedMatrix2039 = 0x005007F7, + LedMatrix2040 = 0x005007F8, + LedMatrix2041 = 0x005007F9, + LedMatrix2042 = 0x005007FA, + LedMatrix2043 = 0x005007FB, + LedMatrix2044 = 0x005007FC, + LedMatrix2045 = 0x005007FD, + LedMatrix2046 = 0x005007FE, + LedMatrix2047 = 0x005007FF, + LedMatrix2048 = 0x00500800, - /*### LedMatrix ###*/ - LedMatrix1 = 0x00500001, - LedMatrix2 = 0x00500002, - LedMatrix3 = 0x00500003, - LedMatrix4 = 0x00500004, - LedMatrix5 = 0x00500005, - LedMatrix6 = 0x00500006, - LedMatrix7 = 0x00500007, - LedMatrix8 = 0x00500008, - LedMatrix9 = 0x00500009, - LedMatrix10 = 0x0050000A, - LedMatrix11 = 0x0050000B, - LedMatrix12 = 0x0050000C, - LedMatrix13 = 0x0050000D, - LedMatrix14 = 0x0050000E, - LedMatrix15 = 0x0050000F, - LedMatrix16 = 0x00500010, - LedMatrix17 = 0x00500011, - LedMatrix18 = 0x00500012, - LedMatrix19 = 0x00500013, - LedMatrix20 = 0x00500014, - LedMatrix21 = 0x00500015, - LedMatrix22 = 0x00500016, - LedMatrix23 = 0x00500017, - LedMatrix24 = 0x00500018, - LedMatrix25 = 0x00500019, - LedMatrix26 = 0x0050001A, - LedMatrix27 = 0x0050001B, - LedMatrix28 = 0x0050001C, - LedMatrix29 = 0x0050001D, - LedMatrix30 = 0x0050001E, - LedMatrix31 = 0x0050001F, - LedMatrix32 = 0x00500020, - LedMatrix33 = 0x00500021, - LedMatrix34 = 0x00500022, - LedMatrix35 = 0x00500023, - LedMatrix36 = 0x00500024, - LedMatrix37 = 0x00500025, - LedMatrix38 = 0x00500026, - LedMatrix39 = 0x00500027, - LedMatrix40 = 0x00500028, - LedMatrix41 = 0x00500029, - LedMatrix42 = 0x0050002A, - LedMatrix43 = 0x0050002B, - LedMatrix44 = 0x0050002C, - LedMatrix45 = 0x0050002D, - LedMatrix46 = 0x0050002E, - LedMatrix47 = 0x0050002F, - LedMatrix48 = 0x00500030, - LedMatrix49 = 0x00500031, - LedMatrix50 = 0x00500032, - LedMatrix51 = 0x00500033, - LedMatrix52 = 0x00500034, - LedMatrix53 = 0x00500035, - LedMatrix54 = 0x00500036, - LedMatrix55 = 0x00500037, - LedMatrix56 = 0x00500038, - LedMatrix57 = 0x00500039, - LedMatrix58 = 0x0050003A, - LedMatrix59 = 0x0050003B, - LedMatrix60 = 0x0050003C, - LedMatrix61 = 0x0050003D, - LedMatrix62 = 0x0050003E, - LedMatrix63 = 0x0050003F, - LedMatrix64 = 0x00500040, - LedMatrix665 = 0x00500041, - LedMatrix666 = 0x00500042, - LedMatrix667 = 0x00500043, - LedMatrix668 = 0x00500044, - LedMatrix669 = 0x00500045, - LedMatrix670 = 0x00500046, - LedMatrix671 = 0x00500047, - LedMatrix672 = 0x00500048, - LedMatrix673 = 0x00500049, - LedMatrix674 = 0x0050004A, - LedMatrix675 = 0x0050004B, - LedMatrix676 = 0x0050004C, - LedMatrix677 = 0x0050004D, - LedMatrix678 = 0x0050004E, - LedMatrix679 = 0x0050004F, - LedMatrix680 = 0x00500050, - LedMatrix681 = 0x00500051, - LedMatrix682 = 0x00500052, - LedMatrix683 = 0x00500053, - LedMatrix684 = 0x00500054, - LedMatrix685 = 0x00500055, - LedMatrix686 = 0x00500056, - LedMatrix687 = 0x00500057, - LedMatrix688 = 0x00500058, - LedMatrix689 = 0x00500059, - LedMatrix690 = 0x0050005A, - LedMatrix691 = 0x0050005B, - LedMatrix692 = 0x0050005C, - LedMatrix693 = 0x0050005D, - LedMatrix694 = 0x0050005E, - LedMatrix695 = 0x0050005F, - LedMatrix696 = 0x00500060, - LedMatrix697 = 0x00500061, - LedMatrix698 = 0x00500062, - LedMatrix699 = 0x00500063, - LedMatrix6100 = 0x00500064, - LedMatrix6101 = 0x00500065, - LedMatrix6102 = 0x00500066, - LedMatrix6103 = 0x00500067, - LedMatrix6104 = 0x00500068, - LedMatrix6105 = 0x00500069, - LedMatrix6106 = 0x0050006A, - LedMatrix6107 = 0x0050006B, - LedMatrix6108 = 0x0050006C, - LedMatrix6109 = 0x0050006D, - LedMatrix6110 = 0x0050006E, - LedMatrix6111 = 0x0050006F, - LedMatrix6112 = 0x00500070, - LedMatrix6113 = 0x00500071, - LedMatrix6114 = 0x00500072, - LedMatrix6115 = 0x00500073, - LedMatrix6116 = 0x00500074, - LedMatrix6117 = 0x00500075, - LedMatrix6118 = 0x00500076, - LedMatrix6119 = 0x00500077, - LedMatrix6120 = 0x00500078, - LedMatrix6121 = 0x00500079, - LedMatrix6122 = 0x0050007A, - LedMatrix6123 = 0x0050007B, - LedMatrix6124 = 0x0050007C, - LedMatrix6125 = 0x0050007D, - LedMatrix6126 = 0x0050007E, - LedMatrix6127 = 0x0050007F, - LedMatrix6128 = 0x00500080, + /*### Mainboard ###*/ + Mainboard1 = 0x00600001, + Mainboard2 = 0x00600002, + Mainboard3 = 0x00600003, + Mainboard4 = 0x00600004, + Mainboard5 = 0x00600005, + Mainboard6 = 0x00600006, + Mainboard7 = 0x00600007, + Mainboard8 = 0x00600008, + Mainboard9 = 0x00600009, + Mainboard10 = 0x0060000A, + Mainboard11 = 0x0060000B, + Mainboard12 = 0x0060000C, + Mainboard13 = 0x0060000D, + Mainboard14 = 0x0060000E, + Mainboard15 = 0x0060000F, + Mainboard16 = 0x00600010, + Mainboard17 = 0x00600011, + Mainboard18 = 0x00600012, + Mainboard19 = 0x00600013, + Mainboard20 = 0x00600014, + Mainboard21 = 0x00600015, + Mainboard22 = 0x00600016, + Mainboard23 = 0x00600017, + Mainboard24 = 0x00600018, + Mainboard25 = 0x00600019, + Mainboard26 = 0x0060001A, + Mainboard27 = 0x0060001B, + Mainboard28 = 0x0060001C, + Mainboard29 = 0x0060001D, + Mainboard30 = 0x0060001E, + Mainboard31 = 0x0060001F, + Mainboard32 = 0x00600020, + Mainboard33 = 0x00600021, + Mainboard34 = 0x00600022, + Mainboard35 = 0x00600023, + Mainboard36 = 0x00600024, + Mainboard37 = 0x00600025, + Mainboard38 = 0x00600026, + Mainboard39 = 0x00600027, + Mainboard40 = 0x00600028, + Mainboard41 = 0x00600029, + Mainboard42 = 0x0060002A, + Mainboard43 = 0x0060002B, + Mainboard44 = 0x0060002C, + Mainboard45 = 0x0060002D, + Mainboard46 = 0x0060002E, + Mainboard47 = 0x0060002F, + Mainboard48 = 0x00600030, + Mainboard49 = 0x00600031, + Mainboard50 = 0x00600032, + Mainboard51 = 0x00600033, + Mainboard52 = 0x00600034, + Mainboard53 = 0x00600035, + Mainboard54 = 0x00600036, + Mainboard55 = 0x00600037, + Mainboard56 = 0x00600038, + Mainboard57 = 0x00600039, + Mainboard58 = 0x0060003A, + Mainboard59 = 0x0060003B, + Mainboard60 = 0x0060003C, + Mainboard61 = 0x0060003D, + Mainboard62 = 0x0060003E, + Mainboard63 = 0x0060003F, + Mainboard64 = 0x00600040, + Mainboard65 = 0x00600041, + Mainboard66 = 0x00600042, + Mainboard67 = 0x00600043, + Mainboard68 = 0x00600044, + Mainboard69 = 0x00600045, + Mainboard70 = 0x00600046, + Mainboard71 = 0x00600047, + Mainboard72 = 0x00600048, + Mainboard73 = 0x00600049, + Mainboard74 = 0x0060004A, + Mainboard75 = 0x0060004B, + Mainboard76 = 0x0060004C, + Mainboard77 = 0x0060004D, + Mainboard78 = 0x0060004E, + Mainboard79 = 0x0060004F, + Mainboard80 = 0x00600050, + Mainboard81 = 0x00600051, + Mainboard82 = 0x00600052, + Mainboard83 = 0x00600053, + Mainboard84 = 0x00600054, + Mainboard85 = 0x00600055, + Mainboard86 = 0x00600056, + Mainboard87 = 0x00600057, + Mainboard88 = 0x00600058, + Mainboard89 = 0x00600059, + Mainboard90 = 0x0060005A, + Mainboard91 = 0x0060005B, + Mainboard92 = 0x0060005C, + Mainboard93 = 0x0060005D, + Mainboard94 = 0x0060005E, + Mainboard95 = 0x0060005F, + Mainboard96 = 0x00600060, + Mainboard97 = 0x00600061, + Mainboard98 = 0x00600062, + Mainboard99 = 0x00600063, + Mainboard100 = 0x00600064, + Mainboard101 = 0x00600065, + Mainboard102 = 0x00600066, + Mainboard103 = 0x00600067, + Mainboard104 = 0x00600068, + Mainboard105 = 0x00600069, + Mainboard106 = 0x0060006A, + Mainboard107 = 0x0060006B, + Mainboard108 = 0x0060006C, + Mainboard109 = 0x0060006D, + Mainboard110 = 0x0060006E, + Mainboard111 = 0x0060006F, + Mainboard112 = 0x00600070, + Mainboard113 = 0x00600071, + Mainboard114 = 0x00600072, + Mainboard115 = 0x00600073, + Mainboard116 = 0x00600074, + Mainboard117 = 0x00600075, + Mainboard118 = 0x00600076, + Mainboard119 = 0x00600077, + Mainboard120 = 0x00600078, + Mainboard121 = 0x00600079, + Mainboard122 = 0x0060007A, + Mainboard123 = 0x0060007B, + Mainboard124 = 0x0060007C, + Mainboard125 = 0x0060007D, + Mainboard126 = 0x0060007E, + Mainboard127 = 0x0060007F, + Mainboard128 = 0x00600080, + Mainboard129 = 0x00600081, + Mainboard130 = 0x00600082, + Mainboard131 = 0x00600083, + Mainboard132 = 0x00600084, + Mainboard133 = 0x00600085, + Mainboard134 = 0x00600086, + Mainboard135 = 0x00600087, + Mainboard136 = 0x00600088, + Mainboard137 = 0x00600089, + Mainboard138 = 0x0060008A, + Mainboard139 = 0x0060008B, + Mainboard140 = 0x0060008C, + Mainboard141 = 0x0060008D, + Mainboard142 = 0x0060008E, + Mainboard143 = 0x0060008F, + Mainboard144 = 0x00600090, + Mainboard145 = 0x00600091, + Mainboard146 = 0x00600092, + Mainboard147 = 0x00600093, + Mainboard148 = 0x00600094, + Mainboard149 = 0x00600095, + Mainboard150 = 0x00600096, + Mainboard151 = 0x00600097, + Mainboard152 = 0x00600098, + Mainboard153 = 0x00600099, + Mainboard154 = 0x0060009A, + Mainboard155 = 0x0060009B, + Mainboard156 = 0x0060009C, + Mainboard157 = 0x0060009D, + Mainboard158 = 0x0060009E, + Mainboard159 = 0x0060009F, + Mainboard160 = 0x006000A0, + Mainboard161 = 0x006000A1, + Mainboard162 = 0x006000A2, + Mainboard163 = 0x006000A3, + Mainboard164 = 0x006000A4, + Mainboard165 = 0x006000A5, + Mainboard166 = 0x006000A6, + Mainboard167 = 0x006000A7, + Mainboard168 = 0x006000A8, + Mainboard169 = 0x006000A9, + Mainboard170 = 0x006000AA, + Mainboard171 = 0x006000AB, + Mainboard172 = 0x006000AC, + Mainboard173 = 0x006000AD, + Mainboard174 = 0x006000AE, + Mainboard175 = 0x006000AF, + Mainboard176 = 0x006000B0, + Mainboard177 = 0x006000B1, + Mainboard178 = 0x006000B2, + Mainboard179 = 0x006000B3, + Mainboard180 = 0x006000B4, + Mainboard181 = 0x006000B5, + Mainboard182 = 0x006000B6, + Mainboard183 = 0x006000B7, + Mainboard184 = 0x006000B8, + Mainboard185 = 0x006000B9, + Mainboard186 = 0x006000BA, + Mainboard187 = 0x006000BB, + Mainboard188 = 0x006000BC, + Mainboard189 = 0x006000BD, + Mainboard190 = 0x006000BE, + Mainboard191 = 0x006000BF, + Mainboard192 = 0x006000C0, + Mainboard193 = 0x006000C1, + Mainboard194 = 0x006000C2, + Mainboard195 = 0x006000C3, + Mainboard196 = 0x006000C4, + Mainboard197 = 0x006000C5, + Mainboard198 = 0x006000C6, + Mainboard199 = 0x006000C7, + Mainboard200 = 0x006000C8, + Mainboard201 = 0x006000C9, + Mainboard202 = 0x006000CA, + Mainboard203 = 0x006000CB, + Mainboard204 = 0x006000CC, + Mainboard205 = 0x006000CD, + Mainboard206 = 0x006000CE, + Mainboard207 = 0x006000CF, + Mainboard208 = 0x006000D0, + Mainboard209 = 0x006000D1, + Mainboard210 = 0x006000D2, + Mainboard211 = 0x006000D3, + Mainboard212 = 0x006000D4, + Mainboard213 = 0x006000D5, + Mainboard214 = 0x006000D6, + Mainboard215 = 0x006000D7, + Mainboard216 = 0x006000D8, + Mainboard217 = 0x006000D9, + Mainboard218 = 0x006000DA, + Mainboard219 = 0x006000DB, + Mainboard220 = 0x006000DC, + Mainboard221 = 0x006000DD, + Mainboard222 = 0x006000DE, + Mainboard223 = 0x006000DF, + Mainboard224 = 0x006000E0, + Mainboard225 = 0x006000E1, + Mainboard226 = 0x006000E2, + Mainboard227 = 0x006000E3, + Mainboard228 = 0x006000E4, + Mainboard229 = 0x006000E5, + Mainboard230 = 0x006000E6, + Mainboard231 = 0x006000E7, + Mainboard232 = 0x006000E8, + Mainboard233 = 0x006000E9, + Mainboard234 = 0x006000EA, + Mainboard235 = 0x006000EB, + Mainboard236 = 0x006000EC, + Mainboard237 = 0x006000ED, + Mainboard238 = 0x006000EE, + Mainboard239 = 0x006000EF, + Mainboard240 = 0x006000F0, + Mainboard241 = 0x006000F1, + Mainboard242 = 0x006000F2, + Mainboard243 = 0x006000F3, + Mainboard244 = 0x006000F4, + Mainboard245 = 0x006000F5, + Mainboard246 = 0x006000F6, + Mainboard247 = 0x006000F7, + Mainboard248 = 0x006000F8, + Mainboard249 = 0x006000F9, + Mainboard250 = 0x006000FA, + Mainboard251 = 0x006000FB, + Mainboard252 = 0x006000FC, + Mainboard253 = 0x006000FD, + Mainboard254 = 0x006000FE, + Mainboard255 = 0x006000FF, + Mainboard256 = 0x00600100, + Mainboard257 = 0x00600101, + Mainboard258 = 0x00600102, + Mainboard259 = 0x00600103, + Mainboard260 = 0x00600104, + Mainboard261 = 0x00600105, + Mainboard262 = 0x00600106, + Mainboard263 = 0x00600107, + Mainboard264 = 0x00600108, + Mainboard265 = 0x00600109, + Mainboard266 = 0x0060010A, + Mainboard267 = 0x0060010B, + Mainboard268 = 0x0060010C, + Mainboard269 = 0x0060010D, + Mainboard270 = 0x0060010E, + Mainboard271 = 0x0060010F, + Mainboard272 = 0x00600110, + Mainboard273 = 0x00600111, + Mainboard274 = 0x00600112, + Mainboard275 = 0x00600113, + Mainboard276 = 0x00600114, + Mainboard277 = 0x00600115, + Mainboard278 = 0x00600116, + Mainboard279 = 0x00600117, + Mainboard280 = 0x00600118, + Mainboard281 = 0x00600119, + Mainboard282 = 0x0060011A, + Mainboard283 = 0x0060011B, + Mainboard284 = 0x0060011C, + Mainboard285 = 0x0060011D, + Mainboard286 = 0x0060011E, + Mainboard287 = 0x0060011F, + Mainboard288 = 0x00600120, + Mainboard289 = 0x00600121, + Mainboard290 = 0x00600122, + Mainboard291 = 0x00600123, + Mainboard292 = 0x00600124, + Mainboard293 = 0x00600125, + Mainboard294 = 0x00600126, + Mainboard295 = 0x00600127, + Mainboard296 = 0x00600128, + Mainboard297 = 0x00600129, + Mainboard298 = 0x0060012A, + Mainboard299 = 0x0060012B, + Mainboard300 = 0x0060012C, + Mainboard301 = 0x0060012D, + Mainboard302 = 0x0060012E, + Mainboard303 = 0x0060012F, + Mainboard304 = 0x00600130, + Mainboard305 = 0x00600131, + Mainboard306 = 0x00600132, + Mainboard307 = 0x00600133, + Mainboard308 = 0x00600134, + Mainboard309 = 0x00600135, + Mainboard310 = 0x00600136, + Mainboard311 = 0x00600137, + Mainboard312 = 0x00600138, + Mainboard313 = 0x00600139, + Mainboard314 = 0x0060013A, + Mainboard315 = 0x0060013B, + Mainboard316 = 0x0060013C, + Mainboard317 = 0x0060013D, + Mainboard318 = 0x0060013E, + Mainboard319 = 0x0060013F, + Mainboard320 = 0x00600140, + Mainboard321 = 0x00600141, + Mainboard322 = 0x00600142, + Mainboard323 = 0x00600143, + Mainboard324 = 0x00600144, + Mainboard325 = 0x00600145, + Mainboard326 = 0x00600146, + Mainboard327 = 0x00600147, + Mainboard328 = 0x00600148, + Mainboard329 = 0x00600149, + Mainboard330 = 0x0060014A, + Mainboard331 = 0x0060014B, + Mainboard332 = 0x0060014C, + Mainboard333 = 0x0060014D, + Mainboard334 = 0x0060014E, + Mainboard335 = 0x0060014F, + Mainboard336 = 0x00600150, + Mainboard337 = 0x00600151, + Mainboard338 = 0x00600152, + Mainboard339 = 0x00600153, + Mainboard340 = 0x00600154, + Mainboard341 = 0x00600155, + Mainboard342 = 0x00600156, + Mainboard343 = 0x00600157, + Mainboard344 = 0x00600158, + Mainboard345 = 0x00600159, + Mainboard346 = 0x0060015A, + Mainboard347 = 0x0060015B, + Mainboard348 = 0x0060015C, + Mainboard349 = 0x0060015D, + Mainboard350 = 0x0060015E, + Mainboard351 = 0x0060015F, + Mainboard352 = 0x00600160, + Mainboard353 = 0x00600161, + Mainboard354 = 0x00600162, + Mainboard355 = 0x00600163, + Mainboard356 = 0x00600164, + Mainboard357 = 0x00600165, + Mainboard358 = 0x00600166, + Mainboard359 = 0x00600167, + Mainboard360 = 0x00600168, + Mainboard361 = 0x00600169, + Mainboard362 = 0x0060016A, + Mainboard363 = 0x0060016B, + Mainboard364 = 0x0060016C, + Mainboard365 = 0x0060016D, + Mainboard366 = 0x0060016E, + Mainboard367 = 0x0060016F, + Mainboard368 = 0x00600170, + Mainboard369 = 0x00600171, + Mainboard370 = 0x00600172, + Mainboard371 = 0x00600173, + Mainboard372 = 0x00600174, + Mainboard373 = 0x00600175, + Mainboard374 = 0x00600176, + Mainboard375 = 0x00600177, + Mainboard376 = 0x00600178, + Mainboard377 = 0x00600179, + Mainboard378 = 0x0060017A, + Mainboard379 = 0x0060017B, + Mainboard380 = 0x0060017C, + Mainboard381 = 0x0060017D, + Mainboard382 = 0x0060017E, + Mainboard383 = 0x0060017F, + Mainboard384 = 0x00600180, + Mainboard385 = 0x00600181, + Mainboard386 = 0x00600182, + Mainboard387 = 0x00600183, + Mainboard388 = 0x00600184, + Mainboard389 = 0x00600185, + Mainboard390 = 0x00600186, + Mainboard391 = 0x00600187, + Mainboard392 = 0x00600188, + Mainboard393 = 0x00600189, + Mainboard394 = 0x0060018A, + Mainboard395 = 0x0060018B, + Mainboard396 = 0x0060018C, + Mainboard397 = 0x0060018D, + Mainboard398 = 0x0060018E, + Mainboard399 = 0x0060018F, + Mainboard400 = 0x00600190, + Mainboard401 = 0x00600191, + Mainboard402 = 0x00600192, + Mainboard403 = 0x00600193, + Mainboard404 = 0x00600194, + Mainboard405 = 0x00600195, + Mainboard406 = 0x00600196, + Mainboard407 = 0x00600197, + Mainboard408 = 0x00600198, + Mainboard409 = 0x00600199, + Mainboard410 = 0x0060019A, + Mainboard411 = 0x0060019B, + Mainboard412 = 0x0060019C, + Mainboard413 = 0x0060019D, + Mainboard414 = 0x0060019E, + Mainboard415 = 0x0060019F, + Mainboard416 = 0x006001A0, + Mainboard417 = 0x006001A1, + Mainboard418 = 0x006001A2, + Mainboard419 = 0x006001A3, + Mainboard420 = 0x006001A4, + Mainboard421 = 0x006001A5, + Mainboard422 = 0x006001A6, + Mainboard423 = 0x006001A7, + Mainboard424 = 0x006001A8, + Mainboard425 = 0x006001A9, + Mainboard426 = 0x006001AA, + Mainboard427 = 0x006001AB, + Mainboard428 = 0x006001AC, + Mainboard429 = 0x006001AD, + Mainboard430 = 0x006001AE, + Mainboard431 = 0x006001AF, + Mainboard432 = 0x006001B0, + Mainboard433 = 0x006001B1, + Mainboard434 = 0x006001B2, + Mainboard435 = 0x006001B3, + Mainboard436 = 0x006001B4, + Mainboard437 = 0x006001B5, + Mainboard438 = 0x006001B6, + Mainboard439 = 0x006001B7, + Mainboard440 = 0x006001B8, + Mainboard441 = 0x006001B9, + Mainboard442 = 0x006001BA, + Mainboard443 = 0x006001BB, + Mainboard444 = 0x006001BC, + Mainboard445 = 0x006001BD, + Mainboard446 = 0x006001BE, + Mainboard447 = 0x006001BF, + Mainboard448 = 0x006001C0, + Mainboard449 = 0x006001C1, + Mainboard450 = 0x006001C2, + Mainboard451 = 0x006001C3, + Mainboard452 = 0x006001C4, + Mainboard453 = 0x006001C5, + Mainboard454 = 0x006001C6, + Mainboard455 = 0x006001C7, + Mainboard456 = 0x006001C8, + Mainboard457 = 0x006001C9, + Mainboard458 = 0x006001CA, + Mainboard459 = 0x006001CB, + Mainboard460 = 0x006001CC, + Mainboard461 = 0x006001CD, + Mainboard462 = 0x006001CE, + Mainboard463 = 0x006001CF, + Mainboard464 = 0x006001D0, + Mainboard465 = 0x006001D1, + Mainboard466 = 0x006001D2, + Mainboard467 = 0x006001D3, + Mainboard468 = 0x006001D4, + Mainboard469 = 0x006001D5, + Mainboard470 = 0x006001D6, + Mainboard471 = 0x006001D7, + Mainboard472 = 0x006001D8, + Mainboard473 = 0x006001D9, + Mainboard474 = 0x006001DA, + Mainboard475 = 0x006001DB, + Mainboard476 = 0x006001DC, + Mainboard477 = 0x006001DD, + Mainboard478 = 0x006001DE, + Mainboard479 = 0x006001DF, + Mainboard480 = 0x006001E0, + Mainboard481 = 0x006001E1, + Mainboard482 = 0x006001E2, + Mainboard483 = 0x006001E3, + Mainboard484 = 0x006001E4, + Mainboard485 = 0x006001E5, + Mainboard486 = 0x006001E6, + Mainboard487 = 0x006001E7, + Mainboard488 = 0x006001E8, + Mainboard489 = 0x006001E9, + Mainboard490 = 0x006001EA, + Mainboard491 = 0x006001EB, + Mainboard492 = 0x006001EC, + Mainboard493 = 0x006001ED, + Mainboard494 = 0x006001EE, + Mainboard495 = 0x006001EF, + Mainboard496 = 0x006001F0, + Mainboard497 = 0x006001F1, + Mainboard498 = 0x006001F2, + Mainboard499 = 0x006001F3, + Mainboard500 = 0x006001F4, + Mainboard501 = 0x006001F5, + Mainboard502 = 0x006001F6, + Mainboard503 = 0x006001F7, + Mainboard504 = 0x006001F8, + Mainboard505 = 0x006001F9, + Mainboard506 = 0x006001FA, + Mainboard507 = 0x006001FB, + Mainboard508 = 0x006001FC, + Mainboard509 = 0x006001FD, + Mainboard510 = 0x006001FE, + Mainboard511 = 0x006001FF, + Mainboard512 = 0x00600200, - /*### Mainboard ###*/ - Mainboard1 = 0x00600001, - Mainboard2 = 0x00600002, - Mainboard3 = 0x00600003, - Mainboard4 = 0x00600004, - Mainboard5 = 0x00600005, - Mainboard6 = 0x00600006, - Mainboard7 = 0x00600007, - Mainboard8 = 0x00600008, - Mainboard9 = 0x00600009, - Mainboard10 = 0x0060000A, - Mainboard11 = 0x0060000B, - Mainboard12 = 0x0060000C, - Mainboard13 = 0x0060000D, - Mainboard14 = 0x0060000E, - Mainboard15 = 0x0060000F, - Mainboard16 = 0x00600010, - Mainboard17 = 0x00600011, - Mainboard18 = 0x00600012, - Mainboard19 = 0x00600013, - Mainboard20 = 0x00600014, - Mainboard21 = 0x00600015, - Mainboard22 = 0x00600016, - Mainboard23 = 0x00600017, - Mainboard24 = 0x00600018, - Mainboard25 = 0x00600019, - Mainboard26 = 0x0060001A, - Mainboard27 = 0x0060001B, - Mainboard28 = 0x0060001C, - Mainboard29 = 0x0060001D, - Mainboard30 = 0x0060001E, - Mainboard31 = 0x0060001F, - Mainboard32 = 0x00600020, - Mainboard33 = 0x00600021, - Mainboard34 = 0x00600022, - Mainboard35 = 0x00600023, - Mainboard36 = 0x00600024, - Mainboard37 = 0x00600025, - Mainboard38 = 0x00600026, - Mainboard39 = 0x00600027, - Mainboard40 = 0x00600028, - Mainboard41 = 0x00600029, - Mainboard42 = 0x0060002A, - Mainboard43 = 0x0060002B, - Mainboard44 = 0x0060002C, - Mainboard45 = 0x0060002D, - Mainboard46 = 0x0060002E, - Mainboard47 = 0x0060002F, - Mainboard48 = 0x00600030, - Mainboard49 = 0x00600031, - Mainboard50 = 0x00600032, - Mainboard51 = 0x00600033, - Mainboard52 = 0x00600034, - Mainboard53 = 0x00600035, - Mainboard54 = 0x00600036, - Mainboard55 = 0x00600037, - Mainboard56 = 0x00600038, - Mainboard57 = 0x00600039, - Mainboard58 = 0x0060003A, - Mainboard59 = 0x0060003B, - Mainboard60 = 0x0060003C, - Mainboard61 = 0x0060003D, - Mainboard62 = 0x0060003E, - Mainboard63 = 0x0060003F, - Mainboard64 = 0x00600040, + /*### GraphicsCard ###*/ + GraphicsCard1 = 0x00700001, + GraphicsCard2 = 0x00700002, + GraphicsCard3 = 0x00700003, + GraphicsCard4 = 0x00700004, + GraphicsCard5 = 0x00700005, + GraphicsCard6 = 0x00700006, + GraphicsCard7 = 0x00700007, + GraphicsCard8 = 0x00700008, + GraphicsCard9 = 0x00700009, + GraphicsCard10 = 0x0070000A, + GraphicsCard11 = 0x0070000B, + GraphicsCard12 = 0x0070000C, + GraphicsCard13 = 0x0070000D, + GraphicsCard14 = 0x0070000E, + GraphicsCard15 = 0x0070000F, + GraphicsCard16 = 0x00700010, + GraphicsCard17 = 0x00700011, + GraphicsCard18 = 0x00700012, + GraphicsCard19 = 0x00700013, + GraphicsCard20 = 0x00700014, + GraphicsCard21 = 0x00700015, + GraphicsCard22 = 0x00700016, + GraphicsCard23 = 0x00700017, + GraphicsCard24 = 0x00700018, + GraphicsCard25 = 0x00700019, + GraphicsCard26 = 0x0070001A, + GraphicsCard27 = 0x0070001B, + GraphicsCard28 = 0x0070001C, + GraphicsCard29 = 0x0070001D, + GraphicsCard30 = 0x0070001E, + GraphicsCard31 = 0x0070001F, + GraphicsCard32 = 0x00700020, + GraphicsCard33 = 0x00700021, + GraphicsCard34 = 0x00700022, + GraphicsCard35 = 0x00700023, + GraphicsCard36 = 0x00700024, + GraphicsCard37 = 0x00700025, + GraphicsCard38 = 0x00700026, + GraphicsCard39 = 0x00700027, + GraphicsCard40 = 0x00700028, + GraphicsCard41 = 0x00700029, + GraphicsCard42 = 0x0070002A, + GraphicsCard43 = 0x0070002B, + GraphicsCard44 = 0x0070002C, + GraphicsCard45 = 0x0070002D, + GraphicsCard46 = 0x0070002E, + GraphicsCard47 = 0x0070002F, + GraphicsCard48 = 0x00700030, + GraphicsCard49 = 0x00700031, + GraphicsCard50 = 0x00700032, + GraphicsCard51 = 0x00700033, + GraphicsCard52 = 0x00700034, + GraphicsCard53 = 0x00700035, + GraphicsCard54 = 0x00700036, + GraphicsCard55 = 0x00700037, + GraphicsCard56 = 0x00700038, + GraphicsCard57 = 0x00700039, + GraphicsCard58 = 0x0070003A, + GraphicsCard59 = 0x0070003B, + GraphicsCard60 = 0x0070003C, + GraphicsCard61 = 0x0070003D, + GraphicsCard62 = 0x0070003E, + GraphicsCard63 = 0x0070003F, + GraphicsCard64 = 0x00700040, + GraphicsCard65 = 0x00700041, + GraphicsCard66 = 0x00700042, + GraphicsCard67 = 0x00700043, + GraphicsCard68 = 0x00700044, + GraphicsCard69 = 0x00700045, + GraphicsCard70 = 0x00700046, + GraphicsCard71 = 0x00700047, + GraphicsCard72 = 0x00700048, + GraphicsCard73 = 0x00700049, + GraphicsCard74 = 0x0070004A, + GraphicsCard75 = 0x0070004B, + GraphicsCard76 = 0x0070004C, + GraphicsCard77 = 0x0070004D, + GraphicsCard78 = 0x0070004E, + GraphicsCard79 = 0x0070004F, + GraphicsCard80 = 0x00700050, + GraphicsCard81 = 0x00700051, + GraphicsCard82 = 0x00700052, + GraphicsCard83 = 0x00700053, + GraphicsCard84 = 0x00700054, + GraphicsCard85 = 0x00700055, + GraphicsCard86 = 0x00700056, + GraphicsCard87 = 0x00700057, + GraphicsCard88 = 0x00700058, + GraphicsCard89 = 0x00700059, + GraphicsCard90 = 0x0070005A, + GraphicsCard91 = 0x0070005B, + GraphicsCard92 = 0x0070005C, + GraphicsCard93 = 0x0070005D, + GraphicsCard94 = 0x0070005E, + GraphicsCard95 = 0x0070005F, + GraphicsCard96 = 0x00700060, + GraphicsCard97 = 0x00700061, + GraphicsCard98 = 0x00700062, + GraphicsCard99 = 0x00700063, + GraphicsCard100 = 0x00700064, + GraphicsCard101 = 0x00700065, + GraphicsCard102 = 0x00700066, + GraphicsCard103 = 0x00700067, + GraphicsCard104 = 0x00700068, + GraphicsCard105 = 0x00700069, + GraphicsCard106 = 0x0070006A, + GraphicsCard107 = 0x0070006B, + GraphicsCard108 = 0x0070006C, + GraphicsCard109 = 0x0070006D, + GraphicsCard110 = 0x0070006E, + GraphicsCard111 = 0x0070006F, + GraphicsCard112 = 0x00700070, + GraphicsCard113 = 0x00700071, + GraphicsCard114 = 0x00700072, + GraphicsCard115 = 0x00700073, + GraphicsCard116 = 0x00700074, + GraphicsCard117 = 0x00700075, + GraphicsCard118 = 0x00700076, + GraphicsCard119 = 0x00700077, + GraphicsCard120 = 0x00700078, + GraphicsCard121 = 0x00700079, + GraphicsCard122 = 0x0070007A, + GraphicsCard123 = 0x0070007B, + GraphicsCard124 = 0x0070007C, + GraphicsCard125 = 0x0070007D, + GraphicsCard126 = 0x0070007E, + GraphicsCard127 = 0x0070007F, + GraphicsCard128 = 0x00700080, - /*### GraphicsCard ###*/ - GraphicsCard1 = 0x00700001, - GraphicsCard2 = 0x00700002, - GraphicsCard3 = 0x00700003, - GraphicsCard4 = 0x00700004, - GraphicsCard5 = 0x00700005, - GraphicsCard6 = 0x00700006, - GraphicsCard7 = 0x00700007, - GraphicsCard8 = 0x00700008, - GraphicsCard9 = 0x00700009, - GraphicsCard10 = 0x0070000A, - GraphicsCard11 = 0x0070000B, - GraphicsCard12 = 0x0070000C, - GraphicsCard13 = 0x0070000D, - GraphicsCard14 = 0x0070000E, - GraphicsCard15 = 0x0070000F, - GraphicsCard16 = 0x00700010, - GraphicsCard17 = 0x00700011, - GraphicsCard18 = 0x00700012, - GraphicsCard19 = 0x00700013, - GraphicsCard20 = 0x00700014, - GraphicsCard21 = 0x00700015, - GraphicsCard22 = 0x00700016, - GraphicsCard23 = 0x00700017, - GraphicsCard24 = 0x00700018, - GraphicsCard25 = 0x00700019, - GraphicsCard26 = 0x0070001A, - GraphicsCard27 = 0x0070001B, - GraphicsCard28 = 0x0070001C, - GraphicsCard29 = 0x0070001D, - GraphicsCard30 = 0x0070001E, - GraphicsCard31 = 0x0070001F, - GraphicsCard32 = 0x00700020, - GraphicsCard33 = 0x00700021, - GraphicsCard34 = 0x00700022, - GraphicsCard35 = 0x00700023, - GraphicsCard36 = 0x00700024, - GraphicsCard37 = 0x00700025, - GraphicsCard38 = 0x00700026, - GraphicsCard39 = 0x00700027, - GraphicsCard40 = 0x00700028, - GraphicsCard41 = 0x00700029, - GraphicsCard42 = 0x0070002A, - GraphicsCard43 = 0x0070002B, - GraphicsCard44 = 0x0070002C, - GraphicsCard45 = 0x0070002D, - GraphicsCard46 = 0x0070002E, - GraphicsCard47 = 0x0070002F, - GraphicsCard48 = 0x00700030, - GraphicsCard49 = 0x00700031, - GraphicsCard50 = 0x00700032, - GraphicsCard51 = 0x00700033, - GraphicsCard52 = 0x00700034, - GraphicsCard53 = 0x00700035, - GraphicsCard54 = 0x00700036, - GraphicsCard55 = 0x00700037, - GraphicsCard56 = 0x00700038, - GraphicsCard57 = 0x00700039, - GraphicsCard58 = 0x0070003A, - GraphicsCard59 = 0x0070003B, - GraphicsCard60 = 0x0070003C, - GraphicsCard61 = 0x0070003D, - GraphicsCard62 = 0x0070003E, - GraphicsCard63 = 0x0070003F, - GraphicsCard64 = 0x00700040, + /*### DRAM ###*/ + DRAM1 = 0x00800001, + DRAM2 = 0x00800002, + DRAM3 = 0x00800003, + DRAM4 = 0x00800004, + DRAM5 = 0x00800005, + DRAM6 = 0x00800006, + DRAM7 = 0x00800007, + DRAM8 = 0x00800008, + DRAM9 = 0x00800009, + DRAM10 = 0x0080000A, + DRAM11 = 0x0080000B, + DRAM12 = 0x0080000C, + DRAM13 = 0x0080000D, + DRAM14 = 0x0080000E, + DRAM15 = 0x0080000F, + DRAM16 = 0x00800010, + DRAM17 = 0x00800011, + DRAM18 = 0x00800012, + DRAM19 = 0x00800013, + DRAM20 = 0x00800014, + DRAM21 = 0x00800015, + DRAM22 = 0x00800016, + DRAM23 = 0x00800017, + DRAM24 = 0x00800018, + DRAM25 = 0x00800019, + DRAM26 = 0x0080001A, + DRAM27 = 0x0080001B, + DRAM28 = 0x0080001C, + DRAM29 = 0x0080001D, + DRAM30 = 0x0080001E, + DRAM31 = 0x0080001F, + DRAM32 = 0x00800020, + DRAM33 = 0x00800021, + DRAM34 = 0x00800022, + DRAM35 = 0x00800023, + DRAM36 = 0x00800024, + DRAM37 = 0x00800025, + DRAM38 = 0x00800026, + DRAM39 = 0x00800027, + DRAM40 = 0x00800028, + DRAM41 = 0x00800029, + DRAM42 = 0x0080002A, + DRAM43 = 0x0080002B, + DRAM44 = 0x0080002C, + DRAM45 = 0x0080002D, + DRAM46 = 0x0080002E, + DRAM47 = 0x0080002F, + DRAM48 = 0x00800030, + DRAM49 = 0x00800031, + DRAM50 = 0x00800032, + DRAM51 = 0x00800033, + DRAM52 = 0x00800034, + DRAM53 = 0x00800035, + DRAM54 = 0x00800036, + DRAM55 = 0x00800037, + DRAM56 = 0x00800038, + DRAM57 = 0x00800039, + DRAM58 = 0x0080003A, + DRAM59 = 0x0080003B, + DRAM60 = 0x0080003C, + DRAM61 = 0x0080003D, + DRAM62 = 0x0080003E, + DRAM63 = 0x0080003F, + DRAM64 = 0x00800040, + DRAM65 = 0x00800041, + DRAM66 = 0x00800042, + DRAM67 = 0x00800043, + DRAM68 = 0x00800044, + DRAM69 = 0x00800045, + DRAM70 = 0x00800046, + DRAM71 = 0x00800047, + DRAM72 = 0x00800048, + DRAM73 = 0x00800049, + DRAM74 = 0x0080004A, + DRAM75 = 0x0080004B, + DRAM76 = 0x0080004C, + DRAM77 = 0x0080004D, + DRAM78 = 0x0080004E, + DRAM79 = 0x0080004F, + DRAM80 = 0x00800050, + DRAM81 = 0x00800051, + DRAM82 = 0x00800052, + DRAM83 = 0x00800053, + DRAM84 = 0x00800054, + DRAM85 = 0x00800055, + DRAM86 = 0x00800056, + DRAM87 = 0x00800057, + DRAM88 = 0x00800058, + DRAM89 = 0x00800059, + DRAM90 = 0x0080005A, + DRAM91 = 0x0080005B, + DRAM92 = 0x0080005C, + DRAM93 = 0x0080005D, + DRAM94 = 0x0080005E, + DRAM95 = 0x0080005F, + DRAM96 = 0x00800060, + DRAM97 = 0x00800061, + DRAM98 = 0x00800062, + DRAM99 = 0x00800063, + DRAM100 = 0x00800064, + DRAM101 = 0x00800065, + DRAM102 = 0x00800066, + DRAM103 = 0x00800067, + DRAM104 = 0x00800068, + DRAM105 = 0x00800069, + DRAM106 = 0x0080006A, + DRAM107 = 0x0080006B, + DRAM108 = 0x0080006C, + DRAM109 = 0x0080006D, + DRAM110 = 0x0080006E, + DRAM111 = 0x0080006F, + DRAM112 = 0x00800070, + DRAM113 = 0x00800071, + DRAM114 = 0x00800072, + DRAM115 = 0x00800073, + DRAM116 = 0x00800074, + DRAM117 = 0x00800075, + DRAM118 = 0x00800076, + DRAM119 = 0x00800077, + DRAM120 = 0x00800078, + DRAM121 = 0x00800079, + DRAM122 = 0x0080007A, + DRAM123 = 0x0080007B, + DRAM124 = 0x0080007C, + DRAM125 = 0x0080007D, + DRAM126 = 0x0080007E, + DRAM127 = 0x0080007F, + DRAM128 = 0x00800080, - /*### DRAM ###*/ - DRAM1 = 0x00800001, - DRAM2 = 0x00800002, - DRAM3 = 0x00800003, - DRAM4 = 0x00800004, - DRAM5 = 0x00800005, - DRAM6 = 0x00800006, - DRAM7 = 0x00800007, - DRAM8 = 0x00800008, - DRAM9 = 0x00800009, - DRAM10 = 0x0080000A, - DRAM11 = 0x0080000B, - DRAM12 = 0x0080000C, - DRAM13 = 0x0080000D, - DRAM14 = 0x0080000E, - DRAM15 = 0x0080000F, - DRAM16 = 0x00800010, - DRAM17 = 0x00800011, - DRAM18 = 0x00800012, - DRAM19 = 0x00800013, - DRAM20 = 0x00800014, - DRAM21 = 0x00800015, - DRAM22 = 0x00800016, - DRAM23 = 0x00800017, - DRAM24 = 0x00800018, - DRAM25 = 0x00800019, - DRAM26 = 0x0080001A, - DRAM27 = 0x0080001B, - DRAM28 = 0x0080001C, - DRAM29 = 0x0080001D, - DRAM30 = 0x0080001E, - DRAM31 = 0x0080001F, - DRAM32 = 0x00800020, - DRAM33 = 0x00800021, - DRAM34 = 0x00800022, - DRAM35 = 0x00800023, - DRAM36 = 0x00800024, - DRAM37 = 0x00800025, - DRAM38 = 0x00800026, - DRAM39 = 0x00800027, - DRAM40 = 0x00800028, - DRAM41 = 0x00800029, - DRAM42 = 0x0080002A, - DRAM43 = 0x0080002B, - DRAM44 = 0x0080002C, - DRAM45 = 0x0080002D, - DRAM46 = 0x0080002E, - DRAM47 = 0x0080002F, - DRAM48 = 0x00800030, - DRAM49 = 0x00800031, - DRAM50 = 0x00800032, - DRAM51 = 0x00800033, - DRAM52 = 0x00800034, - DRAM53 = 0x00800035, - DRAM54 = 0x00800036, - DRAM55 = 0x00800037, - DRAM56 = 0x00800038, - DRAM57 = 0x00800039, - DRAM58 = 0x0080003A, - DRAM59 = 0x0080003B, - DRAM60 = 0x0080003C, - DRAM61 = 0x0080003D, - DRAM62 = 0x0080003E, - DRAM63 = 0x0080003F, - DRAM64 = 0x00800040, + /*### HeadsetStand ###*/ + HeadsetStand1 = 0x00900001, + HeadsetStand2 = 0x00900002, + HeadsetStand3 = 0x00900003, + HeadsetStand4 = 0x00900004, + HeadsetStand5 = 0x00900005, + HeadsetStand6 = 0x00900006, + HeadsetStand7 = 0x00900007, + HeadsetStand8 = 0x00900008, + HeadsetStand9 = 0x00900009, + HeadsetStand10 = 0x0090000A, + HeadsetStand11 = 0x0090000B, + HeadsetStand12 = 0x0090000C, + HeadsetStand13 = 0x0090000D, + HeadsetStand14 = 0x0090000E, + HeadsetStand15 = 0x0090000F, + HeadsetStand16 = 0x00900010, + HeadsetStand17 = 0x00900011, + HeadsetStand18 = 0x00900012, + HeadsetStand19 = 0x00900013, + HeadsetStand20 = 0x00900014, + HeadsetStand21 = 0x00900015, + HeadsetStand22 = 0x00900016, + HeadsetStand23 = 0x00900017, + HeadsetStand24 = 0x00900018, + HeadsetStand25 = 0x00900019, + HeadsetStand26 = 0x0090001A, + HeadsetStand27 = 0x0090001B, + HeadsetStand28 = 0x0090001C, + HeadsetStand29 = 0x0090001D, + HeadsetStand30 = 0x0090001E, + HeadsetStand31 = 0x0090001F, + HeadsetStand32 = 0x00900020, + HeadsetStand33 = 0x00900021, + HeadsetStand34 = 0x00900022, + HeadsetStand35 = 0x00900023, + HeadsetStand36 = 0x00900024, + HeadsetStand37 = 0x00900025, + HeadsetStand38 = 0x00900026, + HeadsetStand39 = 0x00900027, + HeadsetStand40 = 0x00900028, + HeadsetStand41 = 0x00900029, + HeadsetStand42 = 0x0090002A, + HeadsetStand43 = 0x0090002B, + HeadsetStand44 = 0x0090002C, + HeadsetStand45 = 0x0090002D, + HeadsetStand46 = 0x0090002E, + HeadsetStand47 = 0x0090002F, + HeadsetStand48 = 0x00900030, + HeadsetStand49 = 0x00900031, + HeadsetStand50 = 0x00900032, + HeadsetStand51 = 0x00900033, + HeadsetStand52 = 0x00900034, + HeadsetStand53 = 0x00900035, + HeadsetStand54 = 0x00900036, + HeadsetStand55 = 0x00900037, + HeadsetStand56 = 0x00900038, + HeadsetStand57 = 0x00900039, + HeadsetStand58 = 0x0090003A, + HeadsetStand59 = 0x0090003B, + HeadsetStand60 = 0x0090003C, + HeadsetStand61 = 0x0090003D, + HeadsetStand62 = 0x0090003E, + HeadsetStand63 = 0x0090003F, + HeadsetStand64 = 0x00900040, + HeadsetStand65 = 0x00900041, + HeadsetStand66 = 0x00900042, + HeadsetStand67 = 0x00900043, + HeadsetStand68 = 0x00900044, + HeadsetStand69 = 0x00900045, + HeadsetStand70 = 0x00900046, + HeadsetStand71 = 0x00900047, + HeadsetStand72 = 0x00900048, + HeadsetStand73 = 0x00900049, + HeadsetStand74 = 0x0090004A, + HeadsetStand75 = 0x0090004B, + HeadsetStand76 = 0x0090004C, + HeadsetStand77 = 0x0090004D, + HeadsetStand78 = 0x0090004E, + HeadsetStand79 = 0x0090004F, + HeadsetStand80 = 0x00900050, + HeadsetStand81 = 0x00900051, + HeadsetStand82 = 0x00900052, + HeadsetStand83 = 0x00900053, + HeadsetStand84 = 0x00900054, + HeadsetStand85 = 0x00900055, + HeadsetStand86 = 0x00900056, + HeadsetStand87 = 0x00900057, + HeadsetStand88 = 0x00900058, + HeadsetStand89 = 0x00900059, + HeadsetStand90 = 0x0090005A, + HeadsetStand91 = 0x0090005B, + HeadsetStand92 = 0x0090005C, + HeadsetStand93 = 0x0090005D, + HeadsetStand94 = 0x0090005E, + HeadsetStand95 = 0x0090005F, + HeadsetStand96 = 0x00900060, + HeadsetStand97 = 0x00900061, + HeadsetStand98 = 0x00900062, + HeadsetStand99 = 0x00900063, + HeadsetStand100 = 0x00900064, + HeadsetStand101 = 0x00900065, + HeadsetStand102 = 0x00900066, + HeadsetStand103 = 0x00900067, + HeadsetStand104 = 0x00900068, + HeadsetStand105 = 0x00900069, + HeadsetStand106 = 0x0090006A, + HeadsetStand107 = 0x0090006B, + HeadsetStand108 = 0x0090006C, + HeadsetStand109 = 0x0090006D, + HeadsetStand110 = 0x0090006E, + HeadsetStand111 = 0x0090006F, + HeadsetStand112 = 0x00900070, + HeadsetStand113 = 0x00900071, + HeadsetStand114 = 0x00900072, + HeadsetStand115 = 0x00900073, + HeadsetStand116 = 0x00900074, + HeadsetStand117 = 0x00900075, + HeadsetStand118 = 0x00900076, + HeadsetStand119 = 0x00900077, + HeadsetStand120 = 0x00900078, + HeadsetStand121 = 0x00900079, + HeadsetStand122 = 0x0090007A, + HeadsetStand123 = 0x0090007B, + HeadsetStand124 = 0x0090007C, + HeadsetStand125 = 0x0090007D, + HeadsetStand126 = 0x0090007E, + HeadsetStand127 = 0x0090007F, + HeadsetStand128 = 0x00900080, - /*### HeadsetStand ###*/ - HeadsetStand1 = 0x00900001, - HeadsetStand2 = 0x00900002, - HeadsetStand3 = 0x00900003, - HeadsetStand4 = 0x00900004, - HeadsetStand5 = 0x00900005, - HeadsetStand6 = 0x00900006, - HeadsetStand7 = 0x00900007, - HeadsetStand8 = 0x00900008, - HeadsetStand9 = 0x00900009, - HeadsetStand10 = 0x0090000A, - HeadsetStand11 = 0x0090000B, - HeadsetStand12 = 0x0090000C, - HeadsetStand13 = 0x0090000D, - HeadsetStand14 = 0x0090000E, - HeadsetStand15 = 0x0090000F, - HeadsetStand16 = 0x00900010, - HeadsetStand17 = 0x00900011, - HeadsetStand18 = 0x00900012, - HeadsetStand19 = 0x00900013, - HeadsetStand20 = 0x00900014, - HeadsetStand21 = 0x00900015, - HeadsetStand22 = 0x00900016, - HeadsetStand23 = 0x00900017, - HeadsetStand24 = 0x00900018, - HeadsetStand25 = 0x00900019, - HeadsetStand26 = 0x0090001A, - HeadsetStand27 = 0x0090001B, - HeadsetStand28 = 0x0090001C, - HeadsetStand29 = 0x0090001D, - HeadsetStand30 = 0x0090001E, - HeadsetStand31 = 0x0090001F, - HeadsetStand32 = 0x00900020, - HeadsetStand33 = 0x00900021, - HeadsetStand34 = 0x00900022, - HeadsetStand35 = 0x00900023, - HeadsetStand36 = 0x00900024, - HeadsetStand37 = 0x00900025, - HeadsetStand38 = 0x00900026, - HeadsetStand39 = 0x00900027, - HeadsetStand40 = 0x00900028, - HeadsetStand41 = 0x00900029, - HeadsetStand42 = 0x0090002A, - HeadsetStand43 = 0x0090002B, - HeadsetStand44 = 0x0090002C, - HeadsetStand45 = 0x0090002D, - HeadsetStand46 = 0x0090002E, - HeadsetStand47 = 0x0090002F, - HeadsetStand48 = 0x00900030, - HeadsetStand49 = 0x00900031, - HeadsetStand50 = 0x00900032, - HeadsetStand51 = 0x00900033, - HeadsetStand52 = 0x00900034, - HeadsetStand53 = 0x00900035, - HeadsetStand54 = 0x00900036, - HeadsetStand55 = 0x00900037, - HeadsetStand56 = 0x00900038, - HeadsetStand57 = 0x00900039, - HeadsetStand58 = 0x0090003A, - HeadsetStand59 = 0x0090003B, - HeadsetStand60 = 0x0090003C, - HeadsetStand61 = 0x0090003D, - HeadsetStand62 = 0x0090003E, - HeadsetStand63 = 0x0090003F, - HeadsetStand64 = 0x00900040, + /*### Keypad ###*/ + Keypad1 = 0x00A00001, + Keypad2 = 0x00A00002, + Keypad3 = 0x00A00003, + Keypad4 = 0x00A00004, + Keypad5 = 0x00A00005, + Keypad6 = 0x00A00006, + Keypad7 = 0x00A00007, + Keypad8 = 0x00A00008, + Keypad9 = 0x00A00009, + Keypad10 = 0x00A0000A, + Keypad11 = 0x00A0000B, + Keypad12 = 0x00A0000C, + Keypad13 = 0x00A0000D, + Keypad14 = 0x00A0000E, + Keypad15 = 0x00A0000F, + Keypad16 = 0x00A00010, + Keypad17 = 0x00A00011, + Keypad18 = 0x00A00012, + Keypad19 = 0x00A00013, + Keypad20 = 0x00A00014, + Keypad21 = 0x00A00015, + Keypad22 = 0x00A00016, + Keypad23 = 0x00A00017, + Keypad24 = 0x00A00018, + Keypad25 = 0x00A00019, + Keypad26 = 0x00A0001A, + Keypad27 = 0x00A0001B, + Keypad28 = 0x00A0001C, + Keypad29 = 0x00A0001D, + Keypad30 = 0x00A0001E, + Keypad31 = 0x00A0001F, + Keypad32 = 0x00A00020, + Keypad33 = 0x00A00021, + Keypad34 = 0x00A00022, + Keypad35 = 0x00A00023, + Keypad36 = 0x00A00024, + Keypad37 = 0x00A00025, + Keypad38 = 0x00A00026, + Keypad39 = 0x00A00027, + Keypad40 = 0x00A00028, + Keypad41 = 0x00A00029, + Keypad42 = 0x00A0002A, + Keypad43 = 0x00A0002B, + Keypad44 = 0x00A0002C, + Keypad45 = 0x00A0002D, + Keypad46 = 0x00A0002E, + Keypad47 = 0x00A0002F, + Keypad48 = 0x00A00030, + Keypad49 = 0x00A00031, + Keypad50 = 0x00A00032, + Keypad51 = 0x00A00033, + Keypad52 = 0x00A00034, + Keypad53 = 0x00A00035, + Keypad54 = 0x00A00036, + Keypad55 = 0x00A00037, + Keypad56 = 0x00A00038, + Keypad57 = 0x00A00039, + Keypad58 = 0x00A0003A, + Keypad59 = 0x00A0003B, + Keypad60 = 0x00A0003C, + Keypad61 = 0x00A0003D, + Keypad62 = 0x00A0003E, + Keypad63 = 0x00A0003F, + Keypad64 = 0x00A00040, + Keypad65 = 0x00A00041, + Keypad66 = 0x00A00042, + Keypad67 = 0x00A00043, + Keypad68 = 0x00A00044, + Keypad69 = 0x00A00045, + Keypad70 = 0x00A00046, + Keypad71 = 0x00A00047, + Keypad72 = 0x00A00048, + Keypad73 = 0x00A00049, + Keypad74 = 0x00A0004A, + Keypad75 = 0x00A0004B, + Keypad76 = 0x00A0004C, + Keypad77 = 0x00A0004D, + Keypad78 = 0x00A0004E, + Keypad79 = 0x00A0004F, + Keypad80 = 0x00A00050, + Keypad81 = 0x00A00051, + Keypad82 = 0x00A00052, + Keypad83 = 0x00A00053, + Keypad84 = 0x00A00054, + Keypad85 = 0x00A00055, + Keypad86 = 0x00A00056, + Keypad87 = 0x00A00057, + Keypad88 = 0x00A00058, + Keypad89 = 0x00A00059, + Keypad90 = 0x00A0005A, + Keypad91 = 0x00A0005B, + Keypad92 = 0x00A0005C, + Keypad93 = 0x00A0005D, + Keypad94 = 0x00A0005E, + Keypad95 = 0x00A0005F, + Keypad96 = 0x00A00060, + Keypad97 = 0x00A00061, + Keypad98 = 0x00A00062, + Keypad99 = 0x00A00063, + Keypad100 = 0x00A00064, + Keypad101 = 0x00A00065, + Keypad102 = 0x00A00066, + Keypad103 = 0x00A00067, + Keypad104 = 0x00A00068, + Keypad105 = 0x00A00069, + Keypad106 = 0x00A0006A, + Keypad107 = 0x00A0006B, + Keypad108 = 0x00A0006C, + Keypad109 = 0x00A0006D, + Keypad110 = 0x00A0006E, + Keypad111 = 0x00A0006F, + Keypad112 = 0x00A00070, + Keypad113 = 0x00A00071, + Keypad114 = 0x00A00072, + Keypad115 = 0x00A00073, + Keypad116 = 0x00A00074, + Keypad117 = 0x00A00075, + Keypad118 = 0x00A00076, + Keypad119 = 0x00A00077, + Keypad120 = 0x00A00078, + Keypad121 = 0x00A00079, + Keypad122 = 0x00A0007A, + Keypad123 = 0x00A0007B, + Keypad124 = 0x00A0007C, + Keypad125 = 0x00A0007D, + Keypad126 = 0x00A0007E, + Keypad127 = 0x00A0007F, + Keypad128 = 0x00A00080, - /*### Keypad ###*/ - Keypad1 = 0x00A00001, - Keypad2 = 0x00A00002, - Keypad3 = 0x00A00003, - Keypad4 = 0x00A00004, - Keypad5 = 0x00A00005, - Keypad6 = 0x00A00006, - Keypad7 = 0x00A00007, - Keypad8 = 0x00A00008, - Keypad9 = 0x00A00009, - Keypad10 = 0x00A0000A, - Keypad11 = 0x00A0000B, - Keypad12 = 0x00A0000C, - Keypad13 = 0x00A0000D, - Keypad14 = 0x00A0000E, - Keypad15 = 0x00A0000F, - Keypad16 = 0x00A00010, - Keypad17 = 0x00A00011, - Keypad18 = 0x00A00012, - Keypad19 = 0x00A00013, - Keypad20 = 0x00A00014, - Keypad21 = 0x00A00015, - Keypad22 = 0x00A00016, - Keypad23 = 0x00A00017, - Keypad24 = 0x00A00018, - Keypad25 = 0x00A00019, - Keypad26 = 0x00A0001A, - Keypad27 = 0x00A0001B, - Keypad28 = 0x00A0001C, - Keypad29 = 0x00A0001D, - Keypad30 = 0x00A0001E, - Keypad31 = 0x00A0001F, - Keypad32 = 0x00A00020, - Keypad33 = 0x00A00021, - Keypad34 = 0x00A00022, - Keypad35 = 0x00A00023, - Keypad36 = 0x00A00024, - Keypad37 = 0x00A00025, - Keypad38 = 0x00A00026, - Keypad39 = 0x00A00027, - Keypad40 = 0x00A00028, - Keypad41 = 0x00A00029, - Keypad42 = 0x00A0002A, - Keypad43 = 0x00A0002B, - Keypad44 = 0x00A0002C, - Keypad45 = 0x00A0002D, - Keypad46 = 0x00A0002E, - Keypad47 = 0x00A0002F, - Keypad48 = 0x00A00030, - Keypad49 = 0x00A00031, - Keypad50 = 0x00A00032, - Keypad51 = 0x00A00033, - Keypad52 = 0x00A00034, - Keypad53 = 0x00A00035, - Keypad54 = 0x00A00036, - Keypad55 = 0x00A00037, - Keypad56 = 0x00A00038, - Keypad57 = 0x00A00039, - Keypad58 = 0x00A0003A, - Keypad59 = 0x00A0003B, - Keypad60 = 0x00A0003C, - Keypad61 = 0x00A0003D, - Keypad62 = 0x00A0003E, - Keypad63 = 0x00A0003F, - Keypad64 = 0x00A00040, + /*### Fan ###*/ + Fan1 = 0x00B00001, + Fan2 = 0x00B00002, + Fan3 = 0x00B00003, + Fan4 = 0x00B00004, + Fan5 = 0x00B00005, + Fan6 = 0x00B00006, + Fan7 = 0x00B00007, + Fan8 = 0x00B00008, + Fan9 = 0x00B00009, + Fan10 = 0x00B0000A, + Fan11 = 0x00B0000B, + Fan12 = 0x00B0000C, + Fan13 = 0x00B0000D, + Fan14 = 0x00B0000E, + Fan15 = 0x00B0000F, + Fan16 = 0x00B00010, + Fan17 = 0x00B00011, + Fan18 = 0x00B00012, + Fan19 = 0x00B00013, + Fan20 = 0x00B00014, + Fan21 = 0x00B00015, + Fan22 = 0x00B00016, + Fan23 = 0x00B00017, + Fan24 = 0x00B00018, + Fan25 = 0x00B00019, + Fan26 = 0x00B0001A, + Fan27 = 0x00B0001B, + Fan28 = 0x00B0001C, + Fan29 = 0x00B0001D, + Fan30 = 0x00B0001E, + Fan31 = 0x00B0001F, + Fan32 = 0x00B00020, + Fan33 = 0x00B00021, + Fan34 = 0x00B00022, + Fan35 = 0x00B00023, + Fan36 = 0x00B00024, + Fan37 = 0x00B00025, + Fan38 = 0x00B00026, + Fan39 = 0x00B00027, + Fan40 = 0x00B00028, + Fan41 = 0x00B00029, + Fan42 = 0x00B0002A, + Fan43 = 0x00B0002B, + Fan44 = 0x00B0002C, + Fan45 = 0x00B0002D, + Fan46 = 0x00B0002E, + Fan47 = 0x00B0002F, + Fan48 = 0x00B00030, + Fan49 = 0x00B00031, + Fan50 = 0x00B00032, + Fan51 = 0x00B00033, + Fan52 = 0x00B00034, + Fan53 = 0x00B00035, + Fan54 = 0x00B00036, + Fan55 = 0x00B00037, + Fan56 = 0x00B00038, + Fan57 = 0x00B00039, + Fan58 = 0x00B0003A, + Fan59 = 0x00B0003B, + Fan60 = 0x00B0003C, + Fan61 = 0x00B0003D, + Fan62 = 0x00B0003E, + Fan63 = 0x00B0003F, + Fan64 = 0x00B00040, + Fan65 = 0x00B00041, + Fan66 = 0x00B00042, + Fan67 = 0x00B00043, + Fan68 = 0x00B00044, + Fan69 = 0x00B00045, + Fan70 = 0x00B00046, + Fan71 = 0x00B00047, + Fan72 = 0x00B00048, + Fan73 = 0x00B00049, + Fan74 = 0x00B0004A, + Fan75 = 0x00B0004B, + Fan76 = 0x00B0004C, + Fan77 = 0x00B0004D, + Fan78 = 0x00B0004E, + Fan79 = 0x00B0004F, + Fan80 = 0x00B00050, + Fan81 = 0x00B00051, + Fan82 = 0x00B00052, + Fan83 = 0x00B00053, + Fan84 = 0x00B00054, + Fan85 = 0x00B00055, + Fan86 = 0x00B00056, + Fan87 = 0x00B00057, + Fan88 = 0x00B00058, + Fan89 = 0x00B00059, + Fan90 = 0x00B0005A, + Fan91 = 0x00B0005B, + Fan92 = 0x00B0005C, + Fan93 = 0x00B0005D, + Fan94 = 0x00B0005E, + Fan95 = 0x00B0005F, + Fan96 = 0x00B00060, + Fan97 = 0x00B00061, + Fan98 = 0x00B00062, + Fan99 = 0x00B00063, + Fan100 = 0x00B00064, + Fan101 = 0x00B00065, + Fan102 = 0x00B00066, + Fan103 = 0x00B00067, + Fan104 = 0x00B00068, + Fan105 = 0x00B00069, + Fan106 = 0x00B0006A, + Fan107 = 0x00B0006B, + Fan108 = 0x00B0006C, + Fan109 = 0x00B0006D, + Fan110 = 0x00B0006E, + Fan111 = 0x00B0006F, + Fan112 = 0x00B00070, + Fan113 = 0x00B00071, + Fan114 = 0x00B00072, + Fan115 = 0x00B00073, + Fan116 = 0x00B00074, + Fan117 = 0x00B00075, + Fan118 = 0x00B00076, + Fan119 = 0x00B00077, + Fan120 = 0x00B00078, + Fan121 = 0x00B00079, + Fan122 = 0x00B0007A, + Fan123 = 0x00B0007B, + Fan124 = 0x00B0007C, + Fan125 = 0x00B0007D, + Fan126 = 0x00B0007E, + Fan127 = 0x00B0007F, + Fan128 = 0x00B00080, - /*### Fan ###*/ - Fan1 = 0x00B00001, - Fan2 = 0x00B00002, - Fan3 = 0x00B00003, - Fan4 = 0x00B00004, - Fan5 = 0x00B00005, - Fan6 = 0x00B00006, - Fan7 = 0x00B00007, - Fan8 = 0x00B00008, - Fan9 = 0x00B00009, - Fan10 = 0x00B0000A, - Fan11 = 0x00B0000B, - Fan12 = 0x00B0000C, - Fan13 = 0x00B0000D, - Fan14 = 0x00B0000E, - Fan15 = 0x00B0000F, - Fan16 = 0x00B00010, - Fan17 = 0x00B00011, - Fan18 = 0x00B00012, - Fan19 = 0x00B00013, - Fan20 = 0x00B00014, - Fan21 = 0x00B00015, - Fan22 = 0x00B00016, - Fan23 = 0x00B00017, - Fan24 = 0x00B00018, - Fan25 = 0x00B00019, - Fan26 = 0x00B0001A, - Fan27 = 0x00B0001B, - Fan28 = 0x00B0001C, - Fan29 = 0x00B0001D, - Fan30 = 0x00B0001E, - Fan31 = 0x00B0001F, - Fan32 = 0x00B00020, - Fan33 = 0x00B00021, - Fan34 = 0x00B00022, - Fan35 = 0x00B00023, - Fan36 = 0x00B00024, - Fan37 = 0x00B00025, - Fan38 = 0x00B00026, - Fan39 = 0x00B00027, - Fan40 = 0x00B00028, - Fan41 = 0x00B00029, - Fan42 = 0x00B0002A, - Fan43 = 0x00B0002B, - Fan44 = 0x00B0002C, - Fan45 = 0x00B0002D, - Fan46 = 0x00B0002E, - Fan47 = 0x00B0002F, - Fan48 = 0x00B00030, - Fan49 = 0x00B00031, - Fan50 = 0x00B00032, - Fan51 = 0x00B00033, - Fan52 = 0x00B00034, - Fan53 = 0x00B00035, - Fan54 = 0x00B00036, - Fan55 = 0x00B00037, - Fan56 = 0x00B00038, - Fan57 = 0x00B00039, - Fan58 = 0x00B0003A, - Fan59 = 0x00B0003B, - Fan60 = 0x00B0003C, - Fan61 = 0x00B0003D, - Fan62 = 0x00B0003E, - Fan63 = 0x00B0003F, - Fan64 = 0x00B00040, + /*### Speaker ###*/ + Speaker1 = 0x00C00001, + Speaker2 = 0x00C00002, + Speaker3 = 0x00C00003, + Speaker4 = 0x00C00004, + Speaker5 = 0x00C00005, + Speaker6 = 0x00C00006, + Speaker7 = 0x00C00007, + Speaker8 = 0x00C00008, + Speaker9 = 0x00C00009, + Speaker10 = 0x00C0000A, + Speaker11 = 0x00C0000B, + Speaker12 = 0x00C0000C, + Speaker13 = 0x00C0000D, + Speaker14 = 0x00C0000E, + Speaker15 = 0x00C0000F, + Speaker16 = 0x00C00010, + Speaker17 = 0x00C00011, + Speaker18 = 0x00C00012, + Speaker19 = 0x00C00013, + Speaker20 = 0x00C00014, + Speaker21 = 0x00C00015, + Speaker22 = 0x00C00016, + Speaker23 = 0x00C00017, + Speaker24 = 0x00C00018, + Speaker25 = 0x00C00019, + Speaker26 = 0x00C0001A, + Speaker27 = 0x00C0001B, + Speaker28 = 0x00C0001C, + Speaker29 = 0x00C0001D, + Speaker30 = 0x00C0001E, + Speaker31 = 0x00C0001F, + Speaker32 = 0x00C00020, + Speaker33 = 0x00C00021, + Speaker34 = 0x00C00022, + Speaker35 = 0x00C00023, + Speaker36 = 0x00C00024, + Speaker37 = 0x00C00025, + Speaker38 = 0x00C00026, + Speaker39 = 0x00C00027, + Speaker40 = 0x00C00028, + Speaker41 = 0x00C00029, + Speaker42 = 0x00C0002A, + Speaker43 = 0x00C0002B, + Speaker44 = 0x00C0002C, + Speaker45 = 0x00C0002D, + Speaker46 = 0x00C0002E, + Speaker47 = 0x00C0002F, + Speaker48 = 0x00C00030, + Speaker49 = 0x00C00031, + Speaker50 = 0x00C00032, + Speaker51 = 0x00C00033, + Speaker52 = 0x00C00034, + Speaker53 = 0x00C00035, + Speaker54 = 0x00C00036, + Speaker55 = 0x00C00037, + Speaker56 = 0x00C00038, + Speaker57 = 0x00C00039, + Speaker58 = 0x00C0003A, + Speaker59 = 0x00C0003B, + Speaker60 = 0x00C0003C, + Speaker61 = 0x00C0003D, + Speaker62 = 0x00C0003E, + Speaker63 = 0x00C0003F, + Speaker64 = 0x00C00040, + Speaker65 = 0x00C00041, + Speaker66 = 0x00C00042, + Speaker67 = 0x00C00043, + Speaker68 = 0x00C00044, + Speaker69 = 0x00C00045, + Speaker70 = 0x00C00046, + Speaker71 = 0x00C00047, + Speaker72 = 0x00C00048, + Speaker73 = 0x00C00049, + Speaker74 = 0x00C0004A, + Speaker75 = 0x00C0004B, + Speaker76 = 0x00C0004C, + Speaker77 = 0x00C0004D, + Speaker78 = 0x00C0004E, + Speaker79 = 0x00C0004F, + Speaker80 = 0x00C00050, + Speaker81 = 0x00C00051, + Speaker82 = 0x00C00052, + Speaker83 = 0x00C00053, + Speaker84 = 0x00C00054, + Speaker85 = 0x00C00055, + Speaker86 = 0x00C00056, + Speaker87 = 0x00C00057, + Speaker88 = 0x00C00058, + Speaker89 = 0x00C00059, + Speaker90 = 0x00C0005A, + Speaker91 = 0x00C0005B, + Speaker92 = 0x00C0005C, + Speaker93 = 0x00C0005D, + Speaker94 = 0x00C0005E, + Speaker95 = 0x00C0005F, + Speaker96 = 0x00C00060, + Speaker97 = 0x00C00061, + Speaker98 = 0x00C00062, + Speaker99 = 0x00C00063, + Speaker100 = 0x00C00064, + Speaker101 = 0x00C00065, + Speaker102 = 0x00C00066, + Speaker103 = 0x00C00067, + Speaker104 = 0x00C00068, + Speaker105 = 0x00C00069, + Speaker106 = 0x00C0006A, + Speaker107 = 0x00C0006B, + Speaker108 = 0x00C0006C, + Speaker109 = 0x00C0006D, + Speaker110 = 0x00C0006E, + Speaker111 = 0x00C0006F, + Speaker112 = 0x00C00070, + Speaker113 = 0x00C00071, + Speaker114 = 0x00C00072, + Speaker115 = 0x00C00073, + Speaker116 = 0x00C00074, + Speaker117 = 0x00C00075, + Speaker118 = 0x00C00076, + Speaker119 = 0x00C00077, + Speaker120 = 0x00C00078, + Speaker121 = 0x00C00079, + Speaker122 = 0x00C0007A, + Speaker123 = 0x00C0007B, + Speaker124 = 0x00C0007C, + Speaker125 = 0x00C0007D, + Speaker126 = 0x00C0007E, + Speaker127 = 0x00C0007F, + Speaker128 = 0x00C00080, - /*### Speaker ###*/ - Speaker1 = 0x00C00001, - Speaker2 = 0x00C00002, - Speaker3 = 0x00C00003, - Speaker4 = 0x00C00004, - Speaker5 = 0x00C00005, - Speaker6 = 0x00C00006, - Speaker7 = 0x00C00007, - Speaker8 = 0x00C00008, - Speaker9 = 0x00C00009, - Speaker10 = 0x00C0000A, - Speaker11 = 0x00C0000B, - Speaker12 = 0x00C0000C, - Speaker13 = 0x00C0000D, - Speaker14 = 0x00C0000E, - Speaker15 = 0x00C0000F, - Speaker16 = 0x00C00010, - Speaker17 = 0x00C00011, - Speaker18 = 0x00C00012, - Speaker19 = 0x00C00013, - Speaker20 = 0x00C00014, - Speaker21 = 0x00C00015, - Speaker22 = 0x00C00016, - Speaker23 = 0x00C00017, - Speaker24 = 0x00C00018, - Speaker25 = 0x00C00019, - Speaker26 = 0x00C0001A, - Speaker27 = 0x00C0001B, - Speaker28 = 0x00C0001C, - Speaker29 = 0x00C0001D, - Speaker30 = 0x00C0001E, - Speaker31 = 0x00C0001F, - Speaker32 = 0x00C00020, - Speaker33 = 0x00C00021, - Speaker34 = 0x00C00022, - Speaker35 = 0x00C00023, - Speaker36 = 0x00C00024, - Speaker37 = 0x00C00025, - Speaker38 = 0x00C00026, - Speaker39 = 0x00C00027, - Speaker40 = 0x00C00028, - Speaker41 = 0x00C00029, - Speaker42 = 0x00C0002A, - Speaker43 = 0x00C0002B, - Speaker44 = 0x00C0002C, - Speaker45 = 0x00C0002D, - Speaker46 = 0x00C0002E, - Speaker47 = 0x00C0002F, - Speaker48 = 0x00C00030, - Speaker49 = 0x00C00031, - Speaker50 = 0x00C00032, - Speaker51 = 0x00C00033, - Speaker52 = 0x00C00034, - Speaker53 = 0x00C00035, - Speaker54 = 0x00C00036, - Speaker55 = 0x00C00037, - Speaker56 = 0x00C00038, - Speaker57 = 0x00C00039, - Speaker58 = 0x00C0003A, - Speaker59 = 0x00C0003B, - Speaker60 = 0x00C0003C, - Speaker61 = 0x00C0003D, - Speaker62 = 0x00C0003E, - Speaker63 = 0x00C0003F, - Speaker64 = 0x00C00040, + /*### Cooler ###*/ + Cooler1 = 0x00D00001, + Cooler2 = 0x00D00002, + Cooler3 = 0x00D00003, + Cooler4 = 0x00D00004, + Cooler5 = 0x00D00005, + Cooler6 = 0x00D00006, + Cooler7 = 0x00D00007, + Cooler8 = 0x00D00008, + Cooler9 = 0x00D00009, + Cooler10 = 0x00D0000A, + Cooler11 = 0x00D0000B, + Cooler12 = 0x00D0000C, + Cooler13 = 0x00D0000D, + Cooler14 = 0x00D0000E, + Cooler15 = 0x00D0000F, + Cooler16 = 0x00D00010, + Cooler17 = 0x00D00011, + Cooler18 = 0x00D00012, + Cooler19 = 0x00D00013, + Cooler20 = 0x00D00014, + Cooler21 = 0x00D00015, + Cooler22 = 0x00D00016, + Cooler23 = 0x00D00017, + Cooler24 = 0x00D00018, + Cooler25 = 0x00D00019, + Cooler26 = 0x00D0001A, + Cooler27 = 0x00D0001B, + Cooler28 = 0x00D0001C, + Cooler29 = 0x00D0001D, + Cooler30 = 0x00D0001E, + Cooler31 = 0x00D0001F, + Cooler32 = 0x00D00020, + Cooler33 = 0x00D00021, + Cooler34 = 0x00D00022, + Cooler35 = 0x00D00023, + Cooler36 = 0x00D00024, + Cooler37 = 0x00D00025, + Cooler38 = 0x00D00026, + Cooler39 = 0x00D00027, + Cooler40 = 0x00D00028, + Cooler41 = 0x00D00029, + Cooler42 = 0x00D0002A, + Cooler43 = 0x00D0002B, + Cooler44 = 0x00D0002C, + Cooler45 = 0x00D0002D, + Cooler46 = 0x00D0002E, + Cooler47 = 0x00D0002F, + Cooler48 = 0x00D00030, + Cooler49 = 0x00D00031, + Cooler50 = 0x00D00032, + Cooler51 = 0x00D00033, + Cooler52 = 0x00D00034, + Cooler53 = 0x00D00035, + Cooler54 = 0x00D00036, + Cooler55 = 0x00D00037, + Cooler56 = 0x00D00038, + Cooler57 = 0x00D00039, + Cooler58 = 0x00D0003A, + Cooler59 = 0x00D0003B, + Cooler60 = 0x00D0003C, + Cooler61 = 0x00D0003D, + Cooler62 = 0x00D0003E, + Cooler63 = 0x00D0003F, + Cooler64 = 0x00D00040, + Cooler65 = 0x00D00041, + Cooler66 = 0x00D00042, + Cooler67 = 0x00D00043, + Cooler68 = 0x00D00044, + Cooler69 = 0x00D00045, + Cooler70 = 0x00D00046, + Cooler71 = 0x00D00047, + Cooler72 = 0x00D00048, + Cooler73 = 0x00D00049, + Cooler74 = 0x00D0004A, + Cooler75 = 0x00D0004B, + Cooler76 = 0x00D0004C, + Cooler77 = 0x00D0004D, + Cooler78 = 0x00D0004E, + Cooler79 = 0x00D0004F, + Cooler80 = 0x00D00050, + Cooler81 = 0x00D00051, + Cooler82 = 0x00D00052, + Cooler83 = 0x00D00053, + Cooler84 = 0x00D00054, + Cooler85 = 0x00D00055, + Cooler86 = 0x00D00056, + Cooler87 = 0x00D00057, + Cooler88 = 0x00D00058, + Cooler89 = 0x00D00059, + Cooler90 = 0x00D0005A, + Cooler91 = 0x00D0005B, + Cooler92 = 0x00D0005C, + Cooler93 = 0x00D0005D, + Cooler94 = 0x00D0005E, + Cooler95 = 0x00D0005F, + Cooler96 = 0x00D00060, + Cooler97 = 0x00D00061, + Cooler98 = 0x00D00062, + Cooler99 = 0x00D00063, + Cooler100 = 0x00D00064, + Cooler101 = 0x00D00065, + Cooler102 = 0x00D00066, + Cooler103 = 0x00D00067, + Cooler104 = 0x00D00068, + Cooler105 = 0x00D00069, + Cooler106 = 0x00D0006A, + Cooler107 = 0x00D0006B, + Cooler108 = 0x00D0006C, + Cooler109 = 0x00D0006D, + Cooler110 = 0x00D0006E, + Cooler111 = 0x00D0006F, + Cooler112 = 0x00D00070, + Cooler113 = 0x00D00071, + Cooler114 = 0x00D00072, + Cooler115 = 0x00D00073, + Cooler116 = 0x00D00074, + Cooler117 = 0x00D00075, + Cooler118 = 0x00D00076, + Cooler119 = 0x00D00077, + Cooler120 = 0x00D00078, + Cooler121 = 0x00D00079, + Cooler122 = 0x00D0007A, + Cooler123 = 0x00D0007B, + Cooler124 = 0x00D0007C, + Cooler125 = 0x00D0007D, + Cooler126 = 0x00D0007E, + Cooler127 = 0x00D0007F, + Cooler128 = 0x00D00080, - /*### Cooler ###*/ - Cooler1 = 0x00D00001, - Cooler2 = 0x00D00002, - Cooler3 = 0x00D00003, - Cooler4 = 0x00D00004, - Cooler5 = 0x00D00005, - Cooler6 = 0x00D00006, - Cooler7 = 0x00D00007, - Cooler8 = 0x00D00008, - Cooler9 = 0x00D00009, - Cooler10 = 0x00D0000A, - Cooler11 = 0x00D0000B, - Cooler12 = 0x00D0000C, - Cooler13 = 0x00D0000D, - Cooler14 = 0x00D0000E, - Cooler15 = 0x00D0000F, - Cooler16 = 0x00D00010, - Cooler17 = 0x00D00011, - Cooler18 = 0x00D00012, - Cooler19 = 0x00D00013, - Cooler20 = 0x00D00014, - Cooler21 = 0x00D00015, - Cooler22 = 0x00D00016, - Cooler23 = 0x00D00017, - Cooler24 = 0x00D00018, - Cooler25 = 0x00D00019, - Cooler26 = 0x00D0001A, - Cooler27 = 0x00D0001B, - Cooler28 = 0x00D0001C, - Cooler29 = 0x00D0001D, - Cooler30 = 0x00D0001E, - Cooler31 = 0x00D0001F, - Cooler32 = 0x00D00020, - Cooler33 = 0x00D00021, - Cooler34 = 0x00D00022, - Cooler35 = 0x00D00023, - Cooler36 = 0x00D00024, - Cooler37 = 0x00D00025, - Cooler38 = 0x00D00026, - Cooler39 = 0x00D00027, - Cooler40 = 0x00D00028, - Cooler41 = 0x00D00029, - Cooler42 = 0x00D0002A, - Cooler43 = 0x00D0002B, - Cooler44 = 0x00D0002C, - Cooler45 = 0x00D0002D, - Cooler46 = 0x00D0002E, - Cooler47 = 0x00D0002F, - Cooler48 = 0x00D00030, - Cooler49 = 0x00D00031, - Cooler50 = 0x00D00032, - Cooler51 = 0x00D00033, - Cooler52 = 0x00D00034, - Cooler53 = 0x00D00035, - Cooler54 = 0x00D00036, - Cooler55 = 0x00D00037, - Cooler56 = 0x00D00038, - Cooler57 = 0x00D00039, - Cooler58 = 0x00D0003A, - Cooler59 = 0x00D0003B, - Cooler60 = 0x00D0003C, - Cooler61 = 0x00D0003D, - Cooler62 = 0x00D0003E, - Cooler63 = 0x00D0003F, - Cooler64 = 0x00D00040, + /*### Custom ###*/ + Custom1 = 0x0FE00001, + Custom2 = 0x0FE00002, + Custom3 = 0x0FE00003, + Custom4 = 0x0FE00004, + Custom5 = 0x0FE00005, + Custom6 = 0x0FE00006, + Custom7 = 0x0FE00007, + Custom8 = 0x0FE00008, + Custom9 = 0x0FE00009, + Custom10 = 0x0FE0000A, + Custom11 = 0x0FE0000B, + Custom12 = 0x0FE0000C, + Custom13 = 0x0FE0000D, + Custom14 = 0x0FE0000E, + Custom15 = 0x0FE0000F, + Custom16 = 0x0FE00010, + Custom17 = 0x0FE00011, + Custom18 = 0x0FE00012, + Custom19 = 0x0FE00013, + Custom20 = 0x0FE00014, + Custom21 = 0x0FE00015, + Custom22 = 0x0FE00016, + Custom23 = 0x0FE00017, + Custom24 = 0x0FE00018, + Custom25 = 0x0FE00019, + Custom26 = 0x0FE0001A, + Custom27 = 0x0FE0001B, + Custom28 = 0x0FE0001C, + Custom29 = 0x0FE0001D, + Custom30 = 0x0FE0001E, + Custom31 = 0x0FE0001F, + Custom32 = 0x0FE00020, + Custom33 = 0x0FE00021, + Custom34 = 0x0FE00022, + Custom35 = 0x0FE00023, + Custom36 = 0x0FE00024, + Custom37 = 0x0FE00025, + Custom38 = 0x0FE00026, + Custom39 = 0x0FE00027, + Custom40 = 0x0FE00028, + Custom41 = 0x0FE00029, + Custom42 = 0x0FE0002A, + Custom43 = 0x0FE0002B, + Custom44 = 0x0FE0002C, + Custom45 = 0x0FE0002D, + Custom46 = 0x0FE0002E, + Custom47 = 0x0FE0002F, + Custom48 = 0x0FE00030, + Custom49 = 0x0FE00031, + Custom50 = 0x0FE00032, + Custom51 = 0x0FE00033, + Custom52 = 0x0FE00034, + Custom53 = 0x0FE00035, + Custom54 = 0x0FE00036, + Custom55 = 0x0FE00037, + Custom56 = 0x0FE00038, + Custom57 = 0x0FE00039, + Custom58 = 0x0FE0003A, + Custom59 = 0x0FE0003B, + Custom60 = 0x0FE0003C, + Custom61 = 0x0FE0003D, + Custom62 = 0x0FE0003E, + Custom63 = 0x0FE0003F, + Custom64 = 0x0FE00040, + Custom65 = 0x0FE00041, + Custom66 = 0x0FE00042, + Custom67 = 0x0FE00043, + Custom68 = 0x0FE00044, + Custom69 = 0x0FE00045, + Custom70 = 0x0FE00046, + Custom71 = 0x0FE00047, + Custom72 = 0x0FE00048, + Custom73 = 0x0FE00049, + Custom74 = 0x0FE0004A, + Custom75 = 0x0FE0004B, + Custom76 = 0x0FE0004C, + Custom77 = 0x0FE0004D, + Custom78 = 0x0FE0004E, + Custom79 = 0x0FE0004F, + Custom80 = 0x0FE00050, + Custom81 = 0x0FE00051, + Custom82 = 0x0FE00052, + Custom83 = 0x0FE00053, + Custom84 = 0x0FE00054, + Custom85 = 0x0FE00055, + Custom86 = 0x0FE00056, + Custom87 = 0x0FE00057, + Custom88 = 0x0FE00058, + Custom89 = 0x0FE00059, + Custom90 = 0x0FE0005A, + Custom91 = 0x0FE0005B, + Custom92 = 0x0FE0005C, + Custom93 = 0x0FE0005D, + Custom94 = 0x0FE0005E, + Custom95 = 0x0FE0005F, + Custom96 = 0x0FE00060, + Custom97 = 0x0FE00061, + Custom98 = 0x0FE00062, + Custom99 = 0x0FE00063, + Custom100 = 0x0FE00064, + Custom101 = 0x0FE00065, + Custom102 = 0x0FE00066, + Custom103 = 0x0FE00067, + Custom104 = 0x0FE00068, + Custom105 = 0x0FE00069, + Custom106 = 0x0FE0006A, + Custom107 = 0x0FE0006B, + Custom108 = 0x0FE0006C, + Custom109 = 0x0FE0006D, + Custom110 = 0x0FE0006E, + Custom111 = 0x0FE0006F, + Custom112 = 0x0FE00070, + Custom113 = 0x0FE00071, + Custom114 = 0x0FE00072, + Custom115 = 0x0FE00073, + Custom116 = 0x0FE00074, + Custom117 = 0x0FE00075, + Custom118 = 0x0FE00076, + Custom119 = 0x0FE00077, + Custom120 = 0x0FE00078, + Custom121 = 0x0FE00079, + Custom122 = 0x0FE0007A, + Custom123 = 0x0FE0007B, + Custom124 = 0x0FE0007C, + Custom125 = 0x0FE0007D, + Custom126 = 0x0FE0007E, + Custom127 = 0x0FE0007F, + Custom128 = 0x0FE00080, + Custom129 = 0x0FE00081, + Custom130 = 0x0FE00082, + Custom131 = 0x0FE00083, + Custom132 = 0x0FE00084, + Custom133 = 0x0FE00085, + Custom134 = 0x0FE00086, + Custom135 = 0x0FE00087, + Custom136 = 0x0FE00088, + Custom137 = 0x0FE00089, + Custom138 = 0x0FE0008A, + Custom139 = 0x0FE0008B, + Custom140 = 0x0FE0008C, + Custom141 = 0x0FE0008D, + Custom142 = 0x0FE0008E, + Custom143 = 0x0FE0008F, + Custom144 = 0x0FE00090, + Custom145 = 0x0FE00091, + Custom146 = 0x0FE00092, + Custom147 = 0x0FE00093, + Custom148 = 0x0FE00094, + Custom149 = 0x0FE00095, + Custom150 = 0x0FE00096, + Custom151 = 0x0FE00097, + Custom152 = 0x0FE00098, + Custom153 = 0x0FE00099, + Custom154 = 0x0FE0009A, + Custom155 = 0x0FE0009B, + Custom156 = 0x0FE0009C, + Custom157 = 0x0FE0009D, + Custom158 = 0x0FE0009E, + Custom159 = 0x0FE0009F, + Custom160 = 0x0FE000A0, + Custom161 = 0x0FE000A1, + Custom162 = 0x0FE000A2, + Custom163 = 0x0FE000A3, + Custom164 = 0x0FE000A4, + Custom165 = 0x0FE000A5, + Custom166 = 0x0FE000A6, + Custom167 = 0x0FE000A7, + Custom168 = 0x0FE000A8, + Custom169 = 0x0FE000A9, + Custom170 = 0x0FE000AA, + Custom171 = 0x0FE000AB, + Custom172 = 0x0FE000AC, + Custom173 = 0x0FE000AD, + Custom174 = 0x0FE000AE, + Custom175 = 0x0FE000AF, + Custom176 = 0x0FE000B0, + Custom177 = 0x0FE000B1, + Custom178 = 0x0FE000B2, + Custom179 = 0x0FE000B3, + Custom180 = 0x0FE000B4, + Custom181 = 0x0FE000B5, + Custom182 = 0x0FE000B6, + Custom183 = 0x0FE000B7, + Custom184 = 0x0FE000B8, + Custom185 = 0x0FE000B9, + Custom186 = 0x0FE000BA, + Custom187 = 0x0FE000BB, + Custom188 = 0x0FE000BC, + Custom189 = 0x0FE000BD, + Custom190 = 0x0FE000BE, + Custom191 = 0x0FE000BF, + Custom192 = 0x0FE000C0, + Custom193 = 0x0FE000C1, + Custom194 = 0x0FE000C2, + Custom195 = 0x0FE000C3, + Custom196 = 0x0FE000C4, + Custom197 = 0x0FE000C5, + Custom198 = 0x0FE000C6, + Custom199 = 0x0FE000C7, + Custom200 = 0x0FE000C8, + Custom201 = 0x0FE000C9, + Custom202 = 0x0FE000CA, + Custom203 = 0x0FE000CB, + Custom204 = 0x0FE000CC, + Custom205 = 0x0FE000CD, + Custom206 = 0x0FE000CE, + Custom207 = 0x0FE000CF, + Custom208 = 0x0FE000D0, + Custom209 = 0x0FE000D1, + Custom210 = 0x0FE000D2, + Custom211 = 0x0FE000D3, + Custom212 = 0x0FE000D4, + Custom213 = 0x0FE000D5, + Custom214 = 0x0FE000D6, + Custom215 = 0x0FE000D7, + Custom216 = 0x0FE000D8, + Custom217 = 0x0FE000D9, + Custom218 = 0x0FE000DA, + Custom219 = 0x0FE000DB, + Custom220 = 0x0FE000DC, + Custom221 = 0x0FE000DD, + Custom222 = 0x0FE000DE, + Custom223 = 0x0FE000DF, + Custom224 = 0x0FE000E0, + Custom225 = 0x0FE000E1, + Custom226 = 0x0FE000E2, + Custom227 = 0x0FE000E3, + Custom228 = 0x0FE000E4, + Custom229 = 0x0FE000E5, + Custom230 = 0x0FE000E6, + Custom231 = 0x0FE000E7, + Custom232 = 0x0FE000E8, + Custom233 = 0x0FE000E9, + Custom234 = 0x0FE000EA, + Custom235 = 0x0FE000EB, + Custom236 = 0x0FE000EC, + Custom237 = 0x0FE000ED, + Custom238 = 0x0FE000EE, + Custom239 = 0x0FE000EF, + Custom240 = 0x0FE000F0, + Custom241 = 0x0FE000F1, + Custom242 = 0x0FE000F2, + Custom243 = 0x0FE000F3, + Custom244 = 0x0FE000F4, + Custom245 = 0x0FE000F5, + Custom246 = 0x0FE000F6, + Custom247 = 0x0FE000F7, + Custom248 = 0x0FE000F8, + Custom249 = 0x0FE000F9, + Custom250 = 0x0FE000FA, + Custom251 = 0x0FE000FB, + Custom252 = 0x0FE000FC, + Custom253 = 0x0FE000FD, + Custom254 = 0x0FE000FE, + Custom255 = 0x0FE000FF, + Custom256 = 0x0FE00100, + Custom257 = 0x0FE00101, + Custom258 = 0x0FE00102, + Custom259 = 0x0FE00103, + Custom260 = 0x0FE00104, + Custom261 = 0x0FE00105, + Custom262 = 0x0FE00106, + Custom263 = 0x0FE00107, + Custom264 = 0x0FE00108, + Custom265 = 0x0FE00109, + Custom266 = 0x0FE0010A, + Custom267 = 0x0FE0010B, + Custom268 = 0x0FE0010C, + Custom269 = 0x0FE0010D, + Custom270 = 0x0FE0010E, + Custom271 = 0x0FE0010F, + Custom272 = 0x0FE00110, + Custom273 = 0x0FE00111, + Custom274 = 0x0FE00112, + Custom275 = 0x0FE00113, + Custom276 = 0x0FE00114, + Custom277 = 0x0FE00115, + Custom278 = 0x0FE00116, + Custom279 = 0x0FE00117, + Custom280 = 0x0FE00118, + Custom281 = 0x0FE00119, + Custom282 = 0x0FE0011A, + Custom283 = 0x0FE0011B, + Custom284 = 0x0FE0011C, + Custom285 = 0x0FE0011D, + Custom286 = 0x0FE0011E, + Custom287 = 0x0FE0011F, + Custom288 = 0x0FE00120, + Custom289 = 0x0FE00121, + Custom290 = 0x0FE00122, + Custom291 = 0x0FE00123, + Custom292 = 0x0FE00124, + Custom293 = 0x0FE00125, + Custom294 = 0x0FE00126, + Custom295 = 0x0FE00127, + Custom296 = 0x0FE00128, + Custom297 = 0x0FE00129, + Custom298 = 0x0FE0012A, + Custom299 = 0x0FE0012B, + Custom300 = 0x0FE0012C, + Custom301 = 0x0FE0012D, + Custom302 = 0x0FE0012E, + Custom303 = 0x0FE0012F, + Custom304 = 0x0FE00130, + Custom305 = 0x0FE00131, + Custom306 = 0x0FE00132, + Custom307 = 0x0FE00133, + Custom308 = 0x0FE00134, + Custom309 = 0x0FE00135, + Custom310 = 0x0FE00136, + Custom311 = 0x0FE00137, + Custom312 = 0x0FE00138, + Custom313 = 0x0FE00139, + Custom314 = 0x0FE0013A, + Custom315 = 0x0FE0013B, + Custom316 = 0x0FE0013C, + Custom317 = 0x0FE0013D, + Custom318 = 0x0FE0013E, + Custom319 = 0x0FE0013F, + Custom320 = 0x0FE00140, + Custom321 = 0x0FE00141, + Custom322 = 0x0FE00142, + Custom323 = 0x0FE00143, + Custom324 = 0x0FE00144, + Custom325 = 0x0FE00145, + Custom326 = 0x0FE00146, + Custom327 = 0x0FE00147, + Custom328 = 0x0FE00148, + Custom329 = 0x0FE00149, + Custom330 = 0x0FE0014A, + Custom331 = 0x0FE0014B, + Custom332 = 0x0FE0014C, + Custom333 = 0x0FE0014D, + Custom334 = 0x0FE0014E, + Custom335 = 0x0FE0014F, + Custom336 = 0x0FE00150, + Custom337 = 0x0FE00151, + Custom338 = 0x0FE00152, + Custom339 = 0x0FE00153, + Custom340 = 0x0FE00154, + Custom341 = 0x0FE00155, + Custom342 = 0x0FE00156, + Custom343 = 0x0FE00157, + Custom344 = 0x0FE00158, + Custom345 = 0x0FE00159, + Custom346 = 0x0FE0015A, + Custom347 = 0x0FE0015B, + Custom348 = 0x0FE0015C, + Custom349 = 0x0FE0015D, + Custom350 = 0x0FE0015E, + Custom351 = 0x0FE0015F, + Custom352 = 0x0FE00160, + Custom353 = 0x0FE00161, + Custom354 = 0x0FE00162, + Custom355 = 0x0FE00163, + Custom356 = 0x0FE00164, + Custom357 = 0x0FE00165, + Custom358 = 0x0FE00166, + Custom359 = 0x0FE00167, + Custom360 = 0x0FE00168, + Custom361 = 0x0FE00169, + Custom362 = 0x0FE0016A, + Custom363 = 0x0FE0016B, + Custom364 = 0x0FE0016C, + Custom365 = 0x0FE0016D, + Custom366 = 0x0FE0016E, + Custom367 = 0x0FE0016F, + Custom368 = 0x0FE00170, + Custom369 = 0x0FE00171, + Custom370 = 0x0FE00172, + Custom371 = 0x0FE00173, + Custom372 = 0x0FE00174, + Custom373 = 0x0FE00175, + Custom374 = 0x0FE00176, + Custom375 = 0x0FE00177, + Custom376 = 0x0FE00178, + Custom377 = 0x0FE00179, + Custom378 = 0x0FE0017A, + Custom379 = 0x0FE0017B, + Custom380 = 0x0FE0017C, + Custom381 = 0x0FE0017D, + Custom382 = 0x0FE0017E, + Custom383 = 0x0FE0017F, + Custom384 = 0x0FE00180, + Custom385 = 0x0FE00181, + Custom386 = 0x0FE00182, + Custom387 = 0x0FE00183, + Custom388 = 0x0FE00184, + Custom389 = 0x0FE00185, + Custom390 = 0x0FE00186, + Custom391 = 0x0FE00187, + Custom392 = 0x0FE00188, + Custom393 = 0x0FE00189, + Custom394 = 0x0FE0018A, + Custom395 = 0x0FE0018B, + Custom396 = 0x0FE0018C, + Custom397 = 0x0FE0018D, + Custom398 = 0x0FE0018E, + Custom399 = 0x0FE0018F, + Custom400 = 0x0FE00190, + Custom401 = 0x0FE00191, + Custom402 = 0x0FE00192, + Custom403 = 0x0FE00193, + Custom404 = 0x0FE00194, + Custom405 = 0x0FE00195, + Custom406 = 0x0FE00196, + Custom407 = 0x0FE00197, + Custom408 = 0x0FE00198, + Custom409 = 0x0FE00199, + Custom410 = 0x0FE0019A, + Custom411 = 0x0FE0019B, + Custom412 = 0x0FE0019C, + Custom413 = 0x0FE0019D, + Custom414 = 0x0FE0019E, + Custom415 = 0x0FE0019F, + Custom416 = 0x0FE001A0, + Custom417 = 0x0FE001A1, + Custom418 = 0x0FE001A2, + Custom419 = 0x0FE001A3, + Custom420 = 0x0FE001A4, + Custom421 = 0x0FE001A5, + Custom422 = 0x0FE001A6, + Custom423 = 0x0FE001A7, + Custom424 = 0x0FE001A8, + Custom425 = 0x0FE001A9, + Custom426 = 0x0FE001AA, + Custom427 = 0x0FE001AB, + Custom428 = 0x0FE001AC, + Custom429 = 0x0FE001AD, + Custom430 = 0x0FE001AE, + Custom431 = 0x0FE001AF, + Custom432 = 0x0FE001B0, + Custom433 = 0x0FE001B1, + Custom434 = 0x0FE001B2, + Custom435 = 0x0FE001B3, + Custom436 = 0x0FE001B4, + Custom437 = 0x0FE001B5, + Custom438 = 0x0FE001B6, + Custom439 = 0x0FE001B7, + Custom440 = 0x0FE001B8, + Custom441 = 0x0FE001B9, + Custom442 = 0x0FE001BA, + Custom443 = 0x0FE001BB, + Custom444 = 0x0FE001BC, + Custom445 = 0x0FE001BD, + Custom446 = 0x0FE001BE, + Custom447 = 0x0FE001BF, + Custom448 = 0x0FE001C0, + Custom449 = 0x0FE001C1, + Custom450 = 0x0FE001C2, + Custom451 = 0x0FE001C3, + Custom452 = 0x0FE001C4, + Custom453 = 0x0FE001C5, + Custom454 = 0x0FE001C6, + Custom455 = 0x0FE001C7, + Custom456 = 0x0FE001C8, + Custom457 = 0x0FE001C9, + Custom458 = 0x0FE001CA, + Custom459 = 0x0FE001CB, + Custom460 = 0x0FE001CC, + Custom461 = 0x0FE001CD, + Custom462 = 0x0FE001CE, + Custom463 = 0x0FE001CF, + Custom464 = 0x0FE001D0, + Custom465 = 0x0FE001D1, + Custom466 = 0x0FE001D2, + Custom467 = 0x0FE001D3, + Custom468 = 0x0FE001D4, + Custom469 = 0x0FE001D5, + Custom470 = 0x0FE001D6, + Custom471 = 0x0FE001D7, + Custom472 = 0x0FE001D8, + Custom473 = 0x0FE001D9, + Custom474 = 0x0FE001DA, + Custom475 = 0x0FE001DB, + Custom476 = 0x0FE001DC, + Custom477 = 0x0FE001DD, + Custom478 = 0x0FE001DE, + Custom479 = 0x0FE001DF, + Custom480 = 0x0FE001E0, + Custom481 = 0x0FE001E1, + Custom482 = 0x0FE001E2, + Custom483 = 0x0FE001E3, + Custom484 = 0x0FE001E4, + Custom485 = 0x0FE001E5, + Custom486 = 0x0FE001E6, + Custom487 = 0x0FE001E7, + Custom488 = 0x0FE001E8, + Custom489 = 0x0FE001E9, + Custom490 = 0x0FE001EA, + Custom491 = 0x0FE001EB, + Custom492 = 0x0FE001EC, + Custom493 = 0x0FE001ED, + Custom494 = 0x0FE001EE, + Custom495 = 0x0FE001EF, + Custom496 = 0x0FE001F0, + Custom497 = 0x0FE001F1, + Custom498 = 0x0FE001F2, + Custom499 = 0x0FE001F3, + Custom500 = 0x0FE001F4, + Custom501 = 0x0FE001F5, + Custom502 = 0x0FE001F6, + Custom503 = 0x0FE001F7, + Custom504 = 0x0FE001F8, + Custom505 = 0x0FE001F9, + Custom506 = 0x0FE001FA, + Custom507 = 0x0FE001FB, + Custom508 = 0x0FE001FC, + Custom509 = 0x0FE001FD, + Custom510 = 0x0FE001FE, + Custom511 = 0x0FE001FF, + Custom512 = 0x0FE00200, + Custom513 = 0x0FE00201, + Custom514 = 0x0FE00202, + Custom515 = 0x0FE00203, + Custom516 = 0x0FE00204, + Custom517 = 0x0FE00205, + Custom518 = 0x0FE00206, + Custom519 = 0x0FE00207, + Custom520 = 0x0FE00208, + Custom521 = 0x0FE00209, + Custom522 = 0x0FE0020A, + Custom523 = 0x0FE0020B, + Custom524 = 0x0FE0020C, + Custom525 = 0x0FE0020D, + Custom526 = 0x0FE0020E, + Custom527 = 0x0FE0020F, + Custom528 = 0x0FE00210, + Custom529 = 0x0FE00211, + Custom530 = 0x0FE00212, + Custom531 = 0x0FE00213, + Custom532 = 0x0FE00214, + Custom533 = 0x0FE00215, + Custom534 = 0x0FE00216, + Custom535 = 0x0FE00217, + Custom536 = 0x0FE00218, + Custom537 = 0x0FE00219, + Custom538 = 0x0FE0021A, + Custom539 = 0x0FE0021B, + Custom540 = 0x0FE0021C, + Custom541 = 0x0FE0021D, + Custom542 = 0x0FE0021E, + Custom543 = 0x0FE0021F, + Custom544 = 0x0FE00220, + Custom545 = 0x0FE00221, + Custom546 = 0x0FE00222, + Custom547 = 0x0FE00223, + Custom548 = 0x0FE00224, + Custom549 = 0x0FE00225, + Custom550 = 0x0FE00226, + Custom551 = 0x0FE00227, + Custom552 = 0x0FE00228, + Custom553 = 0x0FE00229, + Custom554 = 0x0FE0022A, + Custom555 = 0x0FE0022B, + Custom556 = 0x0FE0022C, + Custom557 = 0x0FE0022D, + Custom558 = 0x0FE0022E, + Custom559 = 0x0FE0022F, + Custom560 = 0x0FE00230, + Custom561 = 0x0FE00231, + Custom562 = 0x0FE00232, + Custom563 = 0x0FE00233, + Custom564 = 0x0FE00234, + Custom565 = 0x0FE00235, + Custom566 = 0x0FE00236, + Custom567 = 0x0FE00237, + Custom568 = 0x0FE00238, + Custom569 = 0x0FE00239, + Custom570 = 0x0FE0023A, + Custom571 = 0x0FE0023B, + Custom572 = 0x0FE0023C, + Custom573 = 0x0FE0023D, + Custom574 = 0x0FE0023E, + Custom575 = 0x0FE0023F, + Custom576 = 0x0FE00240, + Custom577 = 0x0FE00241, + Custom578 = 0x0FE00242, + Custom579 = 0x0FE00243, + Custom580 = 0x0FE00244, + Custom581 = 0x0FE00245, + Custom582 = 0x0FE00246, + Custom583 = 0x0FE00247, + Custom584 = 0x0FE00248, + Custom585 = 0x0FE00249, + Custom586 = 0x0FE0024A, + Custom587 = 0x0FE0024B, + Custom588 = 0x0FE0024C, + Custom589 = 0x0FE0024D, + Custom590 = 0x0FE0024E, + Custom591 = 0x0FE0024F, + Custom592 = 0x0FE00250, + Custom593 = 0x0FE00251, + Custom594 = 0x0FE00252, + Custom595 = 0x0FE00253, + Custom596 = 0x0FE00254, + Custom597 = 0x0FE00255, + Custom598 = 0x0FE00256, + Custom599 = 0x0FE00257, + Custom600 = 0x0FE00258, + Custom601 = 0x0FE00259, + Custom602 = 0x0FE0025A, + Custom603 = 0x0FE0025B, + Custom604 = 0x0FE0025C, + Custom605 = 0x0FE0025D, + Custom606 = 0x0FE0025E, + Custom607 = 0x0FE0025F, + Custom608 = 0x0FE00260, + Custom609 = 0x0FE00261, + Custom610 = 0x0FE00262, + Custom611 = 0x0FE00263, + Custom612 = 0x0FE00264, + Custom613 = 0x0FE00265, + Custom614 = 0x0FE00266, + Custom615 = 0x0FE00267, + Custom616 = 0x0FE00268, + Custom617 = 0x0FE00269, + Custom618 = 0x0FE0026A, + Custom619 = 0x0FE0026B, + Custom620 = 0x0FE0026C, + Custom621 = 0x0FE0026D, + Custom622 = 0x0FE0026E, + Custom623 = 0x0FE0026F, + Custom624 = 0x0FE00270, + Custom625 = 0x0FE00271, + Custom626 = 0x0FE00272, + Custom627 = 0x0FE00273, + Custom628 = 0x0FE00274, + Custom629 = 0x0FE00275, + Custom630 = 0x0FE00276, + Custom631 = 0x0FE00277, + Custom632 = 0x0FE00278, + Custom633 = 0x0FE00279, + Custom634 = 0x0FE0027A, + Custom635 = 0x0FE0027B, + Custom636 = 0x0FE0027C, + Custom637 = 0x0FE0027D, + Custom638 = 0x0FE0027E, + Custom639 = 0x0FE0027F, + Custom640 = 0x0FE00280, + Custom641 = 0x0FE00281, + Custom642 = 0x0FE00282, + Custom643 = 0x0FE00283, + Custom644 = 0x0FE00284, + Custom645 = 0x0FE00285, + Custom646 = 0x0FE00286, + Custom647 = 0x0FE00287, + Custom648 = 0x0FE00288, + Custom649 = 0x0FE00289, + Custom650 = 0x0FE0028A, + Custom651 = 0x0FE0028B, + Custom652 = 0x0FE0028C, + Custom653 = 0x0FE0028D, + Custom654 = 0x0FE0028E, + Custom655 = 0x0FE0028F, + Custom656 = 0x0FE00290, + Custom657 = 0x0FE00291, + Custom658 = 0x0FE00292, + Custom659 = 0x0FE00293, + Custom660 = 0x0FE00294, + Custom661 = 0x0FE00295, + Custom662 = 0x0FE00296, + Custom663 = 0x0FE00297, + Custom664 = 0x0FE00298, + Custom665 = 0x0FE00299, + Custom666 = 0x0FE0029A, + Custom667 = 0x0FE0029B, + Custom668 = 0x0FE0029C, + Custom669 = 0x0FE0029D, + Custom670 = 0x0FE0029E, + Custom671 = 0x0FE0029F, + Custom672 = 0x0FE002A0, + Custom673 = 0x0FE002A1, + Custom674 = 0x0FE002A2, + Custom675 = 0x0FE002A3, + Custom676 = 0x0FE002A4, + Custom677 = 0x0FE002A5, + Custom678 = 0x0FE002A6, + Custom679 = 0x0FE002A7, + Custom680 = 0x0FE002A8, + Custom681 = 0x0FE002A9, + Custom682 = 0x0FE002AA, + Custom683 = 0x0FE002AB, + Custom684 = 0x0FE002AC, + Custom685 = 0x0FE002AD, + Custom686 = 0x0FE002AE, + Custom687 = 0x0FE002AF, + Custom688 = 0x0FE002B0, + Custom689 = 0x0FE002B1, + Custom690 = 0x0FE002B2, + Custom691 = 0x0FE002B3, + Custom692 = 0x0FE002B4, + Custom693 = 0x0FE002B5, + Custom694 = 0x0FE002B6, + Custom695 = 0x0FE002B7, + Custom696 = 0x0FE002B8, + Custom697 = 0x0FE002B9, + Custom698 = 0x0FE002BA, + Custom699 = 0x0FE002BB, + Custom700 = 0x0FE002BC, + Custom701 = 0x0FE002BD, + Custom702 = 0x0FE002BE, + Custom703 = 0x0FE002BF, + Custom704 = 0x0FE002C0, + Custom705 = 0x0FE002C1, + Custom706 = 0x0FE002C2, + Custom707 = 0x0FE002C3, + Custom708 = 0x0FE002C4, + Custom709 = 0x0FE002C5, + Custom710 = 0x0FE002C6, + Custom711 = 0x0FE002C7, + Custom712 = 0x0FE002C8, + Custom713 = 0x0FE002C9, + Custom714 = 0x0FE002CA, + Custom715 = 0x0FE002CB, + Custom716 = 0x0FE002CC, + Custom717 = 0x0FE002CD, + Custom718 = 0x0FE002CE, + Custom719 = 0x0FE002CF, + Custom720 = 0x0FE002D0, + Custom721 = 0x0FE002D1, + Custom722 = 0x0FE002D2, + Custom723 = 0x0FE002D3, + Custom724 = 0x0FE002D4, + Custom725 = 0x0FE002D5, + Custom726 = 0x0FE002D6, + Custom727 = 0x0FE002D7, + Custom728 = 0x0FE002D8, + Custom729 = 0x0FE002D9, + Custom730 = 0x0FE002DA, + Custom731 = 0x0FE002DB, + Custom732 = 0x0FE002DC, + Custom733 = 0x0FE002DD, + Custom734 = 0x0FE002DE, + Custom735 = 0x0FE002DF, + Custom736 = 0x0FE002E0, + Custom737 = 0x0FE002E1, + Custom738 = 0x0FE002E2, + Custom739 = 0x0FE002E3, + Custom740 = 0x0FE002E4, + Custom741 = 0x0FE002E5, + Custom742 = 0x0FE002E6, + Custom743 = 0x0FE002E7, + Custom744 = 0x0FE002E8, + Custom745 = 0x0FE002E9, + Custom746 = 0x0FE002EA, + Custom747 = 0x0FE002EB, + Custom748 = 0x0FE002EC, + Custom749 = 0x0FE002ED, + Custom750 = 0x0FE002EE, + Custom751 = 0x0FE002EF, + Custom752 = 0x0FE002F0, + Custom753 = 0x0FE002F1, + Custom754 = 0x0FE002F2, + Custom755 = 0x0FE002F3, + Custom756 = 0x0FE002F4, + Custom757 = 0x0FE002F5, + Custom758 = 0x0FE002F6, + Custom759 = 0x0FE002F7, + Custom760 = 0x0FE002F8, + Custom761 = 0x0FE002F9, + Custom762 = 0x0FE002FA, + Custom763 = 0x0FE002FB, + Custom764 = 0x0FE002FC, + Custom765 = 0x0FE002FD, + Custom766 = 0x0FE002FE, + Custom767 = 0x0FE002FF, + Custom768 = 0x0FE00300, + Custom769 = 0x0FE00301, + Custom770 = 0x0FE00302, + Custom771 = 0x0FE00303, + Custom772 = 0x0FE00304, + Custom773 = 0x0FE00305, + Custom774 = 0x0FE00306, + Custom775 = 0x0FE00307, + Custom776 = 0x0FE00308, + Custom777 = 0x0FE00309, + Custom778 = 0x0FE0030A, + Custom779 = 0x0FE0030B, + Custom780 = 0x0FE0030C, + Custom781 = 0x0FE0030D, + Custom782 = 0x0FE0030E, + Custom783 = 0x0FE0030F, + Custom784 = 0x0FE00310, + Custom785 = 0x0FE00311, + Custom786 = 0x0FE00312, + Custom787 = 0x0FE00313, + Custom788 = 0x0FE00314, + Custom789 = 0x0FE00315, + Custom790 = 0x0FE00316, + Custom791 = 0x0FE00317, + Custom792 = 0x0FE00318, + Custom793 = 0x0FE00319, + Custom794 = 0x0FE0031A, + Custom795 = 0x0FE0031B, + Custom796 = 0x0FE0031C, + Custom797 = 0x0FE0031D, + Custom798 = 0x0FE0031E, + Custom799 = 0x0FE0031F, + Custom800 = 0x0FE00320, + Custom801 = 0x0FE00321, + Custom802 = 0x0FE00322, + Custom803 = 0x0FE00323, + Custom804 = 0x0FE00324, + Custom805 = 0x0FE00325, + Custom806 = 0x0FE00326, + Custom807 = 0x0FE00327, + Custom808 = 0x0FE00328, + Custom809 = 0x0FE00329, + Custom810 = 0x0FE0032A, + Custom811 = 0x0FE0032B, + Custom812 = 0x0FE0032C, + Custom813 = 0x0FE0032D, + Custom814 = 0x0FE0032E, + Custom815 = 0x0FE0032F, + Custom816 = 0x0FE00330, + Custom817 = 0x0FE00331, + Custom818 = 0x0FE00332, + Custom819 = 0x0FE00333, + Custom820 = 0x0FE00334, + Custom821 = 0x0FE00335, + Custom822 = 0x0FE00336, + Custom823 = 0x0FE00337, + Custom824 = 0x0FE00338, + Custom825 = 0x0FE00339, + Custom826 = 0x0FE0033A, + Custom827 = 0x0FE0033B, + Custom828 = 0x0FE0033C, + Custom829 = 0x0FE0033D, + Custom830 = 0x0FE0033E, + Custom831 = 0x0FE0033F, + Custom832 = 0x0FE00340, + Custom833 = 0x0FE00341, + Custom834 = 0x0FE00342, + Custom835 = 0x0FE00343, + Custom836 = 0x0FE00344, + Custom837 = 0x0FE00345, + Custom838 = 0x0FE00346, + Custom839 = 0x0FE00347, + Custom840 = 0x0FE00348, + Custom841 = 0x0FE00349, + Custom842 = 0x0FE0034A, + Custom843 = 0x0FE0034B, + Custom844 = 0x0FE0034C, + Custom845 = 0x0FE0034D, + Custom846 = 0x0FE0034E, + Custom847 = 0x0FE0034F, + Custom848 = 0x0FE00350, + Custom849 = 0x0FE00351, + Custom850 = 0x0FE00352, + Custom851 = 0x0FE00353, + Custom852 = 0x0FE00354, + Custom853 = 0x0FE00355, + Custom854 = 0x0FE00356, + Custom855 = 0x0FE00357, + Custom856 = 0x0FE00358, + Custom857 = 0x0FE00359, + Custom858 = 0x0FE0035A, + Custom859 = 0x0FE0035B, + Custom860 = 0x0FE0035C, + Custom861 = 0x0FE0035D, + Custom862 = 0x0FE0035E, + Custom863 = 0x0FE0035F, + Custom864 = 0x0FE00360, + Custom865 = 0x0FE00361, + Custom866 = 0x0FE00362, + Custom867 = 0x0FE00363, + Custom868 = 0x0FE00364, + Custom869 = 0x0FE00365, + Custom870 = 0x0FE00366, + Custom871 = 0x0FE00367, + Custom872 = 0x0FE00368, + Custom873 = 0x0FE00369, + Custom874 = 0x0FE0036A, + Custom875 = 0x0FE0036B, + Custom876 = 0x0FE0036C, + Custom877 = 0x0FE0036D, + Custom878 = 0x0FE0036E, + Custom879 = 0x0FE0036F, + Custom880 = 0x0FE00370, + Custom881 = 0x0FE00371, + Custom882 = 0x0FE00372, + Custom883 = 0x0FE00373, + Custom884 = 0x0FE00374, + Custom885 = 0x0FE00375, + Custom886 = 0x0FE00376, + Custom887 = 0x0FE00377, + Custom888 = 0x0FE00378, + Custom889 = 0x0FE00379, + Custom890 = 0x0FE0037A, + Custom891 = 0x0FE0037B, + Custom892 = 0x0FE0037C, + Custom893 = 0x0FE0037D, + Custom894 = 0x0FE0037E, + Custom895 = 0x0FE0037F, + Custom896 = 0x0FE00380, + Custom897 = 0x0FE00381, + Custom898 = 0x0FE00382, + Custom899 = 0x0FE00383, + Custom900 = 0x0FE00384, + Custom901 = 0x0FE00385, + Custom902 = 0x0FE00386, + Custom903 = 0x0FE00387, + Custom904 = 0x0FE00388, + Custom905 = 0x0FE00389, + Custom906 = 0x0FE0038A, + Custom907 = 0x0FE0038B, + Custom908 = 0x0FE0038C, + Custom909 = 0x0FE0038D, + Custom910 = 0x0FE0038E, + Custom911 = 0x0FE0038F, + Custom912 = 0x0FE00390, + Custom913 = 0x0FE00391, + Custom914 = 0x0FE00392, + Custom915 = 0x0FE00393, + Custom916 = 0x0FE00394, + Custom917 = 0x0FE00395, + Custom918 = 0x0FE00396, + Custom919 = 0x0FE00397, + Custom920 = 0x0FE00398, + Custom921 = 0x0FE00399, + Custom922 = 0x0FE0039A, + Custom923 = 0x0FE0039B, + Custom924 = 0x0FE0039C, + Custom925 = 0x0FE0039D, + Custom926 = 0x0FE0039E, + Custom927 = 0x0FE0039F, + Custom928 = 0x0FE003A0, + Custom929 = 0x0FE003A1, + Custom930 = 0x0FE003A2, + Custom931 = 0x0FE003A3, + Custom932 = 0x0FE003A4, + Custom933 = 0x0FE003A5, + Custom934 = 0x0FE003A6, + Custom935 = 0x0FE003A7, + Custom936 = 0x0FE003A8, + Custom937 = 0x0FE003A9, + Custom938 = 0x0FE003AA, + Custom939 = 0x0FE003AB, + Custom940 = 0x0FE003AC, + Custom941 = 0x0FE003AD, + Custom942 = 0x0FE003AE, + Custom943 = 0x0FE003AF, + Custom944 = 0x0FE003B0, + Custom945 = 0x0FE003B1, + Custom946 = 0x0FE003B2, + Custom947 = 0x0FE003B3, + Custom948 = 0x0FE003B4, + Custom949 = 0x0FE003B5, + Custom950 = 0x0FE003B6, + Custom951 = 0x0FE003B7, + Custom952 = 0x0FE003B8, + Custom953 = 0x0FE003B9, + Custom954 = 0x0FE003BA, + Custom955 = 0x0FE003BB, + Custom956 = 0x0FE003BC, + Custom957 = 0x0FE003BD, + Custom958 = 0x0FE003BE, + Custom959 = 0x0FE003BF, + Custom960 = 0x0FE003C0, + Custom961 = 0x0FE003C1, + Custom962 = 0x0FE003C2, + Custom963 = 0x0FE003C3, + Custom964 = 0x0FE003C4, + Custom965 = 0x0FE003C5, + Custom966 = 0x0FE003C6, + Custom967 = 0x0FE003C7, + Custom968 = 0x0FE003C8, + Custom969 = 0x0FE003C9, + Custom970 = 0x0FE003CA, + Custom971 = 0x0FE003CB, + Custom972 = 0x0FE003CC, + Custom973 = 0x0FE003CD, + Custom974 = 0x0FE003CE, + Custom975 = 0x0FE003CF, + Custom976 = 0x0FE003D0, + Custom977 = 0x0FE003D1, + Custom978 = 0x0FE003D2, + Custom979 = 0x0FE003D3, + Custom980 = 0x0FE003D4, + Custom981 = 0x0FE003D5, + Custom982 = 0x0FE003D6, + Custom983 = 0x0FE003D7, + Custom984 = 0x0FE003D8, + Custom985 = 0x0FE003D9, + Custom986 = 0x0FE003DA, + Custom987 = 0x0FE003DB, + Custom988 = 0x0FE003DC, + Custom989 = 0x0FE003DD, + Custom990 = 0x0FE003DE, + Custom991 = 0x0FE003DF, + Custom992 = 0x0FE003E0, + Custom993 = 0x0FE003E1, + Custom994 = 0x0FE003E2, + Custom995 = 0x0FE003E3, + Custom996 = 0x0FE003E4, + Custom997 = 0x0FE003E5, + Custom998 = 0x0FE003E6, + Custom999 = 0x0FE003E7, + Custom1000 = 0x0FE003E8, + Custom1001 = 0x0FE003E9, + Custom1002 = 0x0FE003EA, + Custom1003 = 0x0FE003EB, + Custom1004 = 0x0FE003EC, + Custom1005 = 0x0FE003ED, + Custom1006 = 0x0FE003EE, + Custom1007 = 0x0FE003EF, + Custom1008 = 0x0FE003F0, + Custom1009 = 0x0FE003F1, + Custom1010 = 0x0FE003F2, + Custom1011 = 0x0FE003F3, + Custom1012 = 0x0FE003F4, + Custom1013 = 0x0FE003F5, + Custom1014 = 0x0FE003F6, + Custom1015 = 0x0FE003F7, + Custom1016 = 0x0FE003F8, + Custom1017 = 0x0FE003F9, + Custom1018 = 0x0FE003FA, + Custom1019 = 0x0FE003FB, + Custom1020 = 0x0FE003FC, + Custom1021 = 0x0FE003FD, + Custom1022 = 0x0FE003FE, + Custom1023 = 0x0FE003FF, + Custom1024 = 0x0FE00400, - /*### Custom ###*/ - Custom1 = 0x0FF00001, - Custom2 = 0x0FF00002, - Custom3 = 0x0FF00003, - Custom4 = 0x0FF00004, - Custom5 = 0x0FF00005, - Custom6 = 0x0FF00006, - Custom7 = 0x0FF00007, - Custom8 = 0x0FF00008, - Custom9 = 0x0FF00009, - Custom10 = 0x0FF0000A, - Custom11 = 0x0FF0000B, - Custom12 = 0x0FF0000C, - Custom13 = 0x0FF0000D, - Custom14 = 0x0FF0000E, - Custom15 = 0x0FF0000F, - Custom16 = 0x0FF00010, - Custom17 = 0x0FF00011, - Custom18 = 0x0FF00012, - Custom19 = 0x0FF00013, - Custom20 = 0x0FF00014, - Custom21 = 0x0FF00015, - Custom22 = 0x0FF00016, - Custom23 = 0x0FF00017, - Custom24 = 0x0FF00018, - Custom25 = 0x0FF00019, - Custom26 = 0x0FF0001A, - Custom27 = 0x0FF0001B, - Custom28 = 0x0FF0001C, - Custom29 = 0x0FF0001D, - Custom30 = 0x0FF0001E, - Custom31 = 0x0FF0001F, - Custom32 = 0x0FF00020, - Custom33 = 0x0FF00021, - Custom34 = 0x0FF00022, - Custom35 = 0x0FF00023, - Custom36 = 0x0FF00024, - Custom37 = 0x0FF00025, - Custom38 = 0x0FF00026, - Custom39 = 0x0FF00027, - Custom40 = 0x0FF00028, - Custom41 = 0x0FF00029, - Custom42 = 0x0FF0002A, - Custom43 = 0x0FF0002B, - Custom44 = 0x0FF0002C, - Custom45 = 0x0FF0002D, - Custom46 = 0x0FF0002E, - Custom47 = 0x0FF0002F, - Custom48 = 0x0FF00030, - Custom49 = 0x0FF00031, - Custom50 = 0x0FF00032, - Custom51 = 0x0FF00033, - Custom52 = 0x0FF00034, - Custom53 = 0x0FF00035, - Custom54 = 0x0FF00036, - Custom55 = 0x0FF00037, - Custom56 = 0x0FF00038, - Custom57 = 0x0FF00039, - Custom58 = 0x0FF0003A, - Custom59 = 0x0FF0003B, - Custom60 = 0x0FF0003C, - Custom61 = 0x0FF0003D, - Custom62 = 0x0FF0003E, - Custom63 = 0x0FF0003F, - Custom64 = 0x0FF00040, - Custom65 = 0x0FF00041, - Custom66 = 0x0FF00042, - Custom67 = 0x0FF00043, - Custom68 = 0x0FF00044, - Custom69 = 0x0FF00045, - Custom70 = 0x0FF00046, - Custom71 = 0x0FF00047, - Custom72 = 0x0FF00048, - Custom73 = 0x0FF00049, - Custom74 = 0x0FF0004A, - Custom75 = 0x0FF0004B, - Custom76 = 0x0FF0004C, - Custom77 = 0x0FF0004D, - Custom78 = 0x0FF0004E, - Custom79 = 0x0FF0004F, - Custom80 = 0x0FF00050, - Custom81 = 0x0FF00051, - Custom82 = 0x0FF00052, - Custom83 = 0x0FF00053, - Custom84 = 0x0FF00054, - Custom85 = 0x0FF00055, - Custom86 = 0x0FF00056, - Custom87 = 0x0FF00057, - Custom88 = 0x0FF00058, - Custom89 = 0x0FF00059, - Custom90 = 0x0FF0005A, - Custom91 = 0x0FF0005B, - Custom92 = 0x0FF0005C, - Custom93 = 0x0FF0005D, - Custom94 = 0x0FF0005E, - Custom95 = 0x0FF0005F, - Custom96 = 0x0FF00060, - Custom97 = 0x0FF00061, - Custom98 = 0x0FF00062, - Custom99 = 0x0FF00063, - Custom100 = 0x0FF00064, - Custom101 = 0x0FF00065, - Custom102 = 0x0FF00066, - Custom103 = 0x0FF00067, - Custom104 = 0x0FF00068, - Custom105 = 0x0FF00069, - Custom106 = 0x0FF0006A, - Custom107 = 0x0FF0006B, - Custom108 = 0x0FF0006C, - Custom109 = 0x0FF0006D, - Custom110 = 0x0FF0006E, - Custom111 = 0x0FF0006F, - Custom112 = 0x0FF00070, - Custom113 = 0x0FF00071, - Custom114 = 0x0FF00072, - Custom115 = 0x0FF00073, - Custom116 = 0x0FF00074, - Custom117 = 0x0FF00075, - Custom118 = 0x0FF00076, - Custom119 = 0x0FF00077, - Custom120 = 0x0FF00078, - Custom121 = 0x0FF00079, - Custom122 = 0x0FF0007A, - Custom123 = 0x0FF0007B, - Custom124 = 0x0FF0007C, - Custom125 = 0x0FF0007D, - Custom126 = 0x0FF0007E, - Custom127 = 0x0FF0007F, - Custom128 = 0x0FF00080, - } -} + /*### Unknown ###*/ + Unknown1 = 0x0FF00001, + Unknown2 = 0x0FF00002, + Unknown3 = 0x0FF00003, + Unknown4 = 0x0FF00004, + Unknown5 = 0x0FF00005, + Unknown6 = 0x0FF00006, + Unknown7 = 0x0FF00007, + Unknown8 = 0x0FF00008, + Unknown9 = 0x0FF00009, + Unknown10 = 0x0FF0000A, + Unknown11 = 0x0FF0000B, + Unknown12 = 0x0FF0000C, + Unknown13 = 0x0FF0000D, + Unknown14 = 0x0FF0000E, + Unknown15 = 0x0FF0000F, + Unknown16 = 0x0FF00010, + Unknown17 = 0x0FF00011, + Unknown18 = 0x0FF00012, + Unknown19 = 0x0FF00013, + Unknown20 = 0x0FF00014, + Unknown21 = 0x0FF00015, + Unknown22 = 0x0FF00016, + Unknown23 = 0x0FF00017, + Unknown24 = 0x0FF00018, + Unknown25 = 0x0FF00019, + Unknown26 = 0x0FF0001A, + Unknown27 = 0x0FF0001B, + Unknown28 = 0x0FF0001C, + Unknown29 = 0x0FF0001D, + Unknown30 = 0x0FF0001E, + Unknown31 = 0x0FF0001F, + Unknown32 = 0x0FF00020, + Unknown33 = 0x0FF00021, + Unknown34 = 0x0FF00022, + Unknown35 = 0x0FF00023, + Unknown36 = 0x0FF00024, + Unknown37 = 0x0FF00025, + Unknown38 = 0x0FF00026, + Unknown39 = 0x0FF00027, + Unknown40 = 0x0FF00028, + Unknown41 = 0x0FF00029, + Unknown42 = 0x0FF0002A, + Unknown43 = 0x0FF0002B, + Unknown44 = 0x0FF0002C, + Unknown45 = 0x0FF0002D, + Unknown46 = 0x0FF0002E, + Unknown47 = 0x0FF0002F, + Unknown48 = 0x0FF00030, + Unknown49 = 0x0FF00031, + Unknown50 = 0x0FF00032, + Unknown51 = 0x0FF00033, + Unknown52 = 0x0FF00034, + Unknown53 = 0x0FF00035, + Unknown54 = 0x0FF00036, + Unknown55 = 0x0FF00037, + Unknown56 = 0x0FF00038, + Unknown57 = 0x0FF00039, + Unknown58 = 0x0FF0003A, + Unknown59 = 0x0FF0003B, + Unknown60 = 0x0FF0003C, + Unknown61 = 0x0FF0003D, + Unknown62 = 0x0FF0003E, + Unknown63 = 0x0FF0003F, + Unknown64 = 0x0FF00040, + Unknown65 = 0x0FF00041, + Unknown66 = 0x0FF00042, + Unknown67 = 0x0FF00043, + Unknown68 = 0x0FF00044, + Unknown69 = 0x0FF00045, + Unknown70 = 0x0FF00046, + Unknown71 = 0x0FF00047, + Unknown72 = 0x0FF00048, + Unknown73 = 0x0FF00049, + Unknown74 = 0x0FF0004A, + Unknown75 = 0x0FF0004B, + Unknown76 = 0x0FF0004C, + Unknown77 = 0x0FF0004D, + Unknown78 = 0x0FF0004E, + Unknown79 = 0x0FF0004F, + Unknown80 = 0x0FF00050, + Unknown81 = 0x0FF00051, + Unknown82 = 0x0FF00052, + Unknown83 = 0x0FF00053, + Unknown84 = 0x0FF00054, + Unknown85 = 0x0FF00055, + Unknown86 = 0x0FF00056, + Unknown87 = 0x0FF00057, + Unknown88 = 0x0FF00058, + Unknown89 = 0x0FF00059, + Unknown90 = 0x0FF0005A, + Unknown91 = 0x0FF0005B, + Unknown92 = 0x0FF0005C, + Unknown93 = 0x0FF0005D, + Unknown94 = 0x0FF0005E, + Unknown95 = 0x0FF0005F, + Unknown96 = 0x0FF00060, + Unknown97 = 0x0FF00061, + Unknown98 = 0x0FF00062, + Unknown99 = 0x0FF00063, + Unknown100 = 0x0FF00064, + Unknown101 = 0x0FF00065, + Unknown102 = 0x0FF00066, + Unknown103 = 0x0FF00067, + Unknown104 = 0x0FF00068, + Unknown105 = 0x0FF00069, + Unknown106 = 0x0FF0006A, + Unknown107 = 0x0FF0006B, + Unknown108 = 0x0FF0006C, + Unknown109 = 0x0FF0006D, + Unknown110 = 0x0FF0006E, + Unknown111 = 0x0FF0006F, + Unknown112 = 0x0FF00070, + Unknown113 = 0x0FF00071, + Unknown114 = 0x0FF00072, + Unknown115 = 0x0FF00073, + Unknown116 = 0x0FF00074, + Unknown117 = 0x0FF00075, + Unknown118 = 0x0FF00076, + Unknown119 = 0x0FF00077, + Unknown120 = 0x0FF00078, + Unknown121 = 0x0FF00079, + Unknown122 = 0x0FF0007A, + Unknown123 = 0x0FF0007B, + Unknown124 = 0x0FF0007C, + Unknown125 = 0x0FF0007D, + Unknown126 = 0x0FF0007E, + Unknown127 = 0x0FF0007F, + Unknown128 = 0x0FF00080, + Unknown129 = 0x0FF00081, + Unknown130 = 0x0FF00082, + Unknown131 = 0x0FF00083, + Unknown132 = 0x0FF00084, + Unknown133 = 0x0FF00085, + Unknown134 = 0x0FF00086, + Unknown135 = 0x0FF00087, + Unknown136 = 0x0FF00088, + Unknown137 = 0x0FF00089, + Unknown138 = 0x0FF0008A, + Unknown139 = 0x0FF0008B, + Unknown140 = 0x0FF0008C, + Unknown141 = 0x0FF0008D, + Unknown142 = 0x0FF0008E, + Unknown143 = 0x0FF0008F, + Unknown144 = 0x0FF00090, + Unknown145 = 0x0FF00091, + Unknown146 = 0x0FF00092, + Unknown147 = 0x0FF00093, + Unknown148 = 0x0FF00094, + Unknown149 = 0x0FF00095, + Unknown150 = 0x0FF00096, + Unknown151 = 0x0FF00097, + Unknown152 = 0x0FF00098, + Unknown153 = 0x0FF00099, + Unknown154 = 0x0FF0009A, + Unknown155 = 0x0FF0009B, + Unknown156 = 0x0FF0009C, + Unknown157 = 0x0FF0009D, + Unknown158 = 0x0FF0009E, + Unknown159 = 0x0FF0009F, + Unknown160 = 0x0FF000A0, + Unknown161 = 0x0FF000A1, + Unknown162 = 0x0FF000A2, + Unknown163 = 0x0FF000A3, + Unknown164 = 0x0FF000A4, + Unknown165 = 0x0FF000A5, + Unknown166 = 0x0FF000A6, + Unknown167 = 0x0FF000A7, + Unknown168 = 0x0FF000A8, + Unknown169 = 0x0FF000A9, + Unknown170 = 0x0FF000AA, + Unknown171 = 0x0FF000AB, + Unknown172 = 0x0FF000AC, + Unknown173 = 0x0FF000AD, + Unknown174 = 0x0FF000AE, + Unknown175 = 0x0FF000AF, + Unknown176 = 0x0FF000B0, + Unknown177 = 0x0FF000B1, + Unknown178 = 0x0FF000B2, + Unknown179 = 0x0FF000B3, + Unknown180 = 0x0FF000B4, + Unknown181 = 0x0FF000B5, + Unknown182 = 0x0FF000B6, + Unknown183 = 0x0FF000B7, + Unknown184 = 0x0FF000B8, + Unknown185 = 0x0FF000B9, + Unknown186 = 0x0FF000BA, + Unknown187 = 0x0FF000BB, + Unknown188 = 0x0FF000BC, + Unknown189 = 0x0FF000BD, + Unknown190 = 0x0FF000BE, + Unknown191 = 0x0FF000BF, + Unknown192 = 0x0FF000C0, + Unknown193 = 0x0FF000C1, + Unknown194 = 0x0FF000C2, + Unknown195 = 0x0FF000C3, + Unknown196 = 0x0FF000C4, + Unknown197 = 0x0FF000C5, + Unknown198 = 0x0FF000C6, + Unknown199 = 0x0FF000C7, + Unknown200 = 0x0FF000C8, + Unknown201 = 0x0FF000C9, + Unknown202 = 0x0FF000CA, + Unknown203 = 0x0FF000CB, + Unknown204 = 0x0FF000CC, + Unknown205 = 0x0FF000CD, + Unknown206 = 0x0FF000CE, + Unknown207 = 0x0FF000CF, + Unknown208 = 0x0FF000D0, + Unknown209 = 0x0FF000D1, + Unknown210 = 0x0FF000D2, + Unknown211 = 0x0FF000D3, + Unknown212 = 0x0FF000D4, + Unknown213 = 0x0FF000D5, + Unknown214 = 0x0FF000D6, + Unknown215 = 0x0FF000D7, + Unknown216 = 0x0FF000D8, + Unknown217 = 0x0FF000D9, + Unknown218 = 0x0FF000DA, + Unknown219 = 0x0FF000DB, + Unknown220 = 0x0FF000DC, + Unknown221 = 0x0FF000DD, + Unknown222 = 0x0FF000DE, + Unknown223 = 0x0FF000DF, + Unknown224 = 0x0FF000E0, + Unknown225 = 0x0FF000E1, + Unknown226 = 0x0FF000E2, + Unknown227 = 0x0FF000E3, + Unknown228 = 0x0FF000E4, + Unknown229 = 0x0FF000E5, + Unknown230 = 0x0FF000E6, + Unknown231 = 0x0FF000E7, + Unknown232 = 0x0FF000E8, + Unknown233 = 0x0FF000E9, + Unknown234 = 0x0FF000EA, + Unknown235 = 0x0FF000EB, + Unknown236 = 0x0FF000EC, + Unknown237 = 0x0FF000ED, + Unknown238 = 0x0FF000EE, + Unknown239 = 0x0FF000EF, + Unknown240 = 0x0FF000F0, + Unknown241 = 0x0FF000F1, + Unknown242 = 0x0FF000F2, + Unknown243 = 0x0FF000F3, + Unknown244 = 0x0FF000F4, + Unknown245 = 0x0FF000F5, + Unknown246 = 0x0FF000F6, + Unknown247 = 0x0FF000F7, + Unknown248 = 0x0FF000F8, + Unknown249 = 0x0FF000F9, + Unknown250 = 0x0FF000FA, + Unknown251 = 0x0FF000FB, + Unknown252 = 0x0FF000FC, + Unknown253 = 0x0FF000FD, + Unknown254 = 0x0FF000FE, + Unknown255 = 0x0FF000FF, + Unknown256 = 0x0FF00100, + Unknown257 = 0x0FF00101, + Unknown258 = 0x0FF00102, + Unknown259 = 0x0FF00103, + Unknown260 = 0x0FF00104, + Unknown261 = 0x0FF00105, + Unknown262 = 0x0FF00106, + Unknown263 = 0x0FF00107, + Unknown264 = 0x0FF00108, + Unknown265 = 0x0FF00109, + Unknown266 = 0x0FF0010A, + Unknown267 = 0x0FF0010B, + Unknown268 = 0x0FF0010C, + Unknown269 = 0x0FF0010D, + Unknown270 = 0x0FF0010E, + Unknown271 = 0x0FF0010F, + Unknown272 = 0x0FF00110, + Unknown273 = 0x0FF00111, + Unknown274 = 0x0FF00112, + Unknown275 = 0x0FF00113, + Unknown276 = 0x0FF00114, + Unknown277 = 0x0FF00115, + Unknown278 = 0x0FF00116, + Unknown279 = 0x0FF00117, + Unknown280 = 0x0FF00118, + Unknown281 = 0x0FF00119, + Unknown282 = 0x0FF0011A, + Unknown283 = 0x0FF0011B, + Unknown284 = 0x0FF0011C, + Unknown285 = 0x0FF0011D, + Unknown286 = 0x0FF0011E, + Unknown287 = 0x0FF0011F, + Unknown288 = 0x0FF00120, + Unknown289 = 0x0FF00121, + Unknown290 = 0x0FF00122, + Unknown291 = 0x0FF00123, + Unknown292 = 0x0FF00124, + Unknown293 = 0x0FF00125, + Unknown294 = 0x0FF00126, + Unknown295 = 0x0FF00127, + Unknown296 = 0x0FF00128, + Unknown297 = 0x0FF00129, + Unknown298 = 0x0FF0012A, + Unknown299 = 0x0FF0012B, + Unknown300 = 0x0FF0012C, + Unknown301 = 0x0FF0012D, + Unknown302 = 0x0FF0012E, + Unknown303 = 0x0FF0012F, + Unknown304 = 0x0FF00130, + Unknown305 = 0x0FF00131, + Unknown306 = 0x0FF00132, + Unknown307 = 0x0FF00133, + Unknown308 = 0x0FF00134, + Unknown309 = 0x0FF00135, + Unknown310 = 0x0FF00136, + Unknown311 = 0x0FF00137, + Unknown312 = 0x0FF00138, + Unknown313 = 0x0FF00139, + Unknown314 = 0x0FF0013A, + Unknown315 = 0x0FF0013B, + Unknown316 = 0x0FF0013C, + Unknown317 = 0x0FF0013D, + Unknown318 = 0x0FF0013E, + Unknown319 = 0x0FF0013F, + Unknown320 = 0x0FF00140, + Unknown321 = 0x0FF00141, + Unknown322 = 0x0FF00142, + Unknown323 = 0x0FF00143, + Unknown324 = 0x0FF00144, + Unknown325 = 0x0FF00145, + Unknown326 = 0x0FF00146, + Unknown327 = 0x0FF00147, + Unknown328 = 0x0FF00148, + Unknown329 = 0x0FF00149, + Unknown330 = 0x0FF0014A, + Unknown331 = 0x0FF0014B, + Unknown332 = 0x0FF0014C, + Unknown333 = 0x0FF0014D, + Unknown334 = 0x0FF0014E, + Unknown335 = 0x0FF0014F, + Unknown336 = 0x0FF00150, + Unknown337 = 0x0FF00151, + Unknown338 = 0x0FF00152, + Unknown339 = 0x0FF00153, + Unknown340 = 0x0FF00154, + Unknown341 = 0x0FF00155, + Unknown342 = 0x0FF00156, + Unknown343 = 0x0FF00157, + Unknown344 = 0x0FF00158, + Unknown345 = 0x0FF00159, + Unknown346 = 0x0FF0015A, + Unknown347 = 0x0FF0015B, + Unknown348 = 0x0FF0015C, + Unknown349 = 0x0FF0015D, + Unknown350 = 0x0FF0015E, + Unknown351 = 0x0FF0015F, + Unknown352 = 0x0FF00160, + Unknown353 = 0x0FF00161, + Unknown354 = 0x0FF00162, + Unknown355 = 0x0FF00163, + Unknown356 = 0x0FF00164, + Unknown357 = 0x0FF00165, + Unknown358 = 0x0FF00166, + Unknown359 = 0x0FF00167, + Unknown360 = 0x0FF00168, + Unknown361 = 0x0FF00169, + Unknown362 = 0x0FF0016A, + Unknown363 = 0x0FF0016B, + Unknown364 = 0x0FF0016C, + Unknown365 = 0x0FF0016D, + Unknown366 = 0x0FF0016E, + Unknown367 = 0x0FF0016F, + Unknown368 = 0x0FF00170, + Unknown369 = 0x0FF00171, + Unknown370 = 0x0FF00172, + Unknown371 = 0x0FF00173, + Unknown372 = 0x0FF00174, + Unknown373 = 0x0FF00175, + Unknown374 = 0x0FF00176, + Unknown375 = 0x0FF00177, + Unknown376 = 0x0FF00178, + Unknown377 = 0x0FF00179, + Unknown378 = 0x0FF0017A, + Unknown379 = 0x0FF0017B, + Unknown380 = 0x0FF0017C, + Unknown381 = 0x0FF0017D, + Unknown382 = 0x0FF0017E, + Unknown383 = 0x0FF0017F, + Unknown384 = 0x0FF00180, + Unknown385 = 0x0FF00181, + Unknown386 = 0x0FF00182, + Unknown387 = 0x0FF00183, + Unknown388 = 0x0FF00184, + Unknown389 = 0x0FF00185, + Unknown390 = 0x0FF00186, + Unknown391 = 0x0FF00187, + Unknown392 = 0x0FF00188, + Unknown393 = 0x0FF00189, + Unknown394 = 0x0FF0018A, + Unknown395 = 0x0FF0018B, + Unknown396 = 0x0FF0018C, + Unknown397 = 0x0FF0018D, + Unknown398 = 0x0FF0018E, + Unknown399 = 0x0FF0018F, + Unknown400 = 0x0FF00190, + Unknown401 = 0x0FF00191, + Unknown402 = 0x0FF00192, + Unknown403 = 0x0FF00193, + Unknown404 = 0x0FF00194, + Unknown405 = 0x0FF00195, + Unknown406 = 0x0FF00196, + Unknown407 = 0x0FF00197, + Unknown408 = 0x0FF00198, + Unknown409 = 0x0FF00199, + Unknown410 = 0x0FF0019A, + Unknown411 = 0x0FF0019B, + Unknown412 = 0x0FF0019C, + Unknown413 = 0x0FF0019D, + Unknown414 = 0x0FF0019E, + Unknown415 = 0x0FF0019F, + Unknown416 = 0x0FF001A0, + Unknown417 = 0x0FF001A1, + Unknown418 = 0x0FF001A2, + Unknown419 = 0x0FF001A3, + Unknown420 = 0x0FF001A4, + Unknown421 = 0x0FF001A5, + Unknown422 = 0x0FF001A6, + Unknown423 = 0x0FF001A7, + Unknown424 = 0x0FF001A8, + Unknown425 = 0x0FF001A9, + Unknown426 = 0x0FF001AA, + Unknown427 = 0x0FF001AB, + Unknown428 = 0x0FF001AC, + Unknown429 = 0x0FF001AD, + Unknown430 = 0x0FF001AE, + Unknown431 = 0x0FF001AF, + Unknown432 = 0x0FF001B0, + Unknown433 = 0x0FF001B1, + Unknown434 = 0x0FF001B2, + Unknown435 = 0x0FF001B3, + Unknown436 = 0x0FF001B4, + Unknown437 = 0x0FF001B5, + Unknown438 = 0x0FF001B6, + Unknown439 = 0x0FF001B7, + Unknown440 = 0x0FF001B8, + Unknown441 = 0x0FF001B9, + Unknown442 = 0x0FF001BA, + Unknown443 = 0x0FF001BB, + Unknown444 = 0x0FF001BC, + Unknown445 = 0x0FF001BD, + Unknown446 = 0x0FF001BE, + Unknown447 = 0x0FF001BF, + Unknown448 = 0x0FF001C0, + Unknown449 = 0x0FF001C1, + Unknown450 = 0x0FF001C2, + Unknown451 = 0x0FF001C3, + Unknown452 = 0x0FF001C4, + Unknown453 = 0x0FF001C5, + Unknown454 = 0x0FF001C6, + Unknown455 = 0x0FF001C7, + Unknown456 = 0x0FF001C8, + Unknown457 = 0x0FF001C9, + Unknown458 = 0x0FF001CA, + Unknown459 = 0x0FF001CB, + Unknown460 = 0x0FF001CC, + Unknown461 = 0x0FF001CD, + Unknown462 = 0x0FF001CE, + Unknown463 = 0x0FF001CF, + Unknown464 = 0x0FF001D0, + Unknown465 = 0x0FF001D1, + Unknown466 = 0x0FF001D2, + Unknown467 = 0x0FF001D3, + Unknown468 = 0x0FF001D4, + Unknown469 = 0x0FF001D5, + Unknown470 = 0x0FF001D6, + Unknown471 = 0x0FF001D7, + Unknown472 = 0x0FF001D8, + Unknown473 = 0x0FF001D9, + Unknown474 = 0x0FF001DA, + Unknown475 = 0x0FF001DB, + Unknown476 = 0x0FF001DC, + Unknown477 = 0x0FF001DD, + Unknown478 = 0x0FF001DE, + Unknown479 = 0x0FF001DF, + Unknown480 = 0x0FF001E0, + Unknown481 = 0x0FF001E1, + Unknown482 = 0x0FF001E2, + Unknown483 = 0x0FF001E3, + Unknown484 = 0x0FF001E4, + Unknown485 = 0x0FF001E5, + Unknown486 = 0x0FF001E6, + Unknown487 = 0x0FF001E7, + Unknown488 = 0x0FF001E8, + Unknown489 = 0x0FF001E9, + Unknown490 = 0x0FF001EA, + Unknown491 = 0x0FF001EB, + Unknown492 = 0x0FF001EC, + Unknown493 = 0x0FF001ED, + Unknown494 = 0x0FF001EE, + Unknown495 = 0x0FF001EF, + Unknown496 = 0x0FF001F0, + Unknown497 = 0x0FF001F1, + Unknown498 = 0x0FF001F2, + Unknown499 = 0x0FF001F3, + Unknown500 = 0x0FF001F4, + Unknown501 = 0x0FF001F5, + Unknown502 = 0x0FF001F6, + Unknown503 = 0x0FF001F7, + Unknown504 = 0x0FF001F8, + Unknown505 = 0x0FF001F9, + Unknown506 = 0x0FF001FA, + Unknown507 = 0x0FF001FB, + Unknown508 = 0x0FF001FC, + Unknown509 = 0x0FF001FD, + Unknown510 = 0x0FF001FE, + Unknown511 = 0x0FF001FF, + Unknown512 = 0x0FF00200, + Unknown513 = 0x0FF00201, + Unknown514 = 0x0FF00202, + Unknown515 = 0x0FF00203, + Unknown516 = 0x0FF00204, + Unknown517 = 0x0FF00205, + Unknown518 = 0x0FF00206, + Unknown519 = 0x0FF00207, + Unknown520 = 0x0FF00208, + Unknown521 = 0x0FF00209, + Unknown522 = 0x0FF0020A, + Unknown523 = 0x0FF0020B, + Unknown524 = 0x0FF0020C, + Unknown525 = 0x0FF0020D, + Unknown526 = 0x0FF0020E, + Unknown527 = 0x0FF0020F, + Unknown528 = 0x0FF00210, + Unknown529 = 0x0FF00211, + Unknown530 = 0x0FF00212, + Unknown531 = 0x0FF00213, + Unknown532 = 0x0FF00214, + Unknown533 = 0x0FF00215, + Unknown534 = 0x0FF00216, + Unknown535 = 0x0FF00217, + Unknown536 = 0x0FF00218, + Unknown537 = 0x0FF00219, + Unknown538 = 0x0FF0021A, + Unknown539 = 0x0FF0021B, + Unknown540 = 0x0FF0021C, + Unknown541 = 0x0FF0021D, + Unknown542 = 0x0FF0021E, + Unknown543 = 0x0FF0021F, + Unknown544 = 0x0FF00220, + Unknown545 = 0x0FF00221, + Unknown546 = 0x0FF00222, + Unknown547 = 0x0FF00223, + Unknown548 = 0x0FF00224, + Unknown549 = 0x0FF00225, + Unknown550 = 0x0FF00226, + Unknown551 = 0x0FF00227, + Unknown552 = 0x0FF00228, + Unknown553 = 0x0FF00229, + Unknown554 = 0x0FF0022A, + Unknown555 = 0x0FF0022B, + Unknown556 = 0x0FF0022C, + Unknown557 = 0x0FF0022D, + Unknown558 = 0x0FF0022E, + Unknown559 = 0x0FF0022F, + Unknown560 = 0x0FF00230, + Unknown561 = 0x0FF00231, + Unknown562 = 0x0FF00232, + Unknown563 = 0x0FF00233, + Unknown564 = 0x0FF00234, + Unknown565 = 0x0FF00235, + Unknown566 = 0x0FF00236, + Unknown567 = 0x0FF00237, + Unknown568 = 0x0FF00238, + Unknown569 = 0x0FF00239, + Unknown570 = 0x0FF0023A, + Unknown571 = 0x0FF0023B, + Unknown572 = 0x0FF0023C, + Unknown573 = 0x0FF0023D, + Unknown574 = 0x0FF0023E, + Unknown575 = 0x0FF0023F, + Unknown576 = 0x0FF00240, + Unknown577 = 0x0FF00241, + Unknown578 = 0x0FF00242, + Unknown579 = 0x0FF00243, + Unknown580 = 0x0FF00244, + Unknown581 = 0x0FF00245, + Unknown582 = 0x0FF00246, + Unknown583 = 0x0FF00247, + Unknown584 = 0x0FF00248, + Unknown585 = 0x0FF00249, + Unknown586 = 0x0FF0024A, + Unknown587 = 0x0FF0024B, + Unknown588 = 0x0FF0024C, + Unknown589 = 0x0FF0024D, + Unknown590 = 0x0FF0024E, + Unknown591 = 0x0FF0024F, + Unknown592 = 0x0FF00250, + Unknown593 = 0x0FF00251, + Unknown594 = 0x0FF00252, + Unknown595 = 0x0FF00253, + Unknown596 = 0x0FF00254, + Unknown597 = 0x0FF00255, + Unknown598 = 0x0FF00256, + Unknown599 = 0x0FF00257, + Unknown600 = 0x0FF00258, + Unknown601 = 0x0FF00259, + Unknown602 = 0x0FF0025A, + Unknown603 = 0x0FF0025B, + Unknown604 = 0x0FF0025C, + Unknown605 = 0x0FF0025D, + Unknown606 = 0x0FF0025E, + Unknown607 = 0x0FF0025F, + Unknown608 = 0x0FF00260, + Unknown609 = 0x0FF00261, + Unknown610 = 0x0FF00262, + Unknown611 = 0x0FF00263, + Unknown612 = 0x0FF00264, + Unknown613 = 0x0FF00265, + Unknown614 = 0x0FF00266, + Unknown615 = 0x0FF00267, + Unknown616 = 0x0FF00268, + Unknown617 = 0x0FF00269, + Unknown618 = 0x0FF0026A, + Unknown619 = 0x0FF0026B, + Unknown620 = 0x0FF0026C, + Unknown621 = 0x0FF0026D, + Unknown622 = 0x0FF0026E, + Unknown623 = 0x0FF0026F, + Unknown624 = 0x0FF00270, + Unknown625 = 0x0FF00271, + Unknown626 = 0x0FF00272, + Unknown627 = 0x0FF00273, + Unknown628 = 0x0FF00274, + Unknown629 = 0x0FF00275, + Unknown630 = 0x0FF00276, + Unknown631 = 0x0FF00277, + Unknown632 = 0x0FF00278, + Unknown633 = 0x0FF00279, + Unknown634 = 0x0FF0027A, + Unknown635 = 0x0FF0027B, + Unknown636 = 0x0FF0027C, + Unknown637 = 0x0FF0027D, + Unknown638 = 0x0FF0027E, + Unknown639 = 0x0FF0027F, + Unknown640 = 0x0FF00280, + Unknown641 = 0x0FF00281, + Unknown642 = 0x0FF00282, + Unknown643 = 0x0FF00283, + Unknown644 = 0x0FF00284, + Unknown645 = 0x0FF00285, + Unknown646 = 0x0FF00286, + Unknown647 = 0x0FF00287, + Unknown648 = 0x0FF00288, + Unknown649 = 0x0FF00289, + Unknown650 = 0x0FF0028A, + Unknown651 = 0x0FF0028B, + Unknown652 = 0x0FF0028C, + Unknown653 = 0x0FF0028D, + Unknown654 = 0x0FF0028E, + Unknown655 = 0x0FF0028F, + Unknown656 = 0x0FF00290, + Unknown657 = 0x0FF00291, + Unknown658 = 0x0FF00292, + Unknown659 = 0x0FF00293, + Unknown660 = 0x0FF00294, + Unknown661 = 0x0FF00295, + Unknown662 = 0x0FF00296, + Unknown663 = 0x0FF00297, + Unknown664 = 0x0FF00298, + Unknown665 = 0x0FF00299, + Unknown666 = 0x0FF0029A, + Unknown667 = 0x0FF0029B, + Unknown668 = 0x0FF0029C, + Unknown669 = 0x0FF0029D, + Unknown670 = 0x0FF0029E, + Unknown671 = 0x0FF0029F, + Unknown672 = 0x0FF002A0, + Unknown673 = 0x0FF002A1, + Unknown674 = 0x0FF002A2, + Unknown675 = 0x0FF002A3, + Unknown676 = 0x0FF002A4, + Unknown677 = 0x0FF002A5, + Unknown678 = 0x0FF002A6, + Unknown679 = 0x0FF002A7, + Unknown680 = 0x0FF002A8, + Unknown681 = 0x0FF002A9, + Unknown682 = 0x0FF002AA, + Unknown683 = 0x0FF002AB, + Unknown684 = 0x0FF002AC, + Unknown685 = 0x0FF002AD, + Unknown686 = 0x0FF002AE, + Unknown687 = 0x0FF002AF, + Unknown688 = 0x0FF002B0, + Unknown689 = 0x0FF002B1, + Unknown690 = 0x0FF002B2, + Unknown691 = 0x0FF002B3, + Unknown692 = 0x0FF002B4, + Unknown693 = 0x0FF002B5, + Unknown694 = 0x0FF002B6, + Unknown695 = 0x0FF002B7, + Unknown696 = 0x0FF002B8, + Unknown697 = 0x0FF002B9, + Unknown698 = 0x0FF002BA, + Unknown699 = 0x0FF002BB, + Unknown700 = 0x0FF002BC, + Unknown701 = 0x0FF002BD, + Unknown702 = 0x0FF002BE, + Unknown703 = 0x0FF002BF, + Unknown704 = 0x0FF002C0, + Unknown705 = 0x0FF002C1, + Unknown706 = 0x0FF002C2, + Unknown707 = 0x0FF002C3, + Unknown708 = 0x0FF002C4, + Unknown709 = 0x0FF002C5, + Unknown710 = 0x0FF002C6, + Unknown711 = 0x0FF002C7, + Unknown712 = 0x0FF002C8, + Unknown713 = 0x0FF002C9, + Unknown714 = 0x0FF002CA, + Unknown715 = 0x0FF002CB, + Unknown716 = 0x0FF002CC, + Unknown717 = 0x0FF002CD, + Unknown718 = 0x0FF002CE, + Unknown719 = 0x0FF002CF, + Unknown720 = 0x0FF002D0, + Unknown721 = 0x0FF002D1, + Unknown722 = 0x0FF002D2, + Unknown723 = 0x0FF002D3, + Unknown724 = 0x0FF002D4, + Unknown725 = 0x0FF002D5, + Unknown726 = 0x0FF002D6, + Unknown727 = 0x0FF002D7, + Unknown728 = 0x0FF002D8, + Unknown729 = 0x0FF002D9, + Unknown730 = 0x0FF002DA, + Unknown731 = 0x0FF002DB, + Unknown732 = 0x0FF002DC, + Unknown733 = 0x0FF002DD, + Unknown734 = 0x0FF002DE, + Unknown735 = 0x0FF002DF, + Unknown736 = 0x0FF002E0, + Unknown737 = 0x0FF002E1, + Unknown738 = 0x0FF002E2, + Unknown739 = 0x0FF002E3, + Unknown740 = 0x0FF002E4, + Unknown741 = 0x0FF002E5, + Unknown742 = 0x0FF002E6, + Unknown743 = 0x0FF002E7, + Unknown744 = 0x0FF002E8, + Unknown745 = 0x0FF002E9, + Unknown746 = 0x0FF002EA, + Unknown747 = 0x0FF002EB, + Unknown748 = 0x0FF002EC, + Unknown749 = 0x0FF002ED, + Unknown750 = 0x0FF002EE, + Unknown751 = 0x0FF002EF, + Unknown752 = 0x0FF002F0, + Unknown753 = 0x0FF002F1, + Unknown754 = 0x0FF002F2, + Unknown755 = 0x0FF002F3, + Unknown756 = 0x0FF002F4, + Unknown757 = 0x0FF002F5, + Unknown758 = 0x0FF002F6, + Unknown759 = 0x0FF002F7, + Unknown760 = 0x0FF002F8, + Unknown761 = 0x0FF002F9, + Unknown762 = 0x0FF002FA, + Unknown763 = 0x0FF002FB, + Unknown764 = 0x0FF002FC, + Unknown765 = 0x0FF002FD, + Unknown766 = 0x0FF002FE, + Unknown767 = 0x0FF002FF, + Unknown768 = 0x0FF00300, + Unknown769 = 0x0FF00301, + Unknown770 = 0x0FF00302, + Unknown771 = 0x0FF00303, + Unknown772 = 0x0FF00304, + Unknown773 = 0x0FF00305, + Unknown774 = 0x0FF00306, + Unknown775 = 0x0FF00307, + Unknown776 = 0x0FF00308, + Unknown777 = 0x0FF00309, + Unknown778 = 0x0FF0030A, + Unknown779 = 0x0FF0030B, + Unknown780 = 0x0FF0030C, + Unknown781 = 0x0FF0030D, + Unknown782 = 0x0FF0030E, + Unknown783 = 0x0FF0030F, + Unknown784 = 0x0FF00310, + Unknown785 = 0x0FF00311, + Unknown786 = 0x0FF00312, + Unknown787 = 0x0FF00313, + Unknown788 = 0x0FF00314, + Unknown789 = 0x0FF00315, + Unknown790 = 0x0FF00316, + Unknown791 = 0x0FF00317, + Unknown792 = 0x0FF00318, + Unknown793 = 0x0FF00319, + Unknown794 = 0x0FF0031A, + Unknown795 = 0x0FF0031B, + Unknown796 = 0x0FF0031C, + Unknown797 = 0x0FF0031D, + Unknown798 = 0x0FF0031E, + Unknown799 = 0x0FF0031F, + Unknown800 = 0x0FF00320, + Unknown801 = 0x0FF00321, + Unknown802 = 0x0FF00322, + Unknown803 = 0x0FF00323, + Unknown804 = 0x0FF00324, + Unknown805 = 0x0FF00325, + Unknown806 = 0x0FF00326, + Unknown807 = 0x0FF00327, + Unknown808 = 0x0FF00328, + Unknown809 = 0x0FF00329, + Unknown810 = 0x0FF0032A, + Unknown811 = 0x0FF0032B, + Unknown812 = 0x0FF0032C, + Unknown813 = 0x0FF0032D, + Unknown814 = 0x0FF0032E, + Unknown815 = 0x0FF0032F, + Unknown816 = 0x0FF00330, + Unknown817 = 0x0FF00331, + Unknown818 = 0x0FF00332, + Unknown819 = 0x0FF00333, + Unknown820 = 0x0FF00334, + Unknown821 = 0x0FF00335, + Unknown822 = 0x0FF00336, + Unknown823 = 0x0FF00337, + Unknown824 = 0x0FF00338, + Unknown825 = 0x0FF00339, + Unknown826 = 0x0FF0033A, + Unknown827 = 0x0FF0033B, + Unknown828 = 0x0FF0033C, + Unknown829 = 0x0FF0033D, + Unknown830 = 0x0FF0033E, + Unknown831 = 0x0FF0033F, + Unknown832 = 0x0FF00340, + Unknown833 = 0x0FF00341, + Unknown834 = 0x0FF00342, + Unknown835 = 0x0FF00343, + Unknown836 = 0x0FF00344, + Unknown837 = 0x0FF00345, + Unknown838 = 0x0FF00346, + Unknown839 = 0x0FF00347, + Unknown840 = 0x0FF00348, + Unknown841 = 0x0FF00349, + Unknown842 = 0x0FF0034A, + Unknown843 = 0x0FF0034B, + Unknown844 = 0x0FF0034C, + Unknown845 = 0x0FF0034D, + Unknown846 = 0x0FF0034E, + Unknown847 = 0x0FF0034F, + Unknown848 = 0x0FF00350, + Unknown849 = 0x0FF00351, + Unknown850 = 0x0FF00352, + Unknown851 = 0x0FF00353, + Unknown852 = 0x0FF00354, + Unknown853 = 0x0FF00355, + Unknown854 = 0x0FF00356, + Unknown855 = 0x0FF00357, + Unknown856 = 0x0FF00358, + Unknown857 = 0x0FF00359, + Unknown858 = 0x0FF0035A, + Unknown859 = 0x0FF0035B, + Unknown860 = 0x0FF0035C, + Unknown861 = 0x0FF0035D, + Unknown862 = 0x0FF0035E, + Unknown863 = 0x0FF0035F, + Unknown864 = 0x0FF00360, + Unknown865 = 0x0FF00361, + Unknown866 = 0x0FF00362, + Unknown867 = 0x0FF00363, + Unknown868 = 0x0FF00364, + Unknown869 = 0x0FF00365, + Unknown870 = 0x0FF00366, + Unknown871 = 0x0FF00367, + Unknown872 = 0x0FF00368, + Unknown873 = 0x0FF00369, + Unknown874 = 0x0FF0036A, + Unknown875 = 0x0FF0036B, + Unknown876 = 0x0FF0036C, + Unknown877 = 0x0FF0036D, + Unknown878 = 0x0FF0036E, + Unknown879 = 0x0FF0036F, + Unknown880 = 0x0FF00370, + Unknown881 = 0x0FF00371, + Unknown882 = 0x0FF00372, + Unknown883 = 0x0FF00373, + Unknown884 = 0x0FF00374, + Unknown885 = 0x0FF00375, + Unknown886 = 0x0FF00376, + Unknown887 = 0x0FF00377, + Unknown888 = 0x0FF00378, + Unknown889 = 0x0FF00379, + Unknown890 = 0x0FF0037A, + Unknown891 = 0x0FF0037B, + Unknown892 = 0x0FF0037C, + Unknown893 = 0x0FF0037D, + Unknown894 = 0x0FF0037E, + Unknown895 = 0x0FF0037F, + Unknown896 = 0x0FF00380, + Unknown897 = 0x0FF00381, + Unknown898 = 0x0FF00382, + Unknown899 = 0x0FF00383, + Unknown900 = 0x0FF00384, + Unknown901 = 0x0FF00385, + Unknown902 = 0x0FF00386, + Unknown903 = 0x0FF00387, + Unknown904 = 0x0FF00388, + Unknown905 = 0x0FF00389, + Unknown906 = 0x0FF0038A, + Unknown907 = 0x0FF0038B, + Unknown908 = 0x0FF0038C, + Unknown909 = 0x0FF0038D, + Unknown910 = 0x0FF0038E, + Unknown911 = 0x0FF0038F, + Unknown912 = 0x0FF00390, + Unknown913 = 0x0FF00391, + Unknown914 = 0x0FF00392, + Unknown915 = 0x0FF00393, + Unknown916 = 0x0FF00394, + Unknown917 = 0x0FF00395, + Unknown918 = 0x0FF00396, + Unknown919 = 0x0FF00397, + Unknown920 = 0x0FF00398, + Unknown921 = 0x0FF00399, + Unknown922 = 0x0FF0039A, + Unknown923 = 0x0FF0039B, + Unknown924 = 0x0FF0039C, + Unknown925 = 0x0FF0039D, + Unknown926 = 0x0FF0039E, + Unknown927 = 0x0FF0039F, + Unknown928 = 0x0FF003A0, + Unknown929 = 0x0FF003A1, + Unknown930 = 0x0FF003A2, + Unknown931 = 0x0FF003A3, + Unknown932 = 0x0FF003A4, + Unknown933 = 0x0FF003A5, + Unknown934 = 0x0FF003A6, + Unknown935 = 0x0FF003A7, + Unknown936 = 0x0FF003A8, + Unknown937 = 0x0FF003A9, + Unknown938 = 0x0FF003AA, + Unknown939 = 0x0FF003AB, + Unknown940 = 0x0FF003AC, + Unknown941 = 0x0FF003AD, + Unknown942 = 0x0FF003AE, + Unknown943 = 0x0FF003AF, + Unknown944 = 0x0FF003B0, + Unknown945 = 0x0FF003B1, + Unknown946 = 0x0FF003B2, + Unknown947 = 0x0FF003B3, + Unknown948 = 0x0FF003B4, + Unknown949 = 0x0FF003B5, + Unknown950 = 0x0FF003B6, + Unknown951 = 0x0FF003B7, + Unknown952 = 0x0FF003B8, + Unknown953 = 0x0FF003B9, + Unknown954 = 0x0FF003BA, + Unknown955 = 0x0FF003BB, + Unknown956 = 0x0FF003BC, + Unknown957 = 0x0FF003BD, + Unknown958 = 0x0FF003BE, + Unknown959 = 0x0FF003BF, + Unknown960 = 0x0FF003C0, + Unknown961 = 0x0FF003C1, + Unknown962 = 0x0FF003C2, + Unknown963 = 0x0FF003C3, + Unknown964 = 0x0FF003C4, + Unknown965 = 0x0FF003C5, + Unknown966 = 0x0FF003C6, + Unknown967 = 0x0FF003C7, + Unknown968 = 0x0FF003C8, + Unknown969 = 0x0FF003C9, + Unknown970 = 0x0FF003CA, + Unknown971 = 0x0FF003CB, + Unknown972 = 0x0FF003CC, + Unknown973 = 0x0FF003CD, + Unknown974 = 0x0FF003CE, + Unknown975 = 0x0FF003CF, + Unknown976 = 0x0FF003D0, + Unknown977 = 0x0FF003D1, + Unknown978 = 0x0FF003D2, + Unknown979 = 0x0FF003D3, + Unknown980 = 0x0FF003D4, + Unknown981 = 0x0FF003D5, + Unknown982 = 0x0FF003D6, + Unknown983 = 0x0FF003D7, + Unknown984 = 0x0FF003D8, + Unknown985 = 0x0FF003D9, + Unknown986 = 0x0FF003DA, + Unknown987 = 0x0FF003DB, + Unknown988 = 0x0FF003DC, + Unknown989 = 0x0FF003DD, + Unknown990 = 0x0FF003DE, + Unknown991 = 0x0FF003DF, + Unknown992 = 0x0FF003E0, + Unknown993 = 0x0FF003E1, + Unknown994 = 0x0FF003E2, + Unknown995 = 0x0FF003E3, + Unknown996 = 0x0FF003E4, + Unknown997 = 0x0FF003E5, + Unknown998 = 0x0FF003E6, + Unknown999 = 0x0FF003E7, + Unknown1000 = 0x0FF003E8, + Unknown1001 = 0x0FF003E9, + Unknown1002 = 0x0FF003EA, + Unknown1003 = 0x0FF003EB, + Unknown1004 = 0x0FF003EC, + Unknown1005 = 0x0FF003ED, + Unknown1006 = 0x0FF003EE, + Unknown1007 = 0x0FF003EF, + Unknown1008 = 0x0FF003F0, + Unknown1009 = 0x0FF003F1, + Unknown1010 = 0x0FF003F2, + Unknown1011 = 0x0FF003F3, + Unknown1012 = 0x0FF003F4, + Unknown1013 = 0x0FF003F5, + Unknown1014 = 0x0FF003F6, + Unknown1015 = 0x0FF003F7, + Unknown1016 = 0x0FF003F8, + Unknown1017 = 0x0FF003F9, + Unknown1018 = 0x0FF003FA, + Unknown1019 = 0x0FF003FB, + Unknown1020 = 0x0FF003FC, + Unknown1021 = 0x0FF003FD, + Unknown1022 = 0x0FF003FE, + Unknown1023 = 0x0FF003FF, + Unknown1024 = 0x0FF00400, +} \ No newline at end of file diff --git a/RGB.NET.Core/Leds/LedMapping.cs b/RGB.NET.Core/Leds/LedMapping.cs new file mode 100644 index 00000000..e2866d39 --- /dev/null +++ b/RGB.NET.Core/Leds/LedMapping.cs @@ -0,0 +1,148 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace RGB.NET.Core; + +/// +/// Represents a mapping from to a custom identifier. +/// +/// The identifier the is mapped to. +public class LedMapping : IEnumerable<(LedId ledId, T mapping)> + where T : notnull +{ + #region Properties & Fields + + private readonly Dictionary _mapping = new(); + private readonly Dictionary _reverseMapping = new(); + + /// + /// Gets the number of entries in this mapping. + /// + public int Count => _mapping.Count; + + /// + /// Gets a collection of all mapped ledids. + /// + public ICollection LedIds => _mapping.Keys; + + /// + /// Gets a collection of all mapped custom identifiers. + /// + public ICollection Mappings => _reverseMapping.Keys; + + #endregion + + #region Indexer + + /// + /// Gets the custom identifier mapped to the specified . + /// + /// The led id to get the mapped identifier. + /// The mapped ifentifier. + public T this[LedId ledId] + { + get => _mapping[ledId]; + set + { + _mapping[ledId] = value; + _reverseMapping[value] = ledId; + } + } + + /// + /// Gets the mapped to the specified custom identifier. + /// + /// The custom identifier to get the mapped led id. + /// The led id. + public LedId this[T mapping] + { + get => _reverseMapping[mapping]; + set => this[value] = mapping; + } + + #endregion + + #region Methods + + /// + /// Adds a new entry to the mapping. + /// + /// The to map. + /// The custom identifier to map. + public void Add(LedId ledId, T mapping) + { + _mapping.Add(ledId, mapping); + _reverseMapping.Add(mapping, ledId); + } + + /// + /// Checks if the specified is mapped. + /// + /// The led id to check. + /// true if the led id is mapped; otherwise false. + public bool Contains(LedId ledId) => _mapping.ContainsKey(ledId); + + /// + /// Checks if the specified custom identifier is mapped. + /// + /// The custom identifier to check. + /// true if the led id is mapped; otherwise false. + public bool Contains(T mapping) => _reverseMapping.ContainsKey(mapping); + + /// + /// Gets the custom identifier mapped to the specified led id. + /// + /// The led id to get the custom identifier for. + /// Contains the mapped custom identifier or null if there is no mapping for the specified led id. + /// true if there was a custom identifier for the specified led id; otherwise false. + public bool TryGetValue(LedId ledId, out T? mapping) => _mapping.TryGetValue(ledId, out mapping); + + /// + /// Gets the led id mapped to the specified custom identifier. + /// + /// The custom identifier to get the led id for. + /// Contains the mapped led id or null if there is no mapping for the specified led id. + /// true if there was a led id for the specified custom identifier; otherwise false. + public bool TryGetValue(T mapping, out LedId ledId) => _reverseMapping.TryGetValue(mapping, out ledId); + + /// + /// Removes the specified led id and the mapped custom identifier. + /// + /// The led id to remove. + /// true if there was a mapping for the led id to remove; otherwise false. + public bool Remove(LedId ledId) + { + if (_mapping.TryGetValue(ledId, out T? mapping)) + _reverseMapping.Remove(mapping); + return _mapping.Remove(ledId); + } + + /// + /// Removes the specified custom identifier and the mapped led id. + /// + /// The custom identifier to remove. + /// true if there was a mapping for the custom identifier to remove; otherwise false. + public bool Remove(T mapping) + { + if (_reverseMapping.TryGetValue(mapping, out LedId ledId)) + _mapping.Remove(ledId); + return _reverseMapping.Remove(mapping); + } + + /// + /// Removes all registered mappings. + /// + public void Clear() + { + _mapping.Clear(); + _reverseMapping.Clear(); + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator<(LedId ledId, T mapping)> GetEnumerator() => _mapping.Select(x => (x.Key, x.Value)).GetEnumerator(); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/MVVM/AbstractBindable.cs b/RGB.NET.Core/MVVM/AbstractBindable.cs index ab36978d..c58c1aed 100644 --- a/RGB.NET.Core/MVVM/AbstractBindable.cs +++ b/RGB.NET.Core/MVVM/AbstractBindable.cs @@ -1,67 +1,61 @@ using System.ComponentModel; using System.Runtime.CompilerServices; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// Represents a basic bindable class which notifies when a property value changes. +/// +public abstract class AbstractBindable : IBindable { - /// + #region Events + /// - /// Represents a basic bindable class which notifies when a property value changes. + /// Occurs when a property value changes. /// - public abstract class AbstractBindable : IBindable - { - #region Events - - /// - /// Occurs when a property value changes. - /// - public event PropertyChangedEventHandler PropertyChanged; + public event PropertyChangedEventHandler? PropertyChanged; - #endregion + #endregion - #region Methods + #region Methods - /// - /// Checks if the property already matches the desirec value or needs to be updated. - /// - /// Type of the property. - /// Reference to the backing-filed. - /// Value to apply. - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - protected virtual bool RequiresUpdate(ref T storage, T value) - { - return !Equals(storage, value); - } + /// + /// Checks if the property already matches the desired value or needs to be updated. + /// + /// Type of the property. + /// Reference to the backing-filed. + /// Value to apply. + /// true if the value needs to be updated; otherweise false. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected virtual bool RequiresUpdate(ref T storage, T value) => !Equals(storage, value); - /// - /// Checks if the property already matches the desired value and updates it if not. - /// - /// Type of the property. - /// Reference to the backing-filed. - /// Value to apply. - /// Name of the property used to notify listeners. This value is optional - /// and can be provided automatically when invoked from compilers that support . - /// true if the value was changed, false if the existing value matched the desired value. - protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null) - { - if (!this.RequiresUpdate(ref storage, value)) return false; + /// + /// Checks if the property already matches the desired value and updates it if not. + /// + /// Type of the property. + /// Reference to the backing-filed. + /// Value to apply. + /// Name of the property used to notify listeners. This value is optional + /// and can be provided automatically when invoked from compilers that support . + /// true if the value was changed, false if the existing value matched the desired value. + protected virtual bool SetProperty(ref T storage, T value, [CallerMemberName] string? propertyName = null) + { + if (!RequiresUpdate(ref storage, value)) return false; - storage = value; - // ReSharper disable once ExplicitCallerInfoArgument - this.OnPropertyChanged(propertyName); - return true; - } + storage = value; + // ReSharper disable once ExplicitCallerInfoArgument + OnPropertyChanged(propertyName); + return true; + } - /// - /// Triggers the -event when a a property value has changed. - /// - /// Name of the property used to notify listeners. This value is optional - /// and can be provided automatically when invoked from compilers that support . - protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) - { - this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } + /// + /// Triggers the -event when a a property value has changed. + /// + /// Name of the property used to notify listeners. This value is optional + /// and can be provided automatically when invoked from compilers that support . + protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null) + => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/MVVM/IBindable.cs b/RGB.NET.Core/MVVM/IBindable.cs index 4191eac3..34a861d5 100644 --- a/RGB.NET.Core/MVVM/IBindable.cs +++ b/RGB.NET.Core/MVVM/IBindable.cs @@ -1,11 +1,10 @@ using System.ComponentModel; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a basic bindable class which notifies when a property value changes. +/// +public interface IBindable : INotifyPropertyChanged { - /// - /// Represents a basic bindable class which notifies when a property value changes. - /// - public interface IBindable : INotifyPropertyChanged - { - } -} +} \ No newline at end of file diff --git a/RGB.NET.Core/Positioning/IPlaceable.cs b/RGB.NET.Core/Positioning/IPlaceable.cs new file mode 100644 index 00000000..c53904fc --- /dev/null +++ b/RGB.NET.Core/Positioning/IPlaceable.cs @@ -0,0 +1,92 @@ +// ReSharper disable EventNeverSubscribedTo.Global + +using System; + +namespace RGB.NET.Core; + +/// +/// Represents a generic placeable element. +/// +public interface IPlaceable +{ + #region Properties & Fields + + /// + /// Gets or sets the location of the . + /// + Point Location { get; set; } + + /// + /// Gets the size of the . + /// + Size Size { get; set; } + + /// + /// Gets or sets the scale of the . + /// + Scale Scale { get; set; } + + /// + /// Gets or sets the rotation of the . + /// + Rotation Rotation { get; set; } + + /// + /// Gets the actual location of the . + /// This includes the . + /// + Point ActualLocation { get; } + + /// + /// Gets the actual of the . + /// This includes the . + /// + Size ActualSize { get; } + + /// + /// Gets a rectangle containing the whole . + /// This includes , , and . + /// + Rectangle Boundary { get; } + + #endregion + + #region Events + + /// + /// Occurs when the property was changed. + /// + event EventHandler LocationChanged; + + /// + /// Occurs when the property was changed. + /// + event EventHandler SizeChanged; + + /// + /// Occurs when the property was changed. + /// + event EventHandler ScaleChanged; + + /// + /// Occurs when the property was changed. + /// + event EventHandler RotationChanged; + + /// + /// Occurs when the property was changed. + /// + event EventHandler ActualLocationChanged; + + /// + /// Occurs when the property was changed. + /// + event EventHandler ActualSizeChanged; + + /// + /// Occurs when the property was changed. + /// + event EventHandler BoundaryChanged; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Positioning/Placeable.cs b/RGB.NET.Core/Positioning/Placeable.cs new file mode 100644 index 00000000..29ca5518 --- /dev/null +++ b/RGB.NET.Core/Positioning/Placeable.cs @@ -0,0 +1,261 @@ +using System; + +namespace RGB.NET.Core; + +/// +/// Represents a placeable element. +/// +public class Placeable : AbstractBindable, IPlaceable +{ + #region Properties & Fields + + /// + /// Gets the parent this placeable is placed in. + /// + protected IPlaceable? Parent { get; } + + private Point _location = Point.Invalid; + /// + public Point Location + { + get => _location; + set + { + if (SetProperty(ref _location, value)) + OnLocationChanged(); + } + } + + private Size _size = Size.Invalid; + /// + public Size Size + { + get => _size; + set + { + if (SetProperty(ref _size, value)) + OnSizeChanged(); + } + } + + private Scale _scale = new(1); + /// + public Scale Scale + { + get => _scale; + set + { + if (SetProperty(ref _scale, value)) + OnScaleChanged(); + } + } + + private Rotation _rotation = new(0); + /// + public Rotation Rotation + { + get => _rotation; + set + { + if (SetProperty(ref _rotation, value)) + OnRotationChanged(); + } + } + + private Point _actualLocation = Point.Invalid; + /// + public Point ActualLocation + { + get => _actualLocation; + private set + { + if (SetProperty(ref _actualLocation, value)) + OnActualLocationChanged(); + } + } + + private Size _actualSize = Size.Invalid; + /// + public Size ActualSize + { + get => _actualSize; + private set + { + if (SetProperty(ref _actualSize, value)) + OnActualSizeChanged(); + } + } + + private Rectangle _boundary = new(Point.Invalid, Point.Invalid); + /// + public Rectangle Boundary + { + get => _boundary; + private set + { + if (SetProperty(ref _boundary, value)) + OnBoundaryChanged(); + } + } + + #endregion + + #region Events + + /// + public event EventHandler? LocationChanged; + + /// + public event EventHandler? SizeChanged; + + /// + public event EventHandler? ScaleChanged; + + /// + public event EventHandler? RotationChanged; + + /// + public event EventHandler? ActualLocationChanged; + + /// + public event EventHandler? ActualSizeChanged; + + /// + public event EventHandler? BoundaryChanged; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public Placeable() { } + + /// + /// Initializes a new instance of the class. + /// + /// The parent this placeable is placed in. + public Placeable(IPlaceable parent) + { + this.Parent = parent; + + Parent.BoundaryChanged += (_, _) => UpdateActualPlaceableData(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The location of this placeable. + /// The size of this placeable. + public Placeable(Point location, Size size) + { + this.Location = location; + this.Size = size; + } + + /// + /// Initializes a new instance of the class. + /// + /// The parent placeable this placeable is placed in. + /// The location of this placeable. + /// The size of this placeable. + public Placeable(IPlaceable parent, Point location, Size size) + { + this.Parent = parent; + this.Location = location; + this.Size = size; + + Parent.BoundaryChanged += (_, _) => UpdateActualPlaceableData(); + } + + #endregion + + #region Methods + + /// + /// Updates the , and based on the , and . + /// + protected virtual void UpdateActualPlaceableData() + { + if (Parent != null) + { + Size actualSize = Size * Parent.Scale; + Point actualLocation = (Location * Parent.Scale); + Rectangle boundary = new(actualLocation, actualSize); + + if (Parent.Rotation.IsRotated) + { + Point parentCenter = new Rectangle(Parent.ActualSize).Center; + Point actualParentCenter = new Rectangle(Parent.Boundary.Size).Center; + Point centerOffset = new(actualParentCenter.X - parentCenter.X, actualParentCenter.Y - parentCenter.Y); + + actualLocation = actualLocation.Rotate(Parent.Rotation, new Rectangle(Parent.ActualSize).Center) + centerOffset; + boundary = new Rectangle(boundary.Rotate(Parent.Rotation, new Rectangle(Parent.ActualSize).Center)).Translate(centerOffset); + } + + ActualLocation = actualLocation; + ActualSize = actualSize; + Boundary = boundary; + } + else + { + ActualLocation = Location; + ActualSize = Size * Scale; + Boundary = new Rectangle(Location, new Rectangle(new Rectangle(Location, ActualSize).Rotate(Rotation)).Size); + } + } + + /// + /// Called when the property was changed. + /// + protected virtual void OnLocationChanged() + { + LocationChanged?.Invoke(this, new EventArgs()); + UpdateActualPlaceableData(); + } + + /// + /// Called when the property was changed. + /// + protected virtual void OnSizeChanged() + { + SizeChanged?.Invoke(this, new EventArgs()); + UpdateActualPlaceableData(); + } + + /// + /// Called when the property was changed. + /// + protected virtual void OnScaleChanged() + { + ScaleChanged?.Invoke(this, new EventArgs()); + UpdateActualPlaceableData(); + } + + /// + /// Called when the property was changed. + /// + protected virtual void OnRotationChanged() + { + RotationChanged?.Invoke(this, new EventArgs()); + UpdateActualPlaceableData(); + } + + /// + /// Called when the property was changed. + /// + protected virtual void OnActualLocationChanged() => ActualLocationChanged?.Invoke(this, new EventArgs()); + + /// + /// Called when the property was changed. + /// + protected virtual void OnActualSizeChanged() => ActualSizeChanged?.Invoke(this, new EventArgs()); + + /// + /// Called when the property was changed. + /// + protected virtual void OnBoundaryChanged() => BoundaryChanged?.Invoke(this, new EventArgs()); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Positioning/Point.cs b/RGB.NET.Core/Positioning/Point.cs index 95838634..e2f3d97c 100644 --- a/RGB.NET.Core/Positioning/Point.cs +++ b/RGB.NET.Core/Positioning/Point.cs @@ -1,162 +1,154 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global +using System; using System.Diagnostics; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a point consisting of a X- and a Y-position. +/// +[DebuggerDisplay("[X: {X}, Y: {Y}]")] +public readonly struct Point { + #region Constants + + private static readonly Point INVALID = new(float.NaN, float.NaN); + /// + /// Gets a [NaN,NaN]-Point. + /// + public static ref readonly Point Invalid => ref INVALID; + + #endregion + + #region Properties & Fields + + /// + /// Gets the X-position of this . + /// + public float X { get; } + + /// + /// Gets the Y-position of this . + /// + public float Y { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class using the provided values. + /// + /// The value used for the X-position. + /// The value used for the Y-position. + public Point(float x, float y) + { + this.X = x; + this.Y = y; + } + + #endregion + + #region Methods + + /// + /// Converts the - and -position of this to a human-readable string. + /// + /// A string that contains the and of this . For example "[X: 100, Y: 20]". + public override string ToString() => $"[X: {X}, Y: {Y}]"; + + /// + /// Tests whether the specified object is a and is equivalent to this . + /// + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + public override bool Equals(object? obj) + { + if (obj is not Point comparePoint) return false; + + return ((float.IsNaN(X) && float.IsNaN(comparePoint.X)) || X.EqualsInTolerance(comparePoint.X)) + && ((float.IsNaN(Y) && float.IsNaN(comparePoint.Y)) || Y.EqualsInTolerance(comparePoint.Y)); + } + + /// + /// Returns a hash code for this . + /// + /// An integer value that specifies the hash code for this . + public override int GetHashCode() => HashCode.Combine(X, Y); + + #endregion + + #region Operators + /// - /// Represents a point consisting of a X- and a Y-position. + /// Returns a value that indicates whether two specified are equal. /// - [DebuggerDisplay("[X: {X}, Y: {Y}]")] - public struct Point + /// The first to compare. + /// The second to compare. + /// true if and are equal; otherwise, false. + public static bool operator ==(in Point point1, in Point point2) => point1.Equals(point2); + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are not equal; otherwise, false. + public static bool operator !=(in Point point1, in Point point2) => !(point1 == point2); + + /// + /// Returns a new representing the addition of the two provided . + /// + /// The first . + /// The second . + /// A new representing the addition of the two provided . + public static Point operator +(in Point point1, in Point point2) => new(point1.X + point2.X, point1.Y + point2.Y); + + /// + /// Returns a new created from the provided and . + /// + /// The of the rectangle. + /// The of the rectangle. + /// The rectangle created from the provided and . + public static Rectangle operator +(in Point point, in Size size) => new(point, size); + + /// + /// Returns a new representing the subtraction of the two provided . + /// + /// The first . + /// The second . + /// A new representing the subtraction of the two provided . + public static Point operator -(in Point point1, in Point point2) => new(point1.X - point2.X, point1.Y - point2.Y); + + /// + /// Returns a new representing the multiplication of the two provided . + /// + /// The first . + /// The second . + /// A new representing the multiplication of the two provided . + public static Point operator *(in Point point1, in Point point2) => new(point1.X * point2.X, point1.Y * point2.Y); + + /// + /// Returns a new representing the division of the two provided . + /// + /// The first . + /// The second . + /// A new representing the division of the two provided . + public static Point operator /(in Point point1, in Point point2) { - #region Constants - - /// - /// Gets a [NaN,NaN]-Point. - /// - public static Point Invalid => new Point(double.NaN, double.NaN); - - #endregion - - #region Properties & Fields - - /// - /// Gets the X-position of this . - /// - public double X { get; } - - /// - /// Gets the Y-position of this . - /// - public double Y { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class using the provided values. - /// - /// The value used for the X-position. - /// The value used for the Y-position. - public Point(double x, double y) - { - this.X = x; - this.Y = y; - } - - #endregion - - #region Methods - - /// - /// Converts the - and -position of this to a human-readable string. - /// - /// A string that contains the and of this . For example "[X: 100, Y: 20]". - public override string ToString() => $"[X: {X}, Y: {Y}]"; - - /// - /// Tests whether the specified object is a and is equivalent to this . - /// - /// The object to test. - /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) - { - if (!(obj is Point)) return false; - - Point comparePoint = (Point)obj; - return ((double.IsNaN(X) && double.IsNaN(comparePoint.X)) || X.EqualsInTolerance(comparePoint.X)) - && ((double.IsNaN(Y) && double.IsNaN(comparePoint.Y)) || Y.EqualsInTolerance(comparePoint.Y)); - } - - /// - /// Returns a hash code for this . - /// - /// An integer value that specifies the hash code for this . - public override int GetHashCode() - { - unchecked - { - int hashCode = X.GetHashCode(); - hashCode = (hashCode * 397) ^ Y.GetHashCode(); - return hashCode; - } - } - - #endregion - - #region Operators - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are equal; otherwise, false. - public static bool operator ==(Point point1, Point point2) => point1.Equals(point2); - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are not equal; otherwise, false. - public static bool operator !=(Point point1, Point point2) => !(point1 == point2); - - /// - /// Returns a new representing the addition of the two provided . - /// - /// The first . - /// The second . - /// A new representing the addition of the two provided . - public static Point operator +(Point point1, Point point2) => new Point(point1.X + point2.X, point1.Y + point2.Y); - - /// - /// Returns a new created from the provided and . - /// - /// The of the rectangle. - /// The of the rectangle. - /// The rectangle created from the provided and . - public static Rectangle operator +(Point point, Size size) => new Rectangle(point, size); - - /// - /// Returns a new representing the subtraction of the two provided . - /// - /// The first . - /// The second . - /// A new representing the subtraction of the two provided . - public static Point operator -(Point point1, Point point2) => new Point(point1.X - point2.X, point1.Y - point2.Y); - - /// - /// Returns a new representing the multiplication of the two provided . - /// - /// The first . - /// The second . - /// A new representing the multiplication of the two provided . - public static Point operator *(Point point1, Point point2) => new Point(point1.X * point2.X, point1.Y * point2.Y); - - /// - /// Returns a new representing the division of the two provided . - /// - /// The first . - /// The second . - /// A new representing the division of the two provided . - public static Point operator /(Point point1, Point point2) - { - if (point2.X.EqualsInTolerance(0) || point2.Y.EqualsInTolerance(0)) return Invalid; - return new Point(point1.X / point2.X, point1.Y / point2.Y); - } - - /// - /// Returns a new representing the multiplication of the and the provided . - /// - /// The . - /// The . - /// A new representing the multiplication of the and the provided . - public static Point operator *(Point point, Scale scale) => new Point(point.X * scale.Horizontal, point.Y * scale.Vertical); - - #endregion + if (point2.X.EqualsInTolerance(0) || point2.Y.EqualsInTolerance(0)) return Invalid; + return new Point(point1.X / point2.X, point1.Y / point2.Y); } -} + + /// + /// Returns a new representing the multiplication of the and the provided . + /// + /// The . + /// The . + /// A new representing the multiplication of the and the provided . + public static Point operator *(in Point point, in Scale scale) => new(point.X * scale.Horizontal, point.Y * scale.Vertical); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Positioning/Rectangle.cs b/RGB.NET.Core/Positioning/Rectangle.cs index d3b16185..a1789895 100644 --- a/RGB.NET.Core/Positioning/Rectangle.cs +++ b/RGB.NET.Core/Positioning/Rectangle.cs @@ -6,223 +6,236 @@ using System.Diagnostics; using System.Linq; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a rectangle defined by it's position and it's size. +/// +[DebuggerDisplay("[Location: {Location}, Size: {Size}]")] +public readonly struct Rectangle { + #region Properties & Fields + + /// + /// Gets the representing the top-left corner of the . + /// + public Point Location { get; } + + /// + /// Gets the of the . + /// + public Size Size { get; } + + /// + /// Gets a new representing the center-point of the . + /// + public Point Center { get; } + /// - /// Represents a rectangle defined by it's position and it's size. + /// Gets a bool indicating if both, the width and the height of the rectangle is greater than zero. + /// True if the rectangle has a width or a height of zero; otherwise, false. /// - [DebuggerDisplay("[Location: {Location}, Size: {Size}]")] - public struct Rectangle + public bool IsEmpty => (Size.Width <= FloatExtensions.TOLERANCE) || (Size.Height <= FloatExtensions.TOLERANCE); + + #endregion + + #region Constructors + + /// + /// + /// Initializes a new instance of the class using the provided values for ans . + /// + /// The x-value of the of this . + /// The y-value of the -position of this . + /// The width of the of this . + /// The height of the of this . + public Rectangle(float x, float y, float width, float height) + : this(new Point(x, y), new Size(width, height)) + { } + + /// + /// Initializes a new instance of the class using the (0,0) and the specified . + /// + /// The size of of this . + public Rectangle(Size size) : this(new Point(), size) + { } + + /// + /// Initializes a new instance of the class using the specified and . + /// + /// The location of this of this . + /// The size of of this . + public Rectangle(Point location, Size size) { - #region Properties & Fields - - /// - /// Gets the representing the top-left corner of the . - /// - public Point Location { get; } - - /// - /// Gets the of the . - /// - public Size Size { get; } - - /// - /// Gets a new representing the center-point of the . - /// - public Point Center { get; } - - /// - /// Gets a bool indicating if both, the width and the height of the rectangle is greater than zero. - /// True if the rectangle has a width or a height of zero; otherwise, false. - /// - public bool IsEmpty => (Size.Width <= DoubleExtensions.TOLERANCE) || (Size.Height <= DoubleExtensions.TOLERANCE); - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class using the provided values for ans . - /// - /// The x-value of the of this . - /// The y-value of the -position of this . - /// The width of the of this . - /// The height of the of this . - public Rectangle(double x, double y, double width, double height) - : this(new Point(x, y), new Size(width, height)) - { } - - /// - /// Initializes a new instance of the class using the (0,0) and the given . - /// - /// The size of of this . - public Rectangle(Size size) : this(new Point(), size) - { } - - /// - /// Initializes a new instance of the class using the given and . - /// - /// The location of this of this . - /// The size of of this . - public Rectangle(Point location, Size size) - { - this.Location = location; - this.Size = size; - Center = new Point(Location.X + (Size.Width / 2.0), Location.Y + (Size.Height / 2.0)); - } + this.Location = location; + this.Size = size; + + Center = new Point(Location.X + (Size.Width / 2.0f), Location.Y + (Size.Height / 2.0f)); + } - /// - /// - /// Initializes a new instance of the class using the given array of . - /// The and is calculated to completely contain all rectangles provided as parameters. - /// - /// The array of used to calculate the and - public Rectangle(params Rectangle[] rectangles) - : this(rectangles.AsEnumerable()) - { } - - /// - /// Initializes a new instance of the class using the given list of . - /// The and is calculated to completely contain all rectangles provided as parameters. - /// - /// The list of used to calculate the and - public Rectangle(IEnumerable rectangles) + /// + /// + /// Initializes a new instance of the class using the specified array of . + /// The and is calculated to completely contain all rectangles provided as parameters. + /// + /// The array of used to calculate the and . + public Rectangle(params Rectangle[] rectangles) + : this(rectangles.AsEnumerable()) + { } + + /// + /// Initializes a new instance of the class using the specified list of . + /// The and is calculated to completely contain all rectangles provided as parameters. + /// + /// The list of used to calculate the and . + public Rectangle(IEnumerable rectangles) + { + bool hasPoint = false; + float posX = float.MaxValue; + float posY = float.MaxValue; + float posX2 = float.MinValue; + float posY2 = float.MinValue; + + foreach (Rectangle rectangle in rectangles) { - bool hasPoint = false; - double posX = double.MaxValue; - double posY = double.MaxValue; - double posX2 = double.MinValue; - double posY2 = double.MinValue; - - if (rectangles != null) - foreach (Rectangle rectangle in rectangles) - { - hasPoint = true; - posX = Math.Min(posX, rectangle.Location.X); - posY = Math.Min(posY, rectangle.Location.Y); - posX2 = Math.Max(posX2, rectangle.Location.X + rectangle.Size.Width); - posY2 = Math.Max(posY2, rectangle.Location.Y + rectangle.Size.Height); - } - - (Point location, Size size) = hasPoint ? InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2)) : InitializeFromPoints(new Point(0, 0), new Point(0, 0)); - Location = location; - Size = size; - Center = new Point(Location.X + (Size.Width / 2.0), Location.Y + (Size.Height / 2.0)); + hasPoint = true; + posX = Math.Min(posX, rectangle.Location.X); + posY = Math.Min(posY, rectangle.Location.Y); + posX2 = Math.Max(posX2, rectangle.Location.X + rectangle.Size.Width); + posY2 = Math.Max(posY2, rectangle.Location.Y + rectangle.Size.Height); } - /// - /// - /// Initializes a new instance of the class using the given array of . - /// The and is calculated to contain all points provided as parameters. - /// - /// The array of used to calculate the and - public Rectangle(params Point[] points) - : this(points.AsEnumerable()) - { } - - /// - /// - /// Initializes a new instance of the class using the given list of . - /// The and is calculated to contain all points provided as parameters. - /// - /// The list of used to calculate the and - public Rectangle(IEnumerable points) - : this() + (Point location, Size size) = hasPoint ? InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2)) : InitializeFromPoints(new Point(0, 0), new Point(0, 0)); + Location = location; + Size = size; + Center = new Point(Location.X + (Size.Width / 2.0f), Location.Y + (Size.Height / 2.0f)); + } + + /// + /// + /// Initializes a new instance of the class using the specified array of . + /// The and is calculated to contain all points provided as parameters. + /// + /// The array of used to calculate the and . + public Rectangle(params Point[] points) + : this(points.AsEnumerable()) + { } + + /// + /// + /// Initializes a new instance of the class using the specified list of . + /// The and is calculated to contain all points provided as parameters. + /// + /// The list of used to calculate the and . + public Rectangle(IEnumerable points) + : this() + { + bool hasPoint = false; + float posX = float.MaxValue; + float posY = float.MaxValue; + float posX2 = float.MinValue; + float posY2 = float.MinValue; + + foreach (Point point in points) { - bool hasPoint = false; - double posX = double.MaxValue; - double posY = double.MaxValue; - double posX2 = double.MinValue; - double posY2 = double.MinValue; - - if (points != null) - foreach (Point point in points) - { - hasPoint = true; - posX = Math.Min(posX, point.X); - posY = Math.Min(posY, point.Y); - posX2 = Math.Max(posX2, point.X); - posY2 = Math.Max(posY2, point.Y); - } - - (Point location, Size size) = hasPoint ? InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2)) : InitializeFromPoints(new Point(0, 0), new Point(0, 0)); - - Location = location; - Size = size; - Center = new Point(Location.X + (Size.Width / 2.0), Location.Y + (Size.Height / 2.0)); + hasPoint = true; + posX = Math.Min(posX, point.X); + posY = Math.Min(posY, point.Y); + posX2 = Math.Max(posX2, point.X); + posY2 = Math.Max(posY2, point.Y); } - #endregion + (Point location, Size size) = hasPoint ? InitializeFromPoints(new Point(posX, posY), new Point(posX2, posY2)) : InitializeFromPoints(new Point(0, 0), new Point(0, 0)); - #region Methods + Location = location; + Size = size; + Center = new Point(Location.X + (Size.Width / 2.0f), Location.Y + (Size.Height / 2.0f)); + } - private static (Point location, Size size) InitializeFromPoints(Point point1, Point point2) - { - double posX = Math.Min(point1.X, point2.X); - double posY = Math.Min(point1.Y, point2.Y); - double width = Math.Max(point1.X, point2.X) - posX; - double height = Math.Max(point1.Y, point2.Y) - posY; + #endregion - return (new Point(posX, posY), new Size(width, height)); - } + #region Methods - /// - /// Converts the - and -position of this to a human-readable string. - /// - /// A string that contains the and of this . For example "[Location: [X: 100, Y: 10], Size: [Width: 20, Height: [40]]". - public override string ToString() => $"[Location: {Location}, Size: {Size}]"; - - /// - /// Tests whether the specified object is a and is equivalent to this . - /// - /// The object to test. - /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) - { - if (!(obj is Rectangle compareRect)) - return false; + private static (Point location, Size size) InitializeFromPoints(in Point point1, in Point point2) + { + float posX = Math.Min(point1.X, point2.X); + float posY = Math.Min(point1.Y, point2.Y); + float width = Math.Max(point1.X, point2.X) - posX; + float height = Math.Max(point1.Y, point2.Y) - posY; - if (GetType() != compareRect.GetType()) - return false; + return (new Point(posX, posY), new Size(width, height)); + } - return (Location == compareRect.Location) && (Size == compareRect.Size); - } + /// + /// Converts the - and -position of this to a human-readable string. + /// + /// A string that contains the and of this . For example "[Location: [X: 100, Y: 10], Size: [Width: 20, Height: [40]]". + public override string ToString() => $"[Location: {Location}, Size: {Size}]"; - /// - /// Returns a hash code for this . - /// - /// An integer value that specifies the hash code for this . - public override int GetHashCode() + /// + /// Tests whether the specified object is a and is equivalent to this . + /// + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + public override bool Equals(object? obj) + { + if (obj is not Rectangle compareRect) + return false; + + if (GetType() != compareRect.GetType()) + return false; + + return (Location == compareRect.Location) && (Size == compareRect.Size); + } + + /// + /// Returns a hash code for this . + /// + /// An integer value that specifies the hash code for this . + public override int GetHashCode() + { + unchecked { - unchecked - { - int hashCode = Location.GetHashCode(); - hashCode = (hashCode * 397) ^ Size.GetHashCode(); - return hashCode; - } + int hashCode = Location.GetHashCode(); + hashCode = (hashCode * 397) ^ Size.GetHashCode(); + return hashCode; } + } - #endregion + #endregion - #region Operators + #region Operators - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are equal; otherwise, false. - public static bool operator ==(Rectangle rectangle1, Rectangle rectangle2) => rectangle1.Equals(rectangle2); + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are equal; otherwise, false. + public static bool operator ==(in Rectangle rectangle1, in Rectangle rectangle2) => rectangle1.Equals(rectangle2); - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are not equal; otherwise, false. - public static bool operator !=(Rectangle rectangle1, Rectangle rectangle2) => !(rectangle1 == rectangle2); + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are not equal; otherwise, false. + public static bool operator !=(in Rectangle rectangle1, in Rectangle rectangle2) => !(rectangle1 == rectangle2); - #endregion + // DarthAffe 20.02.2021: Used for normalization + /// + /// Returns a normalized to the specified reference. + /// + /// The rectangle to nromalize. + /// The reference used for normalization. + /// A normalized rectangle. + public static Rectangle operator /(in Rectangle rectangle1, in Rectangle rectangle2) + { + float x = rectangle1.Location.X / (rectangle2.Size.Width - rectangle2.Location.X); + float y = rectangle1.Location.Y / (rectangle2.Size.Height - rectangle2.Location.Y); + Size size = rectangle1.Size / rectangle2.Size; + return new Rectangle(new Point(x, y), size); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Positioning/Rotation.cs b/RGB.NET.Core/Positioning/Rotation.cs index 0f638ec2..58903b77 100644 --- a/RGB.NET.Core/Positioning/Rotation.cs +++ b/RGB.NET.Core/Positioning/Rotation.cs @@ -4,159 +4,158 @@ using System; using System.Diagnostics; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents an angular rotation. +/// +[DebuggerDisplay("[{" + nameof(Degrees) + "}°]")] +public readonly struct Rotation { + #region Constants + + private const float TWO_PI = MathF.PI * 2.0f; + private const float RADIANS_DEGREES_CONVERSION = 180.0f / MathF.PI; + private const float DEGREES_RADIANS_CONVERSION = MathF.PI / 180.0f; + + #endregion + + #region Properties & Fields + + /// + /// Gets the angle in degrees. + /// + public float Degrees { get; } + + /// + /// Gets the angle in radians. + /// + public float Radians { get; } + + /// + /// Gets a bool indicating if the rotation is > 0. + /// + public bool IsRotated => !Degrees.EqualsInTolerance(0); + + #endregion + + #region Constructors + /// - /// Represents an angular rotation. + /// Initializes a new instance of the class using the provided values. /// - [DebuggerDisplay("[{Degrees}°]")] - public struct Rotation + /// The rotation in degrees. + public Rotation(float degrees) + : this(degrees, degrees * DEGREES_RADIANS_CONVERSION) + { } + + private Rotation(float degrees, float radians) { - #region Constants - - private const double TWO_PI = Math.PI * 2.0; - private const double RADIANS_DEGREES_CONVERSION = 180.0 / Math.PI; - private const double DEGREES_RADIANS_CONVERSION = Math.PI / 180.0; - - #endregion - - #region Properties & Fields - - /// - /// Gets the angle in degrees. - /// - public double Degrees { get; } - - /// - /// Gets the angle in radians. - /// - public double Radians { get; } - - /// - /// Gets a bool indicating if the rotation is > 0. - /// - public bool IsRotated => !Degrees.EqualsInTolerance(0); - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class using the provided values. - /// - /// The rotation in degrees. - public Rotation(double degrees) - : this(degrees, degrees * DEGREES_RADIANS_CONVERSION) - { } - - private Rotation(double degrees, double radians) - { - this.Degrees = degrees % 360.0; - this.Radians = radians % TWO_PI; - } - - #endregion - - #region Methods - - /// - /// Creates a new Rotation out of the given degree-angle. - /// - /// The angle in degrees. - /// The new rotation. - public static Rotation FromDegrees(double degrees) => new Rotation(degrees); - - /// - /// Creates a new Rotation out of the given radian-angle. - /// - /// The angle in radians. - /// The new rotation. - public static Rotation FromRadians(double radians) => new Rotation(radians * RADIANS_DEGREES_CONVERSION, radians); - - /// - /// Tests whether the specified is equivalent to this . - /// - /// The rotation to test. - /// true if is equivalent to this ; otherwise, false. - public bool Equals(Rotation other) => Degrees.EqualsInTolerance(other.Degrees); - - /// - /// Tests whether the specified object is a and is equivalent to this . - /// - /// The object to test. - /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) => obj is Rotation other && Equals(other); - - /// - /// Returns a hash code for this . - /// - /// An integer value that specifies the hash code for this . - public override int GetHashCode() => Degrees.GetHashCode(); - - #endregion - - #region Operators - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are equal; otherwise, false. - public static bool operator ==(Rotation rotation1, Rotation rotation2) => rotation1.Equals(rotation2); - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are not equal; otherwise, false. - public static bool operator !=(Rotation rotation1, Rotation rotation2) => !(rotation1 == rotation2); - - /// - /// Returns a new representing the addition of the and the provided value. - /// - /// The . - /// The value to add. - /// A new representing the addition of the and the provided value. - public static Rotation operator +(Rotation rotation, double value) => new Rotation(rotation.Degrees + value); - - /// - /// Returns a new representing the subtraction of the and the provided value. - /// - /// The . - /// The value to substract. - /// A new representing the subtraction of the and the provided value. - public static Rotation operator -(Rotation rotation, double value) => new Rotation(rotation.Degrees - value); - - /// - /// Returns a new representing the multiplication of the and the provided value. - /// - /// The . - /// The value to multiply with. - /// A new representing the multiplication of the and the provided value. - public static Rotation operator *(Rotation rotation, double value) => new Rotation(rotation.Degrees * value); - - /// - /// Returns a new representing the division of the and the provided value. - /// - /// The . - /// The value to device with. - /// A new representing the division of the and the provided value. - public static Rotation operator /(Rotation rotation, double value) => value.EqualsInTolerance(0) ? new Rotation(0) : new Rotation(rotation.Degrees / value); - - /// - /// Converts a double to a . - /// - /// The rotation in degrees to convert. - public static implicit operator Rotation(double rotation) => new Rotation(rotation); - - /// - /// Converts to a double representing the rotation in degrees. - /// - /// The rotatio to convert. - public static implicit operator double(Rotation rotation) => rotation.Degrees; - - #endregion + this.Degrees = degrees % 360.0f; + this.Radians = radians % TWO_PI; } -} + + #endregion + + #region Methods + + /// + /// Creates a new Rotation out of the specified degree-angle. + /// + /// The angle in degrees. + /// The new rotation. + public static Rotation FromDegrees(float degrees) => new(degrees); + + /// + /// Creates a new Rotation out of the specified radian-angle. + /// + /// The angle in radians. + /// The new rotation. + public static Rotation FromRadians(float radians) => new(radians * RADIANS_DEGREES_CONVERSION, radians); + + /// + /// Tests whether the specified is equivalent to this . + /// + /// The rotation to test. + /// true if is equivalent to this ; otherwise, false. + public bool Equals(Rotation other) => Degrees.EqualsInTolerance(other.Degrees); + + /// + /// Tests whether the specified object is a and is equivalent to this . + /// + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + public override bool Equals(object? obj) => obj is Rotation other && Equals(other); + + /// + /// Returns a hash code for this . + /// + /// An integer value that specifies the hash code for this . + public override int GetHashCode() => Degrees.GetHashCode(); + + #endregion + + #region Operators + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are equal; otherwise, false. + public static bool operator ==(in Rotation rotation1, in Rotation rotation2) => rotation1.Equals(rotation2); + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are not equal; otherwise, false. + public static bool operator !=(in Rotation rotation1, in Rotation rotation2) => !(rotation1 == rotation2); + + /// + /// Returns a new representing the addition of the and the provided value. + /// + /// The . + /// The value to add. + /// A new representing the addition of the and the provided value. + public static Rotation operator +(in Rotation rotation, float value) => new(rotation.Degrees + value); + + /// + /// Returns a new representing the subtraction of the and the provided value. + /// + /// The . + /// The value to substract. + /// A new representing the subtraction of the and the provided value. + public static Rotation operator -(in Rotation rotation, float value) => new(rotation.Degrees - value); + + /// + /// Returns a new representing the multiplication of the and the provided value. + /// + /// The . + /// The value to multiply with. + /// A new representing the multiplication of the and the provided value. + public static Rotation operator *(in Rotation rotation, float value) => new(rotation.Degrees * value); + + /// + /// Returns a new representing the division of the and the provided value. + /// + /// The . + /// The value to device with. + /// A new representing the division of the and the provided value. + public static Rotation operator /(in Rotation rotation, float value) => value.EqualsInTolerance(0) ? new Rotation(0) : new Rotation(rotation.Degrees / value); + + /// + /// Converts a float to a . + /// + /// The rotation in degrees to convert. + public static implicit operator Rotation(float rotation) => new(rotation); + + /// + /// Converts to a float representing the rotation in degrees. + /// + /// The rotatio to convert. + public static implicit operator float(in Rotation rotation) => rotation.Degrees; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Positioning/Scale.cs b/RGB.NET.Core/Positioning/Scale.cs index 04b8f092..8c884069 100644 --- a/RGB.NET.Core/Positioning/Scale.cs +++ b/RGB.NET.Core/Positioning/Scale.cs @@ -3,142 +3,141 @@ using System.Diagnostics; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a scaling. +/// +[DebuggerDisplay("[Horizontal: {Horizontal}, Vertical: {Vertical}]")] +public readonly struct Scale { + #region Properties & Fields + + /// + /// Gets the horizontal scaling value. + /// + public float Horizontal { get; } + + /// + /// Gets the vertical scaling value. + /// + public float Vertical { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class using the provided values. + /// + /// The value used for horizontal and vertical scaling. 0 if not set. + public Scale(float scale = 1.0f) : this(scale, scale) + { } + + /// + /// Initializes a new instance of the class using the provided values. + /// + /// The value used for horizontal scaling. + /// The value used for vertical scaling. + public Scale(float horizontal, float vertical) + { + this.Horizontal = horizontal; + this.Vertical = vertical; + } + + #endregion + + #region Methods + + /// + /// Tests whether the specified is equivalent to this . + /// + /// The scale to test. + /// true if is equivalent to this ; otherwise, false. + public bool Equals(Scale other) => Horizontal.EqualsInTolerance(other.Horizontal) && Vertical.EqualsInTolerance(other.Vertical); + + /// + /// Tests whether the specified object is a and is equivalent to this . + /// + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + public override bool Equals(object? obj) => obj is Scale other && Equals(other); + + /// + /// Returns a hash code for this . + /// + /// An integer value that specifies the hash code for this . + public override int GetHashCode() { unchecked { return (Horizontal.GetHashCode() * 397) ^ Vertical.GetHashCode(); } } + /// - /// Represents a scaling. + /// Deconstructs the scale into the horizontal and vertical value. /// - [DebuggerDisplay("[Horizontal: {Horizontal}, Vertical: {Vertical}]")] - public struct Scale + /// The horizontal scaling value. + /// The vertical scaling value. + public void Deconstruct(out float horizontalScale, out float verticalScale) { - #region Properties & Fields - - /// - /// Gets the horizontal scaling value. - /// - public double Horizontal { get; } - - /// - /// Gets the vertical scaling value. - /// - public double Vertical { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class using the provided values. - /// - /// The value used for horizontal and vertical scaling. 0 if not set. - public Scale(double scale = 1.0) : this(scale, scale) - { } - - /// - /// Initializes a new instance of the class using the provided values. - /// - /// The value used for horizontal scaling. - /// The value used for vertical scaling. - public Scale(double horizontal, double vertical) - { - this.Horizontal = horizontal; - this.Vertical = vertical; - } - - #endregion - - #region Methods - - /// - /// Tests whether the specified is equivalent to this . - /// - /// The scale to test. - /// true if is equivalent to this ; otherwise, false. - public bool Equals(Scale other) => Horizontal.EqualsInTolerance(other.Horizontal) && Vertical.EqualsInTolerance(other.Vertical); - - /// - /// Tests whether the specified object is a and is equivalent to this . - /// - /// The object to test. - /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) => obj is Scale other && Equals(other); - - /// - /// Returns a hash code for this . - /// - /// An integer value that specifies the hash code for this . - public override int GetHashCode() { unchecked { return (Horizontal.GetHashCode() * 397) ^ Vertical.GetHashCode(); } } - - /// - /// Deconstructs the scale into the horizontal and vertical value. - /// - /// The horizontal scaling value. - /// The vertical scaling value. - public void Deconstruct(out double horizontalScale, out double verticalScale) - { - horizontalScale = Horizontal; - verticalScale = Vertical; - } - - #endregion - - #region Operators - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are equal; otherwise, false. - public static bool operator ==(Scale scale1, Scale scale2) => scale1.Equals(scale2); - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are not equal; otherwise, false. - public static bool operator !=(Scale scale1, Scale scale2) => !(scale1 == scale2); - - /// - /// Returns a new representing the addition of the and the provided value. - /// - /// The . - /// The value to add. - /// A new representing the addition of the and the provided value. - public static Scale operator +(Scale scale, double value) => new Scale(scale.Horizontal + value, scale.Vertical + value); - - /// - /// Returns a new representing the subtraction of the and the provided value. - /// - /// The . - /// The value to substract. - /// A new representing the subtraction of the and the provided value. - public static Scale operator -(Scale scale, double value) => new Scale(scale.Horizontal - value, scale.Vertical - value); - - /// - /// Returns a new representing the multiplication of the and the provided value. - /// - /// The . - /// The value to multiply with. - /// A new representing the multiplication of the and the provided value. - public static Scale operator *(Scale scale, double value) => new Scale(scale.Horizontal * value, scale.Vertical * value); - - /// - /// Returns a new representing the division of the and the provided value. - /// - /// The . - /// The value to device with. - /// A new representing the division of the and the provided value. - public static Scale operator /(Scale scale, double value) => value.EqualsInTolerance(0) ? new Scale(0) : new Scale(scale.Horizontal / value, scale.Vertical / value); - - - /// - /// Converts a double to a . - /// - /// The scale value to convert. - public static implicit operator Scale(double scale) => new Scale(scale); - - #endregion + horizontalScale = Horizontal; + verticalScale = Vertical; } -} + + #endregion + + #region Operators + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are equal; otherwise, false. + public static bool operator ==(Scale scale1, Scale scale2) => scale1.Equals(scale2); + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are not equal; otherwise, false. + public static bool operator !=(Scale scale1, Scale scale2) => !(scale1 == scale2); + + /// + /// Returns a new representing the addition of the and the provided value. + /// + /// The . + /// The value to add. + /// A new representing the addition of the and the provided value. + public static Scale operator +(Scale scale, float value) => new(scale.Horizontal + value, scale.Vertical + value); + + /// + /// Returns a new representing the subtraction of the and the provided value. + /// + /// The . + /// The value to substract. + /// A new representing the subtraction of the and the provided value. + public static Scale operator -(Scale scale, float value) => new(scale.Horizontal - value, scale.Vertical - value); + + /// + /// Returns a new representing the multiplication of the and the provided value. + /// + /// The . + /// The value to multiply with. + /// A new representing the multiplication of the and the provided value. + public static Scale operator *(Scale scale, float value) => new(scale.Horizontal * value, scale.Vertical * value); + + /// + /// Returns a new representing the division of the and the provided value. + /// + /// The . + /// The value to device with. + /// A new representing the division of the and the provided value. + public static Scale operator /(Scale scale, float value) => value.EqualsInTolerance(0) ? new Scale(0) : new Scale(scale.Horizontal / value, scale.Vertical / value); + + + /// + /// Converts a float to a . + /// + /// The scale value to convert. + public static implicit operator Scale(float scale) => new(scale); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Positioning/Shape.cs b/RGB.NET.Core/Positioning/Shape.cs index f4cdfe01..74e82da9 100644 --- a/RGB.NET.Core/Positioning/Shape.cs +++ b/RGB.NET.Core/Positioning/Shape.cs @@ -1,27 +1,25 @@ using System; -using RGB.NET.Core.Layout; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Contains a list of different shapes used to define the layout of a LED. +/// +[Serializable] +public enum Shape { /// - /// Contains a list of different shapes used by . + /// A custom shape defined by vector-data. /// - [Serializable] - public enum Shape - { - /// - /// A custom shape defined by vector-data. - /// - Custom = 0, + Custom = 0, - /// - /// A simple rectangle. - /// - Rectangle = 1, + /// + /// A simple rectangle. + /// + Rectangle = 1, - /// - /// A simple circle. - /// - Circle = 2, - } -} + /// + /// A simple circle. + /// + Circle = 2, +} \ No newline at end of file diff --git a/RGB.NET.Core/Positioning/Size.cs b/RGB.NET.Core/Positioning/Size.cs index 74f91534..daba2ff1 100644 --- a/RGB.NET.Core/Positioning/Size.cs +++ b/RGB.NET.Core/Positioning/Size.cs @@ -3,194 +3,194 @@ using System.Diagnostics; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a size consisting of a width and a height. +/// +[DebuggerDisplay("[Width: {Width}, Height: {Height}]")] +public readonly struct Size { + #region Constants + + private static readonly Size INVALID = new(float.NaN, float.NaN); /// - /// Represents a size consisting of a width and a height. + /// Gets a [NaN,NaN]-Size. /// - [DebuggerDisplay("[Width: {Width}, Height: {Height}]")] - public struct Size - { - #region Constants - - /// - /// Gets a [NaN,NaN]-Size. - /// - public static Size Invalid => new Size(double.NaN, double.NaN); - - #endregion - - #region Properties & Fields - - /// - /// Gets or sets the width component value of this . - /// - public double Width { get; } - - /// - /// Gets or sets the height component value of this . - /// - public double Height { get; } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the using the provided size to define a square. - /// - /// The size used for the component value and the component value. - public Size(double size) - : this(size, size) - { } - - /// - /// Initializes a new instance of the class using the provided values. - /// - /// The size used for the component value. - /// The size used for the component value. - public Size(double width, double height) - { - this.Width = width; - this.Height = height; - } + public static ref readonly Size Invalid => ref INVALID; - #endregion + #endregion - #region Methods + #region Properties & Fields - /// - /// Converts the and of this to a human-readable string. - /// - /// A string that contains the and of this . For example "[Width: 100, Height: 20]". - public override string ToString() => $"[Width: {Width}, Height: {Height}]"; + /// + /// Gets or sets the width component value of this . + /// + public float Width { get; } - /// - /// Tests whether the specified object is a and is equivalent to this . - /// - /// The object to test. - /// true if is a equivalent to this ; otherwise, false. - public override bool Equals(object obj) - { - if (!(obj is Size)) return false; + /// + /// Gets or sets the height component value of this . + /// + public float Height { get; } - Size compareSize = (Size)obj; - return ((double.IsNaN(Width) && double.IsNaN(compareSize.Width)) || Width.EqualsInTolerance(compareSize.Width)) - && ((double.IsNaN(Height) && double.IsNaN(compareSize.Height)) || Height.EqualsInTolerance(compareSize.Height)); - } + #endregion - /// - /// Returns a hash code for this . - /// - /// An integer value that specifies the hash code for this . - public override int GetHashCode() - { - unchecked - { - int hashCode = Width.GetHashCode(); - hashCode = (hashCode * 397) ^ Height.GetHashCode(); - return hashCode; - } - } + #region Constructors + + /// + /// + /// Initializes a new instance of the using the provided size to define a square. + /// + /// The size used for the component value and the component value. + public Size(float size) + : this(size, size) + { } + + /// + /// Initializes a new instance of the class using the provided values. + /// + /// The size used for the component value. + /// The size used for the component value. + public Size(float width, float height) + { + this.Width = width; + this.Height = height; + } + + #endregion + + #region Methods + + /// + /// Converts the and of this to a human-readable string. + /// + /// A string that contains the and of this . For example "[Width: 100, Height: 20]". + public override string ToString() => $"[Width: {Width}, Height: {Height}]"; + + /// + /// Tests whether the specified object is a and is equivalent to this . + /// + /// The object to test. + /// true if is a equivalent to this ; otherwise, false. + public override bool Equals(object? obj) + { + if (obj is not Size size) return false; + + (float width, float height) = size; + return ((float.IsNaN(Width) && float.IsNaN(width)) || Width.EqualsInTolerance(width)) + && ((float.IsNaN(Height) && float.IsNaN(height)) || Height.EqualsInTolerance(height)); + } - /// - /// Deconstructs the size into the width and height value. - /// - /// The width. - /// The height. - public void Deconstruct(out double width, out double height) + /// + /// Returns a hash code for this . + /// + /// An integer value that specifies the hash code for this . + public override int GetHashCode() + { + unchecked { - width = Width; - height = Height; + int hashCode = Width.GetHashCode(); + hashCode = (hashCode * 397) ^ Height.GetHashCode(); + return hashCode; } + } - #endregion - - #region Operators - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are equal; otherwise, false. - public static bool operator ==(Size size1, Size size2) => size1.Equals(size2); - - /// - /// Returns a value that indicates whether two specified are equal. - /// - /// The first to compare. - /// The second to compare. - /// true if and are not equal; otherwise, false. - public static bool operator !=(Size size1, Size size2) => !(size1 == size2); - - /// - /// Returns a new representing the addition of the two provided . - /// - /// The first . - /// The second . - /// A new representing the addition of the two provided . - public static Size operator +(Size size1, Size size2) => new Size(size1.Width + size2.Width, size1.Height + size2.Height); - - /// - /// Returns a new created from the provided and . - /// - /// The of the rectangle. - /// The of the rectangle. - /// The rectangle created from the provided and . - public static Rectangle operator +(Size size, Point point) => new Rectangle(point, size); - - /// - /// Returns a new representing the subtraction of the two provided . - /// - /// The first . - /// The second . - /// A new representing the subtraction of the two provided . - public static Size operator -(Size size1, Size size2) => new Size(size1.Width - size2.Width, size1.Height - size2.Height); - - /// - /// Returns a new representing the multiplication of the two provided . - /// - /// The first . - /// The second . - /// A new representing the multiplication of the two provided . - public static Size operator *(Size size1, Size size2) => new Size(size1.Width * size2.Width, size1.Height * size2.Height); - - /// - /// Returns a new representing the multiplication of the and the provided factor. - /// - /// The . - /// The factor by which the should be multiplied. - /// A new representing the multiplication of the and the provided factor. - public static Size operator *(Size size, double factor) => new Size(size.Width * factor, size.Height * factor); - - /// - /// Returns a new representing the division of the two provided . - /// - /// The first . - /// The second . - /// A new representing the division of the two provided . - public static Size operator /(Size size1, Size size2) - => size2.Width.EqualsInTolerance(0) || size2.Height.EqualsInTolerance(0) - ? Invalid : new Size(size1.Width / size2.Width, size1.Height / size2.Height); - - /// - /// Returns a new representing the division of the and the provided factor. - /// - /// The . - /// The factor by which the should be divided. - /// A new representing the division of the and the provided factor. - public static Size operator /(Size size, double factor) => factor.EqualsInTolerance(0) ? Invalid : new Size(size.Width / factor, size.Height / factor); - - /// - /// Returns a new representing the multiplication of the and the given . - /// - /// The to scale. - /// The scaling factor. - /// A new representing the multiplication of the and the given . - public static Size operator *(Size size, Scale scale) => new Size(size.Width * scale.Horizontal, size.Height * scale.Vertical); - - #endregion + /// + /// Deconstructs the size into the width and height value. + /// + /// The width. + /// The height. + public void Deconstruct(out float width, out float height) + { + width = Width; + height = Height; } -} + + #endregion + + #region Operators + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are equal; otherwise, false. + public static bool operator ==(in Size size1, in Size size2) => size1.Equals(size2); + + /// + /// Returns a value that indicates whether two specified are equal. + /// + /// The first to compare. + /// The second to compare. + /// true if and are not equal; otherwise, false. + public static bool operator !=(in Size size1, in Size size2) => !(size1 == size2); + + /// + /// Returns a new representing the addition of the two provided . + /// + /// The first . + /// The second . + /// A new representing the addition of the two provided . + public static Size operator +(in Size size1, in Size size2) => new(size1.Width + size2.Width, size1.Height + size2.Height); + + /// + /// Returns a new created from the provided and . + /// + /// The of the rectangle. + /// The of the rectangle. + /// The rectangle created from the provided and . + public static Rectangle operator +(in Size size, in Point point) => new(point, size); + + /// + /// Returns a new representing the subtraction of the two provided . + /// + /// The first . + /// The second . + /// A new representing the subtraction of the two provided . + public static Size operator -(in Size size1, in Size size2) => new(size1.Width - size2.Width, size1.Height - size2.Height); + + /// + /// Returns a new representing the multiplication of the two provided . + /// + /// The first . + /// The second . + /// A new representing the multiplication of the two provided . + public static Size operator *(in Size size1, in Size size2) => new(size1.Width * size2.Width, size1.Height * size2.Height); + + /// + /// Returns a new representing the multiplication of the and the provided factor. + /// + /// The . + /// The factor by which the should be multiplied. + /// A new representing the multiplication of the and the provided factor. + public static Size operator *(in Size size, float factor) => new(size.Width * factor, size.Height * factor); + + /// + /// Returns a new representing the division of the two provided . + /// + /// The first . + /// The second . + /// A new representing the division of the two provided . + public static Size operator /(in Size size1, in Size size2) + => size2.Width.EqualsInTolerance(0) || size2.Height.EqualsInTolerance(0) + ? Invalid : new Size(size1.Width / size2.Width, size1.Height / size2.Height); + + /// + /// Returns a new representing the division of the and the provided factor. + /// + /// The . + /// The factor by which the should be divided. + /// A new representing the division of the and the provided factor. + public static Size operator /(in Size size, float factor) => factor.EqualsInTolerance(0) ? Invalid : new Size(size.Width / factor, size.Height / factor); + + /// + /// Returns a new representing the multiplication of the and the specified . + /// + /// The to scale. + /// The scaling factor. + /// A new representing the multiplication of the and the specified . + public static Size operator *(in Size size, in Scale scale) => new(size.Width * scale.Horizontal, size.Height * scale.Vertical); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/README.md b/RGB.NET.Core/README.md new file mode 100644 index 00000000..d31978bc --- /dev/null +++ b/RGB.NET.Core/README.md @@ -0,0 +1,36 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Core-Package. + +Required to use RGB.NET + +## Getting Started +```csharp +// Create a surface - this is where all devices belongs too +RGBSurface surface = new RGBSurface(); + +// Load your devices - check out the RGB.NET.Devices-packages for more information +// TODO: Load device-providers + +// Automatically align devices to not overlap - you can ofc also move them by hand +surface.AlignDevices(); + +// Register an update-trigger +surface.RegisterUpdateTrigger(new TimerUpdateTrigger()); +``` + +## Basis Rendering +```csharp +// Create a led-group containing all leds on the surface +ILedGroup allLeds = new ListLedGroup(surface, surface.Leds); + +// Create a rainbow gradient +RainbowGradient rainbow = new RainbowGradient(); + +// Animate the gradient to steadily move +rainbow.AddDecorator(new MoveGradientDecorator(surface)); + +// Create a texture rendering that gradient +ITexture texture = new ConicalGradientTexture(new Size(10, 10), rainbow); + +// Create a brush rendering the texture and assign it to the group +allLeds.Brush = new TextureBrush(texture); +``` \ No newline at end of file diff --git a/RGB.NET.Core/RGB.NET.Core.csproj b/RGB.NET.Core/RGB.NET.Core.csproj index 6fab932b..63573888 100644 --- a/RGB.NET.Core/RGB.NET.Core.csproj +++ b/RGB.NET.Core/RGB.NET.Core.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Core Core-Module of RGB.NET Core-Module of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,32 +35,26 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg + true $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - - + + + + \ No newline at end of file diff --git a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings index 9555e90e..bf7655f9 100644 --- a/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings +++ b/RGB.NET.Core/RGB.NET.Core.csproj.DotSettings @@ -9,13 +9,20 @@ True True True + True True True True True + True True True True + True + True + True + True True True - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Core/RGBSurface.cs b/RGB.NET.Core/RGBSurface.cs index 74bc8829..f8ec4378 100644 --- a/RGB.NET.Core/RGBSurface.cs +++ b/RGB.NET.Core/RGBSurface.cs @@ -7,290 +7,379 @@ using System.Diagnostics; using System.Linq; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// +/// Represents a RGB-surface containing multiple devices. +/// +public sealed class RGBSurface : AbstractBindable, IDisposable { - /// - /// + #region Properties & Fields + + private readonly Stopwatch _deltaTimeCounter; + + private readonly IList _devices = new List(); + private readonly IList _updateTriggers = new List(); + private readonly List _ledGroups = new(); + + /// + /// Gets a readonly list containing all loaded . + /// This collection should be locked when enumerated in a multi-threaded application. + /// + public IReadOnlyList Devices { get; } + /// - /// Represents a RGB-surface containing multiple devices. + /// Gets a readonly list containing all registered . + /// This collection should be locked when enumerated in a multi-threaded application. /// - public partial class RGBSurface : AbstractBindable, IDisposable + public IReadOnlyList UpdateTriggers { get; } + + /// + /// Gets a copy of the representing this . + /// + public Rectangle Boundary { get; private set; } = new(new Point(0, 0), new Size(0, 0)); + + /// + /// Gets a list of all on this . + /// + public IEnumerable Leds { - #region Properties & Fields + get + { + lock (Devices) + return _devices.SelectMany(x => x); + } + } - /// - /// Gets the singelot-instance of the class. - /// - public static RGBSurface Instance { get; } = new RGBSurface(); + #endregion - private Stopwatch _deltaTimeCounter; + #region EventHandler - private IList _deviceProvider = new List(); - private IList _devices = new List(); - private IList _updateTriggers = new List(); + /// + /// Represents the event-handler of the -event. + /// + /// The arguments provided by the event. + public delegate void ExceptionEventHandler(ExceptionEventArgs args); - // ReSharper disable InconsistentNaming + /// + /// Represents the event-handler of the -event. + /// + /// The arguments provided by the event. + public delegate void UpdatingEventHandler(UpdatingEventArgs args); - private readonly LinkedList _ledGroups = new LinkedList(); + /// + /// Represents the event-handler of the -event. + /// + /// The arguments provided by the event. + public delegate void UpdatedEventHandler(UpdatedEventArgs args); - // ReSharper restore InconsistentNaming + /// + /// Represents the event-handler of the -event. + /// + /// The arguments provided by the event. + public delegate void SurfaceLayoutChangedEventHandler(SurfaceLayoutChangedEventArgs args); - /// - /// Gets a readonly list containing all loaded . - /// - public IEnumerable Devices - { - get - { - lock (_devices) - return new ReadOnlyCollection(_devices); - } - } + #endregion - /// - /// Gets a readonly list containing all registered . - /// - public IEnumerable UpdateTriggers => new ReadOnlyCollection(_updateTriggers); + #region Events - /// - /// Gets a copy of the representing this . - /// - public Rectangle SurfaceRectangle { get; private set; } + // ReSharper disable EventNeverSubscribedTo.Global - /// - /// Gets a list of all on this . - /// - public IEnumerable Leds - { - get - { - lock (_devices) - return _devices.SelectMany(x => x); - } - } + /// + /// Occurs when a catched exception is thrown inside the . + /// + public event ExceptionEventHandler? Exception; - #endregion + /// + /// Occurs when the starts updating. + /// + public event UpdatingEventHandler? Updating; + + /// + /// Occurs when the update is done. + /// + public event UpdatedEventHandler? Updated; + + /// + /// Occurs when the layout of this changed. + /// + public event SurfaceLayoutChangedEventHandler? SurfaceLayoutChanged; + + // ReSharper restore EventNeverSubscribedTo.Global + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public RGBSurface() + { + _deltaTimeCounter = Stopwatch.StartNew(); + + Devices = new ReadOnlyCollection(_devices); + UpdateTriggers = new ReadOnlyCollection(_updateTriggers); + } + + #endregion + + #region Methods + + /// + /// Perform a full update for all devices. Updates only dirty by default, or all , if flushLeds is set to true. + /// + /// Specifies whether all , (including clean ones) should be updated. + public void Update(bool flushLeds = false) => Update(null, new CustomUpdateData((CustomUpdateDataIndex.FLUSH_LEDS, flushLeds))); - #region Constructors + private void Update(object? updateTrigger, CustomUpdateData customData) => Update(updateTrigger as IUpdateTrigger, customData); - /// - /// Initializes a new instance of the class. - /// - private RGBSurface() + private void Update(IUpdateTrigger? updateTrigger, CustomUpdateData customData) + { + try + { + bool flushLeds = customData[CustomUpdateDataIndex.FLUSH_LEDS] as bool? ?? false; + bool render = customData[CustomUpdateDataIndex.RENDER] as bool? ?? true; + bool updateDevices = customData[CustomUpdateDataIndex.UPDATE_DEVICES] as bool? ?? true; + + lock (UpdateTriggers) + lock (Devices) + { + OnUpdating(updateTrigger, customData); + + if (render) + lock (_ledGroups) + { + // Render brushes + foreach (ILedGroup ledGroup in _ledGroups) + try { Render(ledGroup); } + catch (Exception ex) { OnException(ex); } + } + + if (updateDevices) + foreach (IRGBDevice device in _devices) + try { device.Update(flushLeds); } + catch (Exception ex) { OnException(ex); } + + OnUpdated(); + } + } + catch (Exception ex) { - _deltaTimeCounter = Stopwatch.StartNew(); + OnException(ex); } + } + + /// + public void Dispose() + { + List devices; + lock (Devices) + devices = new List(_devices); - #endregion + foreach (IRGBDevice device in devices) + try { Detach(device); } + catch { /* We do what we can */} - #region Methods + foreach (IUpdateTrigger updateTrigger in _updateTriggers) + try { updateTrigger.Dispose(); } + catch { /* We do what we can */} - /// - /// Perform a full update for all devices. Updates only dirty by default, or all , if flushLeds is set to true. - /// - /// Specifies whether all , (including clean ones) should be updated. - public void Update(bool flushLeds = false) => Update(null, new CustomUpdateData(("flushLeds", flushLeds))); + _ledGroups.Clear(); + } + + /// + /// Renders a ledgroup. + /// + /// The led group to render. + /// Thrown if the of the Brush is not valid. + private void Render(ILedGroup ledGroup) + { + IList leds = ledGroup.ToList(); + IBrush? brush = ledGroup.Brush; - private void Update(object updateTrigger, CustomUpdateData customData) => Update(updateTrigger as IUpdateTrigger, customData); + if ((brush == null) || !brush.IsEnabled) return; - private void Update(IUpdateTrigger updateTrigger, CustomUpdateData customData) + IEnumerable<(RenderTarget renderTarget, Color color)> render; + switch (brush.CalculationMode) { - if (customData == null) - customData = new CustomUpdateData(); - - try - { - bool flushLeds = customData["flushLeds"] as bool? ?? false; - bool syncBack = customData["syncBack"] as bool? ?? true; - bool render = customData["render"] as bool? ?? true; - bool updateDevices = customData["updateDevices"] as bool? ?? true; - - lock (_updateTriggers) - lock (_devices) - { - OnUpdating(updateTrigger, customData); - - if (syncBack) - foreach (IRGBDevice device in _devices) - if (device.UpdateMode.HasFlag(DeviceUpdateMode.SyncBack) && device.DeviceInfo.SupportsSyncBack) - try { device.SyncBack(); } - catch (Exception ex) { OnException(ex); } - - if (render) - lock (_ledGroups) - { - // Render brushes - foreach (ILedGroup ledGroup in _ledGroups.OrderBy(x => x.ZIndex)) - try { Render(ledGroup); } - catch (Exception ex) { OnException(ex); } - } - - if (updateDevices) - foreach (IRGBDevice device in _devices) - if (!device.UpdateMode.HasFlag(DeviceUpdateMode.NoUpdate)) - try { device.Update(flushLeds); } - catch (Exception ex) { OnException(ex); } - - OnUpdated(); - } - } - catch (Exception ex) - { - OnException(ex); - } + case RenderMode.Relative: + Rectangle brushRectangle = new(leds.Select(led => led.AbsoluteBoundary)); + Point offset = new(-brushRectangle.Location.X, -brushRectangle.Location.Y); + brushRectangle = brushRectangle.SetLocation(new Point(0, 0)); + render = brush.Render(brushRectangle, leds.Select(led => new RenderTarget(led, led.AbsoluteBoundary.Translate(offset)))); + break; + case RenderMode.Absolute: + render = brush.Render(Boundary, leds.Select(led => new RenderTarget(led, led.AbsoluteBoundary))); + break; + default: + throw new ArgumentException($"The CalculationMode '{brush.CalculationMode}' is not valid."); } - /// - public void Dispose() + foreach ((RenderTarget renderTarget, Color c) in render) + renderTarget.Led.Color = c; + } + + /// + /// Attaches the specified . + /// + /// The to attach. + /// true if the could be attached; otherwise, false. + public bool Attach(ILedGroup ledGroup) + { + lock (_ledGroups) { - lock (_devices) - foreach (IRGBDevice device in _devices) - try { device.Dispose(); } - catch { /* We do what we can */} - - lock (_deviceProvider) - foreach (IRGBDeviceProvider deviceProvider in _deviceProvider) - try { deviceProvider.Dispose(); } - catch { /* We do what we can */} - - foreach (IUpdateTrigger updateTrigger in _updateTriggers) - try { updateTrigger.Dispose(); } - catch { /* We do what we can */} - - _ledGroups.Clear(); - _devices = null; - _deviceProvider = null; + if (ledGroup.Surface != null) return false; + + ledGroup.Surface = this; + _ledGroups.Add(ledGroup); + _ledGroups.Sort((group1, group2) => group1.ZIndex.CompareTo(group2.ZIndex)); + ledGroup.OnAttach(); + + return true; } + } - /// - /// Renders a ledgroup. - /// - /// The led group to render. - private void Render(ILedGroup ledGroup) + /// + /// Detaches the specified . + /// + /// The to detache. + /// true if the could be detached; false otherwise. + public bool Detach(ILedGroup ledGroup) + { + lock (_ledGroups) { - IList leds = ledGroup.GetLeds().ToList(); - IBrush brush = ledGroup.Brush; - - if ((brush == null) || !brush.IsEnabled) return; - - switch (brush.BrushCalculationMode) - { - case BrushCalculationMode.Relative: - Rectangle brushRectangle = new Rectangle(leds.Select(led => led.AbsoluteLedRectangle)); - Point offset = new Point(-brushRectangle.Location.X, -brushRectangle.Location.Y); - brushRectangle = brushRectangle.SetLocation(new Point(0, 0)); - brush.PerformRender(brushRectangle, leds.Select(led => new BrushRenderTarget(led, led.AbsoluteLedRectangle.Translate(offset)))); - break; - case BrushCalculationMode.Absolute: - brush.PerformRender(SurfaceRectangle, leds.Select(led => new BrushRenderTarget(led, led.AbsoluteLedRectangle))); - break; - default: - throw new ArgumentException(); - } - - //brush.UpdateEffects(); - brush.PerformFinalize(); - - foreach (KeyValuePair renders in brush.RenderedTargets) - renders.Key.Led.Color = renders.Value; + if (!_ledGroups.Remove(ledGroup)) return false; + ledGroup.OnDetach(); + ledGroup.Surface = null; + + return true; } + } - /// - /// Attaches the given . - /// - /// The to attach. - /// true if the could be attached; otherwise, false. - public bool AttachLedGroup(ILedGroup ledGroup) + /// + /// Attaches the specified . + /// + /// The to attach. + public void Attach(IRGBDevice device) + { + lock (Devices) { - if (ledGroup == null) return false; - - lock (_ledGroups) - { - if (_ledGroups.Contains(ledGroup)) return false; + if (string.IsNullOrWhiteSpace(device.DeviceInfo.DeviceName)) throw new RGBDeviceException($"The device '{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model}' has no valid name."); + if (device.Surface != null) throw new RGBSurfaceException($"The device '{device.DeviceInfo.DeviceName}' is already attached to a surface."); - _ledGroups.AddLast(ledGroup); - ledGroup.OnAttach(); + device.Surface = this; + device.BoundaryChanged += DeviceOnBoundaryChanged; - return true; - } + _devices.Add(device); + OnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs.FromAddedDevice(device)); } + } - /// - /// Detaches the given . - /// - /// The to detached. - /// true if the could be detached; otherwise, false. - public bool DetachLedGroup(ILedGroup ledGroup) + /// + /// Detaches the specified . + /// + /// The to detache. + /// true if the could be detached; false otherwise. + public void Detach(IRGBDevice device) + { + lock (Devices) { - if (ledGroup == null) return false; + if (!_devices.Contains(device)) throw new RGBSurfaceException($"The device '{device.DeviceInfo.DeviceName}' is not attached to this surface."); - lock (_ledGroups) - { - LinkedListNode node = _ledGroups.Find(ledGroup); - if (node == null) return false; + device.BoundaryChanged -= DeviceOnBoundaryChanged; + device.Surface = null; - _ledGroups.Remove(node); - node.Value.OnDetach(); + _devices.Remove(device); - return true; - } + OnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs.FromRemovedDevice(device)); } + } + + // ReSharper restore UnusedMember.Global + + private void DeviceOnBoundaryChanged(object? sender, EventArgs args) + => OnSurfaceLayoutChanged((sender is IRGBDevice device) ? SurfaceLayoutChangedEventArgs.FromChangedDevice(device) : SurfaceLayoutChangedEventArgs.Misc()); - private void UpdateSurfaceRectangle() + private void OnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) + { + UpdateSurfaceRectangle(); + + SurfaceLayoutChanged?.Invoke(args); + } + + private void UpdateSurfaceRectangle() + { + lock (Devices) { - lock (_devices) - { - Rectangle devicesRectangle = new Rectangle(_devices.Select(d => d.DeviceRectangle)); - SurfaceRectangle = SurfaceRectangle.SetSize(new Size(devicesRectangle.Location.X + devicesRectangle.Size.Width, devicesRectangle.Location.Y + devicesRectangle.Size.Height)); - } + Rectangle devicesRectangle = new(_devices.Select(d => d.Boundary)); + Boundary = Boundary.SetSize(new Size(devicesRectangle.Location.X + devicesRectangle.Size.Width, devicesRectangle.Location.Y + devicesRectangle.Size.Height)); } + } - /// - /// Gets all devices of a specific type. - /// - /// The type of devices to get. - /// A list of devices with the specified type. - public IList GetDevices() - where T : class + /// + /// Registers the provided . + /// + /// The to register. + public void RegisterUpdateTrigger(IUpdateTrigger updateTrigger) + { + if (!_updateTriggers.Contains(updateTrigger)) { - lock (_devices) - return new ReadOnlyCollection(_devices.Select(x => x as T).Where(x => x != null).ToList()); + _updateTriggers.Add(updateTrigger); + updateTrigger.Update += Update; } + } + + /// + /// Unregisters the provided . + /// + /// The to unregister. + public void UnregisterUpdateTrigger(IUpdateTrigger updateTrigger) + { + if (_updateTriggers.Remove(updateTrigger)) + updateTrigger.Update -= Update; + } - /// - /// Gets all devices of the specified . - /// - /// The of the devices to get. - /// a list of devices matching the specified . - public IList GetDevices(RGBDeviceType deviceType) + /// + /// Handles the needed event-calls for an exception. + /// + /// The exception previously thrown. + private void OnException(Exception ex) + { + try { - lock (_devices) - return new ReadOnlyCollection(_devices.Where(d => deviceType.HasFlag(d.DeviceInfo.DeviceType)).ToList()); + Exception?.Invoke(new ExceptionEventArgs(ex)); } + catch { /* Well ... that's not my fault */ } + } - /// - /// Registers the provided . - /// - /// The to register. - public void RegisterUpdateTrigger(IUpdateTrigger updateTrigger) + /// + /// Handles the needed event-calls before updating. + /// + private void OnUpdating(IUpdateTrigger? trigger, CustomUpdateData customData) + { + try { - if (!_updateTriggers.Contains(updateTrigger)) - { - _updateTriggers.Add(updateTrigger); - updateTrigger.Update += Update; - } + double deltaTime = _deltaTimeCounter.Elapsed.TotalSeconds; + _deltaTimeCounter.Restart(); + Updating?.Invoke(new UpdatingEventArgs(deltaTime, trigger, customData)); } + catch { /* Well ... that's not my fault */ } + } - /// - /// Unregisters the provided . - /// - /// The to unregister. - public void UnregisterUpdateTrigger(IUpdateTrigger updateTrigger) + /// + /// Handles the needed event-calls after an update. + /// + private void OnUpdated() + { + try { - if (_updateTriggers.Remove(updateTrigger)) - updateTrigger.Update -= Update; + Updated?.Invoke(new UpdatedEventArgs()); } - - #endregion + catch { /* Well ... that's not my fault */ } } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/RGBSurfaceDeviceEvents.cs b/RGB.NET.Core/RGBSurfaceDeviceEvents.cs deleted file mode 100644 index 8af4f06f..00000000 --- a/RGB.NET.Core/RGBSurfaceDeviceEvents.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; - -namespace RGB.NET.Core -{ - public partial class RGBSurface - { - #region EventHandler - - /// - /// Represents the event-handler of the -event. - /// - /// The arguments provided by the event. - public delegate void ExceptionEventHandler(ExceptionEventArgs args); - - /// - /// Represents the event-handler of the -event. - /// - /// The arguments provided by the event. - public delegate void UpdatingEventHandler(UpdatingEventArgs args); - - /// - /// Represents the event-handler of the -event. - /// - /// The arguments provided by the event. - public delegate void UpdatedEventHandler(UpdatedEventArgs args); - - /// - /// Represents the event-handler of the -event. - /// - /// - public delegate void SurfaceLayoutChangedEventHandler(SurfaceLayoutChangedEventArgs args); - - #endregion - - #region Events - - // ReSharper disable EventNeverSubscribedTo.Global - - /// - /// Occurs when a catched exception is thrown inside the . - /// - public event ExceptionEventHandler Exception; - - /// - /// Occurs when the starts updating. - /// - public event UpdatingEventHandler Updating; - - /// - /// Occurs when the update is done. - /// - public event UpdatedEventHandler Updated; - - /// - /// Occurs when the layout of this changed. - /// - public event SurfaceLayoutChangedEventHandler SurfaceLayoutChanged; - - // ReSharper restore EventNeverSubscribedTo.Global - - #endregion - - #region Methods - - /// - /// Handles the needed event-calls for an exception. - /// - /// The exception previously thrown. - private void OnException(Exception ex) - { - try - { - Exception?.Invoke(new ExceptionEventArgs(ex)); - } - catch { /* Well ... that's not my fault */ } - } - - /// - /// Handles the needed event-calls before updating. - /// - private void OnUpdating(IUpdateTrigger trigger, CustomUpdateData customData) - { - try - { - double deltaTime = _deltaTimeCounter.Elapsed.TotalSeconds; - _deltaTimeCounter.Restart(); - Updating?.Invoke(new UpdatingEventArgs(deltaTime, trigger, customData)); - } - catch { /* Well ... that's not my fault */ } - } - - /// - /// Handles the needed event-calls after an update. - /// - private void OnUpdated() - { - try - { - Updated?.Invoke(new UpdatedEventArgs()); - } - catch { /* Well ... that's not my fault */ } - } - - #endregion - } -} diff --git a/RGB.NET.Core/RGBSurfaceDeviceLoader.cs b/RGB.NET.Core/RGBSurfaceDeviceLoader.cs deleted file mode 100644 index df760c32..00000000 --- a/RGB.NET.Core/RGBSurfaceDeviceLoader.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; - -namespace RGB.NET.Core -{ - public partial class RGBSurface - { - #region Methods - - // ReSharper disable UnusedMember.Global - /// - /// Loads all devices the given by the provided by the give . - /// - /// The which provides the to load the devices from. - /// Specifies which types of devices to load. - /// Specifies whether the application should request exclusive access of possible or not. - /// Specifies whether exception during the initialization sequence should be thrown or not. - public void LoadDevices(IRGBDeviceProviderLoader deviceProviderLoader, RGBDeviceType loadFilter = RGBDeviceType.All, - bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - => LoadDevices(deviceProviderLoader.GetDeviceProvider(), loadFilter, exclusiveAccessIfPossible, throwExceptions); - - /// - /// Loads all devices the given is able to provide. - /// - /// The to load the devices from. - /// Specifies which types of devices to load. - /// Specifies whether the application should request exclusive access of possible or not. - /// Specifies whether exception during the initialization sequence should be thrown or not. - public void LoadDevices(IRGBDeviceProvider deviceProvider, RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - lock (_deviceProvider) - { - if (_deviceProvider.Contains(deviceProvider) || _deviceProvider.Any(x => x.GetType() == deviceProvider.GetType())) return; - - List addedDevices = new List(); - if (deviceProvider.IsInitialized || deviceProvider.Initialize(loadFilter, exclusiveAccessIfPossible, throwExceptions)) - { - _deviceProvider.Add(deviceProvider); - lock (_devices) - foreach (IRGBDevice device in deviceProvider.Devices) - { - if (_devices.Contains(device)) continue; - - addedDevices.Add(device); - - device.PropertyChanged += DeviceOnPropertyChanged; - _devices.Add(device); - } - } - - if (addedDevices.Any()) - { - UpdateSurfaceRectangle(); - SurfaceLayoutChanged?.Invoke(new SurfaceLayoutChangedEventArgs(addedDevices, true, false)); - } - } - } - - /// - /// Automatically aligns all devices to prevent overlaps. - /// - public void AlignDevices() - { - double posX = 0; - foreach (IRGBDevice device in Devices) - { - device.Location += new Point(posX, 0); - posX += device.ActualSize.Width + 1; - } - } - - // ReSharper restore UnusedMember.Global - - private void DeviceOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs) - { - UpdateSurfaceRectangle(); - SurfaceLayoutChanged?.Invoke(new SurfaceLayoutChangedEventArgs(new[] { sender as IRGBDevice }, false, true)); - } - - #endregion - } -} diff --git a/RGB.NET.Core/Rendering/Brushes/AbstractBrush.cs b/RGB.NET.Core/Rendering/Brushes/AbstractBrush.cs new file mode 100644 index 00000000..553e53b1 --- /dev/null +++ b/RGB.NET.Core/Rendering/Brushes/AbstractBrush.cs @@ -0,0 +1,108 @@ +// ReSharper disable VirtualMemberNeverOverriden.Global +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable VirtualMemberNeverOverridden.Global + +using System.Collections.Generic; + +namespace RGB.NET.Core; + +/// +/// +/// +/// Represents a basic brush. +/// +public abstract class AbstractBrush : AbstractDecoratable, IBrush +{ + #region Properties & Fields + + /// + public bool IsEnabled { get; set; } = true; + + /// + public RenderMode CalculationMode { get; set; } = RenderMode.Relative; + + /// + public float Brightness { get; set; } + + /// + public float Opacity { get; set; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The overall percentage brightness of the brush. (default: 1.0) + /// The overall percentage opacity of the brush. (default: 1.0) + protected AbstractBrush(float brightness = 1, float opacity = 1) + { + this.Brightness = brightness; + this.Opacity = opacity; + } + + #endregion + + #region Methods + + /// + /// Renders the brush to the specified list of . + /// + /// The bounding box the brush is rendered in. + /// The targets to render to. + /// A enumerable containing the rendered for each . + public virtual IEnumerable<(RenderTarget renderTarget, Color color)> Render(Rectangle rectangle, IEnumerable renderTargets) + { + foreach (RenderTarget renderTarget in renderTargets) + { + Color color = GetColorAtPoint(rectangle, renderTarget); + ApplyDecorators(rectangle, renderTarget, ref color); + FinalizeColor(ref color); + yield return (renderTarget, color); + } + } + + /// + /// Applies all attached and enabled decorators to the brush. + /// + /// The rectangle in which the brush should be drawn. + /// The target (key/point) from which the color should be taken. + /// The to be modified. + protected virtual void ApplyDecorators(in Rectangle rectangle, in RenderTarget renderTarget, ref Color color) + { + if (Decorators.Count == 0) return; + + lock (Decorators) + foreach (IBrushDecorator decorator in Decorators) + if (decorator.IsEnabled) + decorator.ManipulateColor(rectangle, renderTarget, ref color); + } + + /// + /// Gets the color at an specific point assuming the brush is drawn into the specified rectangle. + /// + /// The rectangle in which the brush should be drawn. + /// The target (key/point) from which the color should be taken. + /// The color at the specified point. + protected abstract Color GetColorAtPoint(in Rectangle rectangle, in RenderTarget renderTarget); + + /// + /// Finalizes the color by appliing the overall brightness and opacity.
+ ///
+ /// The color to finalize. + /// The finalized color. + protected virtual void FinalizeColor(ref Color color) + { + // Since we use HSV to calculate there is no way to make a color 'brighter' than 100% + // Be carefull with the naming: Since we use HSV the correct term is 'value' but outside we call it 'brightness' + // THIS IS NOT A HSB CALCULATION!!! + if (Brightness < 1) + color = color.MultiplyHSV(value: Brightness.Clamp(0, 1)); + + if (Opacity < 1) + color = color.MultiplyA(Opacity.Clamp(0, 1)); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/Brushes/IBrush.cs b/RGB.NET.Core/Rendering/Brushes/IBrush.cs new file mode 100644 index 00000000..cefa339e --- /dev/null +++ b/RGB.NET.Core/Rendering/Brushes/IBrush.cs @@ -0,0 +1,40 @@ +// ReSharper disable UnusedMemberInSuper.Global +// ReSharper disable UnusedMember.Global +// ReSharper disable ReturnTypeCanBeEnumerable.Global + +using System.Collections.Generic; + +namespace RGB.NET.Core; + +/// +/// Represents a basic brush. +/// +public interface IBrush : IDecoratable +{ + /// + /// Gets or sets if the is enabled and will be drawn on an update. + /// + bool IsEnabled { get; set; } + + /// + /// Gets or sets the calculation mode used for the rectangle/points used for color-selection in brushes. + /// + RenderMode CalculationMode { get; set; } + + /// + /// Gets or sets the overall percentage brightness of the . + /// + float Brightness { get; set; } + + /// + /// Gets or sets the overall percentage opacity of the . + /// + float Opacity { get; set; } + + /// + /// Performs the render pass of the and calculates the raw for all requested . + /// + /// The in which the brush should be drawn. + /// The (keys/points) of which the color should be calculated. + IEnumerable<(RenderTarget renderTarget, Color color)> Render(Rectangle rectangle, IEnumerable renderTargets); +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/Brushes/SolidColorBrush.cs b/RGB.NET.Core/Rendering/Brushes/SolidColorBrush.cs new file mode 100644 index 00000000..4175db11 --- /dev/null +++ b/RGB.NET.Core/Rendering/Brushes/SolidColorBrush.cs @@ -0,0 +1,61 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global + +namespace RGB.NET.Core; + +/// +/// +/// Represents a brush drawing only a single color. +/// +public class SolidColorBrush : AbstractBrush +{ + #region Properties & Fields + + private Color _color; + /// + /// Gets or sets the drawn by this . + /// + public Color Color + { + get => _color; + set => SetProperty(ref _color, value); + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The drawn by this . + public SolidColorBrush(Color color) + { + this.Color = color; + } + + #endregion + + #region Methods + + /// + protected override Color GetColorAtPoint(in Rectangle rectangle, in RenderTarget renderTarget) => Color; + + #endregion + + #region Operators + + /// + /// Converts a to a . + /// + /// The to convert. + public static explicit operator SolidColorBrush(Color color) => new(color); + + /// + /// Converts a to a . + /// + /// The to convert. + public static implicit operator Color(SolidColorBrush brush) => brush.Color; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/Brushes/TextureBrush.cs b/RGB.NET.Core/Rendering/Brushes/TextureBrush.cs new file mode 100644 index 00000000..4a2de6e7 --- /dev/null +++ b/RGB.NET.Core/Rendering/Brushes/TextureBrush.cs @@ -0,0 +1,46 @@ +namespace RGB.NET.Core; + +/// +/// +/// Represents a brush drawing a texture. +/// +public class TextureBrush : AbstractBrush +{ + #region Properties & Fields + + private ITexture _texture = ITexture.Empty; + /// + /// Gets or sets the texture drawn by this brush. + /// + public ITexture Texture + { + get => _texture; + set => SetProperty(ref _texture, value); + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The texture drawn by this brush. + public TextureBrush(ITexture texture) + { + this.Texture = texture; + } + + #endregion + + #region Methods + + /// + protected override Color GetColorAtPoint(in Rectangle rectangle, in RenderTarget renderTarget) + { + Rectangle normalizedRect = renderTarget.Rectangle / rectangle; + return Texture[normalizedRect]; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/RenderMode.cs b/RGB.NET.Core/Rendering/RenderMode.cs new file mode 100644 index 00000000..4c9199e5 --- /dev/null +++ b/RGB.NET.Core/Rendering/RenderMode.cs @@ -0,0 +1,19 @@ +// ReSharper disable UnusedMember.Global + +namespace RGB.NET.Core; + +/// +/// Contains a list of all brush calculation modes. +/// +public enum RenderMode +{ + /// + /// The calculation for will be the rectangle around the the is applied to. + /// + Relative, + + /// + /// The calculation for will always be the whole . + /// + Absolute +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/RenderTarget.cs b/RGB.NET.Core/Rendering/RenderTarget.cs new file mode 100644 index 00000000..f8b6d6af --- /dev/null +++ b/RGB.NET.Core/Rendering/RenderTarget.cs @@ -0,0 +1,44 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedAutoPropertyAccessor.Global + +namespace RGB.NET.Core; + +/// +/// Represents a single target of a brush render. +/// +public readonly struct RenderTarget +{ + #region Properties & Fields + + /// + /// Gets the target-. + /// + public Led Led { get; } + + /// + /// Gets the representing the area to render the target-. + /// + public Rectangle Rectangle { get; } + + /// + /// Gets the representing the position to render the target-. + /// + public Point Point => Rectangle.Center; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The target-. + /// The representing the area to render the target-. + public RenderTarget(Led led, Rectangle rectangle) + { + this.Led = led; + this.Rectangle = rectangle; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/Textures/EmptyTexture.cs b/RGB.NET.Core/Rendering/Textures/EmptyTexture.cs new file mode 100644 index 00000000..588b62b8 --- /dev/null +++ b/RGB.NET.Core/Rendering/Textures/EmptyTexture.cs @@ -0,0 +1,12 @@ +namespace RGB.NET.Core; + +internal class EmptyTexture : ITexture +{ + #region Properties & Fields + + public Size Size { get; } = new(0, 0); + public Color this[in Point point] => Color.Transparent; + public Color this[in Rectangle rectangle] => Color.Transparent; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/Textures/ITexture.cs b/RGB.NET.Core/Rendering/Textures/ITexture.cs new file mode 100644 index 00000000..8fdd2ae7 --- /dev/null +++ b/RGB.NET.Core/Rendering/Textures/ITexture.cs @@ -0,0 +1,31 @@ +namespace RGB.NET.Core; + +/// +/// Represents a generic texture. +/// +public interface ITexture +{ + /// + /// Gets a empty texture. + /// + static ITexture Empty => new EmptyTexture(); + + /// + /// Gets the size of the texture + /// + Size Size { get; } + + /// + /// Gets the color at the specified location. + /// + /// The location to get the color from. + /// The color at the specified location. + Color this[in Point point] { get; } + + /// + /// Gets the sampled color inside the specified rectangle. + /// + /// The rectangle to get the color from. + /// The sampled color. + Color this[in Rectangle rectangle] { get; } +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/Textures/PixelTexture.cs b/RGB.NET.Core/Rendering/Textures/PixelTexture.cs new file mode 100644 index 00000000..3672e2ce --- /dev/null +++ b/RGB.NET.Core/Rendering/Textures/PixelTexture.cs @@ -0,0 +1,231 @@ +using System; +using System.Buffers; +using System.Runtime.CompilerServices; + +namespace RGB.NET.Core; + +/// +/// +/// Represents a texture made of pixels (like a common image). +/// +/// The type of the pixels. +public abstract class PixelTexture : ITexture + where T : unmanaged +{ + #region Constants + + private const int STACK_ALLOC_LIMIT = 1024; + + #endregion + + #region Properties & Fields + + private readonly int _dataPerPixel; + private readonly int _stride; + + /// + /// Gets or sets the sampler used to get the color of a region. + /// + public ISampler Sampler { get; set; } + + /// + public Size Size { get; } + + /// + /// Gets the underlying pixel data. + /// + protected abstract ReadOnlySpan Data { get; } + + /// + public virtual Color this[in Point point] + { + get + { + if (Data.Length == 0) return Color.Transparent; + + int x = (int)MathF.Round((Size.Width - 1) * point.X.Clamp(0, 1)); + int y = (int)MathF.Round((Size.Height - 1) * point.Y.Clamp(0, 1)); + return GetColor(GetPixelData(x, y)); + } + } + + /// + public virtual Color this[in Rectangle rectangle] + { + get + { + if (Data.Length == 0) return Color.Transparent; + + int x = (int)MathF.Round((Size.Width - 1) * rectangle.Location.X.Clamp(0, 1)); + int y = (int)MathF.Round((Size.Height - 1) * rectangle.Location.Y.Clamp(0, 1)); + int width = (int)MathF.Round(Size.Width * rectangle.Size.Width.Clamp(0, 1)); + int height = (int)MathF.Round(Size.Height * rectangle.Size.Height.Clamp(0, 1)); + + if ((width == 0) && (rectangle.Size.Width > 0)) width = 1; + if ((height == 0) && (rectangle.Size.Height > 0)) height = 1; + + return this[x, y, width, height]; + } + } + + /// + /// Gets the sampled color inside the specified region. + /// + /// The x-location of the region. + /// The y-location of the region. + /// The with of the region. + /// The height of the region. + /// The sampled color. + public virtual Color this[int x, int y, int width, int height] + { + get + { + if (Data.Length == 0) return Color.Transparent; + + if ((width == 0) || (height == 0)) return Color.Transparent; + if ((width == 1) && (height == 1)) return GetColor(GetPixelData(x, y)); + + int bufferSize = width * height * _dataPerPixel; + if (bufferSize <= STACK_ALLOC_LIMIT) + { + Span buffer = stackalloc T[bufferSize]; + GetRegionData(x, y, width, height, buffer); + + Span pixelData = stackalloc T[_dataPerPixel]; + Sampler.Sample(new SamplerInfo(width, height, buffer), pixelData); + + return GetColor(pixelData); + } + else + { + T[] rent = ArrayPool.Shared.Rent(bufferSize); + + Span buffer = new Span(rent)[..bufferSize]; + GetRegionData(x, y, width, height, buffer); + + Span pixelData = stackalloc T[_dataPerPixel]; + Sampler.Sample(new SamplerInfo(width, height, buffer), pixelData); + + ArrayPool.Shared.Return(rent); + + return GetColor(pixelData); + } + } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The width of the texture. + /// The height of the texture. + /// The amount of data-entries per pixel. + /// The sampler used to get the color of a region. + /// The stride of the data or -1 if the width should be used. + public PixelTexture(int with, int height, int dataPerPixel, ISampler sampler, int stride = -1) + { + this._stride = stride == -1 ? with : stride; + this._dataPerPixel = dataPerPixel; + this.Sampler = sampler; + + Size = new Size(with, height); + } + + #endregion + + #region Methods + + /// + /// Converts the pixel-data to a color. + /// + /// The pixel-data to convert. + /// The color represented by the specified pixel-data. + protected abstract Color GetColor(in ReadOnlySpan pixel); + + /// + /// Gets the pixel-data at the specified location. + /// + /// The x-location. + /// The y-location. + /// The pixel-data on the specified location. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + protected virtual ReadOnlySpan GetPixelData(int x, int y) => Data.Slice((y * _stride) + x, _dataPerPixel); + + /// + /// Writes the pixel-data of the specified region to the passed buffer. + /// + /// The x-location of the region to get the data for. + /// The y-location of the region to get the data for. + /// The width of the region to get the data for. + /// The height of the region to get the data for. + /// The buffer to write the data to. + protected virtual void GetRegionData(int x, int y, int width, int height, in Span buffer) + { + int dataWidth = width * _dataPerPixel; + ReadOnlySpan data = Data; + for (int i = 0; i < height; i++) + { + ReadOnlySpan dataSlice = data.Slice((((y + i) * _stride) + x) * _dataPerPixel, dataWidth); + Span destination = buffer.Slice(i * dataWidth, dataWidth); + dataSlice.CopyTo(destination); + } + } + + #endregion +} + +/// +/// +/// Represents a texture made of color-pixels. +/// +public sealed class PixelTexture : PixelTexture +{ + #region Properties & Fields + + private readonly Color[] _data; + + /// + protected override ReadOnlySpan Data => _data; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// A is used. + /// + /// The width of the texture. + /// The height of the texture. + /// The pixel-data of the texture. + public PixelTexture(int with, int height, Color[] data) + : this(with, height, data, new AverageColorSampler()) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The width of the texture. + /// The height of the texture. + /// The pixel-data of the texture. + /// The sampler used to get the color of a region. + public PixelTexture(int with, int height, Color[] data, ISampler sampler) + : base(with, height, 1, sampler) + { + this._data = data; + + if (Data.Length != (with * height)) throw new ArgumentException($"Data-Length {Data.Length} differs from the specified size {with}x{height} ({with * height})."); + } + + #endregion + + #region Methods + + /// + protected override Color GetColor(in ReadOnlySpan pixel) => pixel[0]; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/Textures/Sampler/AverageColorSampler.cs b/RGB.NET.Core/Rendering/Textures/Sampler/AverageColorSampler.cs new file mode 100644 index 00000000..f93d2120 --- /dev/null +++ b/RGB.NET.Core/Rendering/Textures/Sampler/AverageColorSampler.cs @@ -0,0 +1,83 @@ +using System; +using System.Numerics; +using System.Runtime.InteropServices; + +namespace RGB.NET.Core; + +/// +/// Represents a sampled that averages multiple color to a single color. +/// +/// +/// Averages all components (A, R, G, B) of the colors separately which isn't ideal in cases where multiple different colors are combined. +/// +public class AverageColorSampler : ISampler +{ + #region Constants + + private const int VALUES_PER_COLOR = 4; + private static readonly int ELEMENTS_PER_VECTOR = Vector.Count / VALUES_PER_COLOR; + private static readonly int VALUES_PER_VECTOR = ELEMENTS_PER_VECTOR * VALUES_PER_COLOR; + + #endregion + + #region Methods + + /// + public unsafe void Sample(in SamplerInfo info, in Span pixelData) + { + int count = info.Width * info.Height; + if (count == 0) return; + + float a = 0, r = 0, g = 0, b = 0; + + if (Vector.IsHardwareAccelerated && (info.Data.Length >= Vector.Count)) + { + int chunks = info.Data.Length / ELEMENTS_PER_VECTOR; + int missingElements = info.Data.Length - (chunks * ELEMENTS_PER_VECTOR); + + Vector sum = Vector.Zero; + + fixed (Color* colorPtr = &MemoryMarshal.GetReference(info.Data)) + { + Color* current = colorPtr; + for (int i = 0; i < chunks; i++) + { + sum = Vector.Add(sum, *(Vector*)current); + current += ELEMENTS_PER_VECTOR; + } + } + + for (int i = 0; i < VALUES_PER_VECTOR; i += VALUES_PER_COLOR) + { + a += sum[i]; + r += sum[i + 1]; + g += sum[i + 2]; + b += sum[i + 3]; + } + + for (int i = 0; i < missingElements; i++) + { + Color color = info.Data[^(i + 1)]; + + a += color.A; + r += color.R; + g += color.G; + b += color.B; + } + } + else + { + foreach (Color color in info.Data) + { + a += color.A; + r += color.R; + g += color.G; + b += color.B; + } + } + + pixelData[0] = new Color(a / count, r / count, g / count, b / count); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/Textures/Sampler/ISampler.cs b/RGB.NET.Core/Rendering/Textures/Sampler/ISampler.cs new file mode 100644 index 00000000..9a2c4f10 --- /dev/null +++ b/RGB.NET.Core/Rendering/Textures/Sampler/ISampler.cs @@ -0,0 +1,17 @@ +using System; + +namespace RGB.NET.Core; + +/// +/// Represents a generic sampler to combine multipel data entries to a single one. +/// +/// The type of the data to sample. +public interface ISampler +{ + /// + /// Samples the specified data to a single pixel-buffer. + /// + /// The information containing the data to sample. + /// The buffer used to write the resulting pixel to. + void Sample(in SamplerInfo info, in Span pixelData); +} \ No newline at end of file diff --git a/RGB.NET.Core/Rendering/Textures/Sampler/SamplerInfo.cs b/RGB.NET.Core/Rendering/Textures/Sampler/SamplerInfo.cs new file mode 100644 index 00000000..ab7a0a19 --- /dev/null +++ b/RGB.NET.Core/Rendering/Textures/Sampler/SamplerInfo.cs @@ -0,0 +1,46 @@ +using System; + +namespace RGB.NET.Core; + +/// +/// Represents the information used to sample data. +/// +/// The type of the data to sample. +public readonly ref struct SamplerInfo +{ + #region Properties & Fields + + /// + /// Gets the width of the region the data comes from. + /// + public int Width { get; } + + /// + /// Gets the height of region the data comes from. + /// + public int Height { get; } + + /// + /// Gets the data to sample. + /// + public ReadOnlySpan Data { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The width of the region the data comes from. + /// The height of region the data comes from. + /// The data to sample. + public SamplerInfo(int width, int height, ReadOnlySpan data) + { + this.Width = width; + this.Height = height; + this.Data = data; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs index e311037a..974e0b08 100644 --- a/RGB.NET.Core/Update/AbstractUpdateTrigger.cs +++ b/RGB.NET.Core/Update/AbstractUpdateTrigger.cs @@ -1,38 +1,47 @@ using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a generic update trigger. +/// +public abstract class AbstractUpdateTrigger : AbstractBindable, IUpdateTrigger { - /// - /// Represents a generic update trigger. - /// - public abstract class AbstractUpdateTrigger : AbstractBindable, IUpdateTrigger - { - #region Events + #region Properties & Fields + + /// + public abstract double LastUpdateTime { get; protected set; } + + #endregion + + #region Events - /// - public event EventHandler Starting; - /// - public event EventHandler Update; + /// + public event EventHandler? Starting; + /// + public event EventHandler? Update; - #endregion + #endregion - #region Methods + #region Methods - /// - /// Invokes the -event. - /// - /// Optional custom-data passed to the subscribers of the .event. - protected virtual void OnStartup(CustomUpdateData updateData = null) => Starting?.Invoke(this, updateData); + /// + /// Invokes the -event. + /// + /// Optional custom-data passed to the subscribers of the .event. + protected virtual void OnStartup(CustomUpdateData? updateData = null) => Starting?.Invoke(this, updateData ?? new CustomUpdateData()); + + /// + /// Invokes the -event. + /// + /// Optional custom-data passed to the subscribers of the .event. + protected virtual void OnUpdate(CustomUpdateData? updateData = null) => Update?.Invoke(this, updateData ?? new CustomUpdateData()); - /// - /// Invokes the -event. - /// - /// Optional custom-data passed to the subscribers of the .event. - protected virtual void OnUpdate(CustomUpdateData updateData = null) => Update?.Invoke(this, updateData); + /// + public abstract void Start(); - /// - public abstract void Dispose(); + /// + public abstract void Dispose(); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Update/CustomUpdateData.cs b/RGB.NET.Core/Update/CustomUpdateData.cs index 0ecfc7f9..88f734aa 100644 --- a/RGB.NET.Core/Update/CustomUpdateData.cs +++ b/RGB.NET.Core/Update/CustomUpdateData.cs @@ -1,51 +1,79 @@ using System.Collections.Generic; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents an index used to identify data in the . +/// +public static class CustomUpdateDataIndex +{ + /// + /// Checked by the to see if all LEDs needs to be flushed even if they aren't changed in this update. + /// default: false + /// + public const string FLUSH_LEDS = "flushLeds"; + + /// + /// Checked by the to see if the surface should be rendered in this update. + /// default: true + /// + public const string RENDER = "render"; + + /// + /// Checked by the to see if devies should be updated after rendering. + /// default: true + /// + public const string UPDATE_DEVICES = "updateDevices"; + + /// + /// Used by to indicate heatbeat updates. + /// + public const string HEARTBEAT = "heartbeat"; +} + +/// +/// Represents a set of custom data, each indexed by a string-key. +/// +public class CustomUpdateData { + #region Properties & Fields + + private Dictionary _data = new(); + + #endregion + + #region Indexer + /// - /// Represents a set of custom data, each indexed by a string-key. + /// Gets or sets the value for a specific key. /// - public class CustomUpdateData + /// The key of the value. + /// The value represented by the specified key. + public object? this[string key] { - #region Properties & Fields - - private Dictionary _data = new Dictionary(); - - #endregion - - #region Indexer - - /// - /// Gets or sets the value for a specific key. - /// - /// The key of the value. - /// The value represented by the given key. - public object this[string key] - { - get => _data.TryGetValue(key?.ToUpperInvariant() ?? string.Empty, out object data) ? data : default; - set => _data[key?.ToUpperInvariant() ?? string.Empty] = value; - } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - public CustomUpdateData() - { } - - /// - /// Initializes a new instance of the class. - /// - /// A params-list of tuples containing the key (string) and the value of a specific custom-data. - public CustomUpdateData(params (string key, object value)[] values) - { - foreach ((string key, object value) in values) - this[key] = value; - } - - #endregion + get => _data.TryGetValue(key.ToUpperInvariant(), out object? data) ? data : default; + set => _data[key.ToUpperInvariant()] = value; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public CustomUpdateData() + { } + + /// + /// Initializes a new instance of the class. + /// + /// A params-list of tuples containing the key (string) and the value of a specific custom-data. + public CustomUpdateData(params (string key, object value)[] values) + { + foreach ((string key, object value) in values) + this[key] = value; + } + + #endregion } diff --git a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs index 8f4bebae..5d357b6a 100644 --- a/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs +++ b/RGB.NET.Core/Update/Devices/DeviceUpdateTrigger.cs @@ -4,149 +4,181 @@ using System.Threading; using System.Threading.Tasks; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents an update-trigger used to update devices with a maximum update-rate. +/// +public class DeviceUpdateTrigger : AbstractUpdateTrigger, IDeviceUpdateTrigger { + #region Properties & Fields + + /// + /// Gets or sets the timeout used by the blocking wait for data availability. + /// + public int Timeout { get; set; } = 100; + /// - /// Represents an update-trigger used to update devices with a maximum update-rate. + /// Gets the update frequency used by the trigger if not limited by data shortage. /// - public class DeviceUpdateTrigger : AbstractUpdateTrigger, IDeviceUpdateTrigger + public double UpdateFrequency { get; private set; } + + private double _maxUpdateRate; + /// + /// Gets or sets the maximum update rate of this trigger (is overwriten if the is smaller). + /// <= 0 removes the limit. + /// + public double MaxUpdateRate { - #region Properties & Fields - - /// - /// Gets or sets the timeout used by the blocking wait for data availability. - /// - public int Timeout { get; set; } = 100; - - /// - /// Gets the update frequency used by the trigger if not limited by data shortage. - /// - public double UpdateFrequency { get; private set; } - - private double _maxUpdateRate; - /// - /// Gets or sets the maximum update rate of this trigger (is overwriten if the is smaller). - /// <= 0 removes the limit. - /// - public double MaxUpdateRate + get => _maxUpdateRate; + set { - get => _maxUpdateRate; - set - { - _maxUpdateRate = value; - UpdateUpdateFrequency(); - } + _maxUpdateRate = value; + UpdateUpdateFrequency(); } + } - private double _updateRateHardLimit; - /// - /// Gets the hard limit of the update rate of this trigger. Updates will never perform faster then then this value if it's set. - /// <= 0 removes the limit. - /// - public double UpdateRateHardLimit + private double _updateRateHardLimit; + /// + /// Gets the hard limit of the update rate of this trigger. Updates will never perform faster then then this value if it's set. + /// <= 0 removes the limit. + /// + public double UpdateRateHardLimit + { + get => _updateRateHardLimit; + protected set { - get => _updateRateHardLimit; - protected set - { - _updateRateHardLimit = value; - UpdateUpdateFrequency(); - } + _updateRateHardLimit = value; + UpdateUpdateFrequency(); } + } - protected AutoResetEvent HasDataEvent = new AutoResetEvent(false); + /// + /// Gets or sets the time in ms after which a refresh-request is sent even if no changes are made in the meantime to prevent the target from timing out or similar problems. + /// To disable heartbeats leave it at 0. + /// + public int HeartbeatTimer { get; set; } - protected bool IsRunning; - protected Task UpdateTask; - protected CancellationTokenSource UpdateTokenSource; - protected CancellationToken UpdateToken; + /// + public override double LastUpdateTime { get; protected set; } - #endregion + /// + /// Gets or sets the timestamp of the last update. + /// + protected long LastUpdateTimestamp { get; set; } - #region Constructors + /// + /// Gets or sets the event to trigger when new data is available (). + /// + protected AutoResetEvent HasDataEvent { get; set; } = new(false); - /// - /// Initializes a new instance of the class. - /// - public DeviceUpdateTrigger() - { } + /// + /// Gets or sets a bool indicating if the trigger is currently updating. + /// + protected bool IsRunning { get; set; } - /// - /// Initializes a new instance of the class. - /// - /// The hard limit of the update rate of this trigger. - public DeviceUpdateTrigger(double updateRateHardLimit) - { - this.UpdateRateHardLimit = updateRateHardLimit; - } + /// + /// Gets or sets the update loop of this trigger. + /// + protected Task? UpdateTask { get; set; } - #endregion + /// + /// Gets or sets the cancellation token source used to create the cancellation token checked by the . + /// + protected CancellationTokenSource? UpdateTokenSource { get; set; } - #region Methods + /// + /// Gets or sets the cancellation token checked by the . + /// + protected CancellationToken UpdateToken { get; set; } - /// - /// Starts the trigger. - /// - public void Start() - { - if (IsRunning) return; + #endregion - IsRunning = true; + #region Constructors - UpdateTokenSource?.Dispose(); - UpdateTokenSource = new CancellationTokenSource(); - UpdateTask = Task.Factory.StartNew(UpdateLoop, (UpdateToken = UpdateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); - } + /// + /// Initializes a new instance of the class. + /// + public DeviceUpdateTrigger() + { } - /// - /// Stops the trigger. - /// - public async void Stop() - { - if (!IsRunning) return; + /// + /// Initializes a new instance of the class. + /// + /// The hard limit of the update rate of this trigger. + public DeviceUpdateTrigger(double updateRateHardLimit) + { + this.UpdateRateHardLimit = updateRateHardLimit; + } + + #endregion + + #region Methods + + /// + /// Starts the trigger. + /// + public override void Start() + { + if (IsRunning) return; - IsRunning = false; + IsRunning = true; - UpdateTokenSource.Cancel(); + UpdateTokenSource?.Dispose(); + UpdateTokenSource = new CancellationTokenSource(); + UpdateTask = Task.Factory.StartNew(UpdateLoop, (UpdateToken = UpdateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); + } + + /// + /// Stops the trigger. + /// + public async void Stop() + { + if (!IsRunning) return; + + IsRunning = false; + + UpdateTokenSource?.Cancel(); + if (UpdateTask != null) await UpdateTask; - UpdateTask.Dispose(); - UpdateTask = null; - } - protected virtual void UpdateLoop() - { - OnStartup(); + UpdateTask?.Dispose(); + UpdateTask = null; + } + + /// + /// The update loop called by the . + /// + protected virtual void UpdateLoop() + { + OnStartup(); + + using (TimerHelper.RequestHighResolutionTimer()) while (!UpdateToken.IsCancellationRequested) - { if (HasDataEvent.WaitOne(Timeout)) - { - long preUpdateTicks = Stopwatch.GetTimestamp(); - - OnUpdate(); - - if (UpdateFrequency > 0) - { - double lastUpdateTime = ((Stopwatch.GetTimestamp() - preUpdateTicks) / 10000.0); - int sleep = (int)((UpdateFrequency * 1000.0) - lastUpdateTime); - if (sleep > 0) - Thread.Sleep(sleep); - } - } - } - } - - /// - public void TriggerHasData() => HasDataEvent.Set(); + LastUpdateTime = TimerHelper.Execute(() => OnUpdate(), UpdateFrequency * 1000); + else if ((HeartbeatTimer > 0) && (LastUpdateTimestamp > 0) && (TimerHelper.GetElapsedTime(LastUpdateTimestamp) > HeartbeatTimer)) + OnUpdate(new CustomUpdateData().Heartbeat()); + } - private void UpdateUpdateFrequency() - { - UpdateFrequency = MaxUpdateRate; - if ((UpdateFrequency <= 0) || ((UpdateRateHardLimit > 0) && (UpdateRateHardLimit < UpdateFrequency))) - UpdateFrequency = UpdateRateHardLimit; - } + protected override void OnUpdate(CustomUpdateData? updateData = null) + { + base.OnUpdate(updateData); + LastUpdateTimestamp = Stopwatch.GetTimestamp(); + } - /// - public override void Dispose() => Stop(); + /// + public void TriggerHasData() => HasDataEvent.Set(); - #endregion + private void UpdateUpdateFrequency() + { + UpdateFrequency = MaxUpdateRate; + if ((UpdateFrequency <= 0) || ((UpdateRateHardLimit > 0) && (UpdateRateHardLimit < UpdateFrequency))) + UpdateFrequency = UpdateRateHardLimit; } -} + + /// + public override void Dispose() => Stop(); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Update/Devices/IDeviceUpdateTrigger.cs b/RGB.NET.Core/Update/Devices/IDeviceUpdateTrigger.cs index 81303c1d..8fcd758c 100644 --- a/RGB.NET.Core/Update/Devices/IDeviceUpdateTrigger.cs +++ b/RGB.NET.Core/Update/Devices/IDeviceUpdateTrigger.cs @@ -1,13 +1,12 @@ -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents an update trigger used to trigger device-updates. +/// +public interface IDeviceUpdateTrigger : IUpdateTrigger { /// - /// Represents an update trigger used to trigger device-updates. + /// Indicates that there's data available to process. /// - public interface IDeviceUpdateTrigger : IUpdateTrigger - { - /// - /// Indicates that there's data available to process. - /// - void TriggerHasData(); - } -} + void TriggerHasData(); +} \ No newline at end of file diff --git a/RGB.NET.Core/Update/Devices/IUpdateQueue.cs b/RGB.NET.Core/Update/Devices/IUpdateQueue.cs new file mode 100644 index 00000000..3a0f63a5 --- /dev/null +++ b/RGB.NET.Core/Update/Devices/IUpdateQueue.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; + +namespace RGB.NET.Core; + +/// +/// Represents a generic update queue. +/// +/// The identifier used to identify the data processed by this queue. +/// The type of the data processed by this queue. +public interface IUpdateQueue : IDisposable + where TIdentifier : notnull +{ + /// + /// Sets or merges the provided data set in the current dataset and notifies the trigger that there is new data available. + /// + /// The set of data. + // ReSharper disable once MemberCanBeProtected.Global + void SetData(IEnumerable<(TIdentifier, TData)> dataSet); + + /// + /// Resets the current data set. + /// + void Reset(); +} + +/// +/// Represents a generic update queue processing -data using -identifiers. +/// +public interface IUpdateQueue : IUpdateQueue +{ } \ No newline at end of file diff --git a/RGB.NET.Core/Update/Devices/UpdateQueue.cs b/RGB.NET.Core/Update/Devices/UpdateQueue.cs index da5c82cb..4c169b7b 100644 --- a/RGB.NET.Core/Update/Devices/UpdateQueue.cs +++ b/RGB.NET.Core/Update/Devices/UpdateQueue.cs @@ -1,139 +1,138 @@ using System; +using System.Buffers; using System.Collections.Generic; using System.Linq; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a generic update queue. +/// +/// The type of the key used to identify some data. +/// The type of the data. +public abstract class UpdateQueue : IUpdateQueue + where TIdentifier : notnull { + #region Properties & Fields + + private readonly object _dataLock = new(); + private readonly IDeviceUpdateTrigger _updateTrigger; + private readonly Dictionary _currentDataSet = new(); + + #endregion + + #region Constructors + /// - /// Represents a generic update queue. + /// Initializes a new instance of the class. /// - /// The type of the key used to identify some data. - /// The type of the data. - public abstract class UpdateQueue : IDisposable + /// The causing this queue to update. + protected UpdateQueue(IDeviceUpdateTrigger updateTrigger) { - #region Properties & Fields + this._updateTrigger = updateTrigger; - private readonly object _dataLock = new object(); - private readonly IDeviceUpdateTrigger _updateTrigger; - private Dictionary _currentDataSet; + _updateTrigger.Starting += OnStartup; + _updateTrigger.Update += OnUpdate; + } - #endregion + #endregion - #region Constructors + #region Methods - /// - /// Initializes a new instance of the class. - /// - /// The causing this queue to update. - protected UpdateQueue(IDeviceUpdateTrigger updateTrigger) + /// + /// Event handler for the -event. + /// + /// The causing this update. + /// provided by the trigger. + protected virtual void OnUpdate(object? sender, CustomUpdateData customData) + { + (TIdentifier, TData)[] dataSet; + Span<(TIdentifier, TData)> data; + lock (_dataLock) { - this._updateTrigger = updateTrigger; + if (_currentDataSet.Count == 0) return; - _updateTrigger.Starting += OnStartup; - _updateTrigger.Update += OnUpdate; + dataSet = ArrayPool<(TIdentifier, TData)>.Shared.Rent(_currentDataSet.Count); + data = new Span<(TIdentifier, TData)>(dataSet)[.._currentDataSet.Count]; + + int i = 0; + foreach ((TIdentifier key, TData value) in _currentDataSet) + data[i++] = (key, value); + + _currentDataSet.Clear(); } - #endregion + Update(data); - #region Methods + ArrayPool<(TIdentifier, TData)>.Shared.Return(dataSet); + } - /// - /// Event handler for the -event. - /// - /// The causing this update. - /// provided by the trigger. - protected virtual void OnUpdate(object sender, CustomUpdateData customData) - { - Dictionary dataSet; - lock (_dataLock) - { - dataSet = _currentDataSet; - _currentDataSet = null; - } - - if ((dataSet != null) && (dataSet.Count != 0)) - Update(dataSet); - } + /// + /// Event handler for the -event. + /// + /// The starting . + /// provided by the trigger. + protected virtual void OnStartup(object? sender, CustomUpdateData customData) { } - /// - /// Event handler for the -event. - /// - /// The starting . - /// provided by the trigger. - protected virtual void OnStartup(object sender, CustomUpdateData customData) { } - - /// - /// Performs the update this queue is responsible for. - /// - /// The set of data that needs to be updated. - protected abstract void Update(Dictionary dataSet); - - /// - /// Sets or merges the provided data set in the current dataset and notifies the trigger that there is new data available. - /// - /// The set of data. - // ReSharper disable once MemberCanBeProtected.Global - public virtual void SetData(Dictionary dataSet) - { - if ((dataSet == null) || (dataSet.Count == 0)) return; - - lock (_dataLock) - { - if (_currentDataSet == null) - _currentDataSet = dataSet; - else - { - foreach (KeyValuePair command in dataSet) - _currentDataSet[command.Key] = command.Value; - } - } - - _updateTrigger.TriggerHasData(); - } + /// + /// Performs the update this queue is responsible for. + /// + /// The set of data that needs to be updated. + protected abstract void Update(in ReadOnlySpan<(TIdentifier key, TData color)> dataSet); - /// - /// Resets the current data set. - /// - public virtual void Reset() - { - lock (_dataLock) - _currentDataSet = null; - } + /// + /// Sets or merges the provided data set in the current dataset and notifies the trigger that there is new data available. + /// + /// The set of data. + // ReSharper disable once MemberCanBeProtected.Global + public virtual void SetData(IEnumerable<(TIdentifier, TData)> dataSet) + { + IList<(TIdentifier, TData)> data = dataSet.ToList(); + if (data.Count == 0) return; - /// - public virtual void Dispose() + lock (_dataLock) { - _updateTrigger.Starting -= OnStartup; - _updateTrigger.Update -= OnUpdate; - - Reset(); + foreach ((TIdentifier key, TData value) in data) + _currentDataSet[key] = value; } - #endregion + _updateTrigger.TriggerHasData(); } /// - /// Represents a generic using an object as the key and a color as the value. + /// Resets the current data set. /// - public abstract class UpdateQueue : UpdateQueue + public virtual void Reset() { - #region Constructors - - /// - protected UpdateQueue(IDeviceUpdateTrigger updateTrigger) - : base(updateTrigger) - { } - - #endregion + lock (_dataLock) + _currentDataSet.Clear(); + } - #region Methods + /// + public virtual void Dispose() + { + _updateTrigger.Starting -= OnStartup; + _updateTrigger.Update -= OnUpdate; - /// - /// Calls for a data set created out of the provided list of . - /// - /// - public void SetData(IEnumerable leds) => SetData(leds?.ToDictionary(x => x.CustomData ?? x.Id, x => x.Color)); + Reset(); - #endregion + GC.SuppressFinalize(this); } + + #endregion } + +/// +/// Represents a generic using an object as the key and a color as the value. +/// +public abstract class UpdateQueue : UpdateQueue, IUpdateQueue +{ + #region Constructors + + /// + protected UpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Update/IUpdateTrigger.cs b/RGB.NET.Core/Update/IUpdateTrigger.cs index eed8f3db..aae3e830 100644 --- a/RGB.NET.Core/Update/IUpdateTrigger.cs +++ b/RGB.NET.Core/Update/IUpdateTrigger.cs @@ -1,20 +1,29 @@ using System; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// Represents a trigger causing an update. +/// +public interface IUpdateTrigger : IDisposable { /// - /// Represents a trigger causing an update. + /// Gets the time spent for the last update. /// - public interface IUpdateTrigger : IDisposable - { - /// - /// Occurs when the trigger is starting up. - /// - event EventHandler Starting; + double LastUpdateTime { get; } - /// - /// Occurs when the trigger wants to cause an update. - /// - event EventHandler Update; - } -} + /// + /// Occurs when the trigger is starting up. + /// + event EventHandler? Starting; + + /// + /// Occurs when the trigger wants to cause an update. + /// + event EventHandler? Update; + + /// + /// Starts the update trigger. + /// + void Start(); +} \ No newline at end of file diff --git a/RGB.NET.Core/Update/ManualUpdateTrigger.cs b/RGB.NET.Core/Update/ManualUpdateTrigger.cs new file mode 100644 index 00000000..67e8ca4c --- /dev/null +++ b/RGB.NET.Core/Update/ManualUpdateTrigger.cs @@ -0,0 +1,96 @@ +// ReSharper disable MemberCanBePrivate.Global + +using System.Threading; +using System.Threading.Tasks; + +namespace RGB.NET.Core; + +/// +/// +/// Represents an update trigger that is manully triggered by calling . +/// +public sealed class ManualUpdateTrigger : AbstractUpdateTrigger +{ + #region Properties & Fields + + private readonly AutoResetEvent _mutex = new(false); + private Task? UpdateTask { get; set; } + private CancellationTokenSource? UpdateTokenSource { get; set; } + private CancellationToken UpdateToken { get; set; } + + private CustomUpdateData? _customUpdateData; + + /// + /// Gets the time it took the last update-loop cycle to run. + /// + public override double LastUpdateTime { get; protected set; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + public ManualUpdateTrigger() + { + Start(); + } + + #endregion + + #region Methods + + /// + /// Starts the trigger if needed, causing it to performing updates. + /// + public override void Start() + { + if (UpdateTask == null) + { + UpdateTokenSource?.Dispose(); + UpdateTokenSource = new CancellationTokenSource(); + UpdateTask = Task.Factory.StartNew(UpdateLoop, (UpdateToken = UpdateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); + } + } + + /// + /// Stops the trigger if running, causing it to stop performing updates. + /// + private void Stop() + { + if (UpdateTask != null) + { + UpdateTokenSource?.Cancel(); + // ReSharper disable once MethodSupportsCancellation + UpdateTask.Wait(); + UpdateTask.Dispose(); + UpdateTask = null; + } + } + + /// + /// Triggers an update. + /// + public void TriggerUpdate(CustomUpdateData? updateData = null) + { + _customUpdateData = updateData; + _mutex.Set(); + } + + private void UpdateLoop() + { + OnStartup(); + + while (!UpdateToken.IsCancellationRequested) + { + if (_mutex.WaitOne(100)) + LastUpdateTime = TimerHelper.Execute(() => OnUpdate(_customUpdateData)); + } + } + + /// + public override void Dispose() => Stop(); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Core/Update/TimerUpdateTrigger.cs b/RGB.NET.Core/Update/TimerUpdateTrigger.cs index 0171ffbe..14a7e9ff 100644 --- a/RGB.NET.Core/Update/TimerUpdateTrigger.cs +++ b/RGB.NET.Core/Update/TimerUpdateTrigger.cs @@ -1,114 +1,146 @@ // ReSharper disable MemberCanBePrivate.Global -using System.Diagnostics; +using System; using System.Threading; using System.Threading.Tasks; -namespace RGB.NET.Core +namespace RGB.NET.Core; + +/// +/// +/// Represents an update trigger that triggers in a set interval. +/// +public class TimerUpdateTrigger : AbstractUpdateTrigger { - /// + #region Properties & Fields + + private readonly object _lock = new(); + + private readonly CustomUpdateData? _customUpdateData; + /// - /// Represents an + /// Gets or sets the update loop of this trigger. /// - public class TimerUpdateTrigger : AbstractUpdateTrigger - { - #region Properties & Fields + protected Task? UpdateTask { get; set; } - private object _lock = new object(); + /// + /// Gets or sets the cancellation token source used to create the cancellation token checked by the . + /// + protected CancellationTokenSource? UpdateTokenSource { get; set; } - private CancellationTokenSource _updateTokenSource; - private CancellationToken _updateToken; - private Task _updateTask; - private Stopwatch _sleepCounter; + /// + /// Gets or sets the cancellation token checked by the . + /// + protected CancellationToken UpdateToken { get; set; } - private double _updateFrequency = 1.0 / 30.0; - /// - /// Gets or sets the update-frequency in seconds. (Calculate by using '1.0 / updates per second') - /// - public double UpdateFrequency - { - get => _updateFrequency; - set => SetProperty(ref _updateFrequency, value); - } + private double _updateFrequency = 1.0 / 30.0; + /// + /// Gets or sets the update-frequency in seconds. (Calculate by using '1.0 / updates per second') + /// + public double UpdateFrequency + { + get => _updateFrequency; + set => SetProperty(ref _updateFrequency, value); + } - /// - /// Gets the time it took the last update-loop cycle to run. - /// - public double LastUpdateTime { get; private set; } + /// + /// Gets the time it took the last update-loop cycle to run. + /// + public override double LastUpdateTime { get; protected set; } - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// A value indicating if the trigger should automatically right after construction. - public TimerUpdateTrigger(bool autostart = true) - { - _sleepCounter = new Stopwatch(); + /// + /// Initializes a new instance of the class. + /// + /// A value indicating if the trigger should automatically right after construction. + public TimerUpdateTrigger(bool autostart = true) + { + if (autostart) + // ReSharper disable once VirtualMemberCallInConstructor - HACK DarthAffe 01.06.2021: I've no idea how to correctly handle that case, for now just disable it + Start(); + } - if (autostart) - Start(); - } + /// + /// Initializes a new instance of the class. + /// + /// The update-data passed on each update triggered. + /// A value indicating if the trigger should automatically right after construction. + public TimerUpdateTrigger(CustomUpdateData? customUpdateData, bool autostart = true) + { + this._customUpdateData = customUpdateData; - #endregion + if (autostart) + // ReSharper disable once VirtualMemberCallInConstructor - HACK DarthAffe 01.06.2021: I've no idea how to correctly handle that case, for now just disable it + Start(); + } + + #endregion - #region Methods + #region Methods - /// - /// Starts the trigger if needed, causing it to performing updates. - /// - public void Start() + /// + /// Starts the trigger if needed, causing it to performing updates. + /// + public override void Start() + { + lock (_lock) { - lock (_lock) + if (UpdateTask == null) { - if (_updateTask == null) - { - _updateTokenSource?.Dispose(); - _updateTokenSource = new CancellationTokenSource(); - _updateTask = Task.Factory.StartNew(UpdateLoop, (_updateToken = _updateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); - } + UpdateTokenSource?.Dispose(); + UpdateTokenSource = new CancellationTokenSource(); + UpdateTask = Task.Factory.StartNew(UpdateLoop, (UpdateToken = UpdateTokenSource.Token), TaskCreationOptions.LongRunning, TaskScheduler.Default); } } + } - /// - /// Stops the trigger if running, causing it to stop performing updates. - /// - public void Stop() + /// + /// Stops the trigger if running, causing it to stop performing updates. + /// + public void Stop() + { + lock (_lock) { - lock (_lock) + if (UpdateTask != null) { - if (_updateTask != null) + UpdateTokenSource?.Cancel(); + try { - _updateTokenSource.Cancel(); // ReSharper disable once MethodSupportsCancellation - _updateTask.Wait(); - _updateTask.Dispose(); - _updateTask = null; + UpdateTask.Wait(); + } + catch (AggregateException) + { + // ignored + } + finally + { + UpdateTask.Dispose(); + UpdateTask = null; } } } + } - private void UpdateLoop() - { - while (!_updateToken.IsCancellationRequested) - { - _sleepCounter.Restart(); + private void UpdateLoop() + { + OnStartup(); - OnUpdate(); + using (TimerHelper.RequestHighResolutionTimer()) + while (!UpdateToken.IsCancellationRequested) + LastUpdateTime = TimerHelper.Execute(() => OnUpdate(_customUpdateData), UpdateFrequency * 1000); - _sleepCounter.Stop(); - LastUpdateTime = _sleepCounter.Elapsed.TotalSeconds; - int sleep = (int)((UpdateFrequency * 1000.0) - _sleepCounter.ElapsedMilliseconds); - if (sleep > 0) - Thread.Sleep(sleep); - } - } - - /// - public override void Dispose() => Stop(); + } - #endregion + /// + public override void Dispose() + { + Stop(); + GC.SuppressFinalize(this); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Decorators/Brush/FlashDecorator.cs b/RGB.NET.Decorators/Brush/FlashDecorator.cs deleted file mode 100644 index 580fce43..00000000 --- a/RGB.NET.Decorators/Brush/FlashDecorator.cs +++ /dev/null @@ -1,164 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -// ReSharper disable UnusedMember.Global - -using System; -using RGB.NET.Core; - -namespace RGB.NET.Decorators.Brush -{ - /// - /// - /// - /// Represents a decorator which allows to flash a brush by modifying his opacity. - /// - public class FlashDecorator : AbstractUpdateAwareDecorator, IBrushDecorator - { - #region Properties & Fields - - /// - /// Gets or sets the attack-time (in seconds) of the decorator. (default: 0.2)
- /// This is close to a synthesizer envelope. (See as reference) - ///
- public double Attack { get; set; } = 0.2; - - /// - /// Gets or sets the decay-time (in seconds) of the decorator. (default: 0)
- /// This is close to a synthesizer envelope. (See as reference) - ///
- public double Decay { get; set; } = 0; - - /// - /// Gets or sets the sustain-time (in seconds) of the decorator. (default: 0.3)
- /// This is close to a synthesizer envelope. (See as reference)
- /// Note that this value for naming reasons represents the time NOT the level. - ///
- public double Sustain { get; set; } = 0.3; - - /// - /// Gets or sets the release-time (in seconds) of the decorator. (default: 0.2)
- /// This is close to a synthesizer envelope. (See as reference) - ///
- public double Release { get; set; } = 0.2; - - /// - /// Gets or sets the level to which the oppacity (percentage) should raise in the attack-cycle. (default: 1); - /// - public double AttackValue { get; set; } = 1; - - /// - /// Gets or sets the level at which the oppacity (percentage) should stay in the sustain-cycle. (default: 1); - /// - public double SustainValue { get; set; } = 1; - - /// - /// Gets or sets the level at which the oppacity (percentage) should stay in the pause-cycle. (default: 0); - /// - public double PauseValue { get; set; } = 0; - - /// - /// Gets or sets the interval (in seconds) in which the decorator should repeat (if repetition is enabled). (default: 1) - /// - public double Interval { get; set; } = 1; - - /// - /// Gets or sets the amount of repetitions the decorator should do until it's finished. Zero means infinite. (default: 0) - /// - public int Repetitions { get; set; } = 0; - - private ADSRPhase _currentPhase; - private double _currentPhaseValue; - private int _repetitionCount; - - private double _currentValue; - - #endregion - - #region Methods - - /// - public Color ManipulateColor(Rectangle rectangle, BrushRenderTarget renderTarget, Color color) => color.SetA(_currentValue); - - /// - protected override void Update(double deltaTime) - { - _currentPhaseValue -= deltaTime; - - // Using ifs instead of a switch allows to skip phases with time 0. - // ReSharper disable InvertIf - - if (_currentPhase == ADSRPhase.Attack) - if (_currentPhaseValue > 0) - _currentValue = PauseValue + (Math.Min(1, (Attack - _currentPhaseValue) / Attack) * (AttackValue - PauseValue)); - else - { - _currentPhaseValue = Decay; - _currentPhase = ADSRPhase.Decay; - } - - if (_currentPhase == ADSRPhase.Decay) - if (_currentPhaseValue > 0) - _currentValue = SustainValue + (Math.Min(1, _currentPhaseValue / Decay) * (AttackValue - SustainValue)); - else - { - _currentPhaseValue = Sustain; - _currentPhase = ADSRPhase.Sustain; - } - - if (_currentPhase == ADSRPhase.Sustain) - if (_currentPhaseValue > 0) - _currentValue = SustainValue; - else - { - _currentPhaseValue = Release; - _currentPhase = ADSRPhase.Release; - } - - if (_currentPhase == ADSRPhase.Release) - if (_currentPhaseValue > 0) - _currentValue = PauseValue + (Math.Min(1, _currentPhaseValue / Release) * (SustainValue - PauseValue)); - else - { - _currentPhaseValue = Interval; - _currentPhase = ADSRPhase.Pause; - } - - if (_currentPhase == ADSRPhase.Pause) - if (_currentPhaseValue > 0) - _currentValue = PauseValue; - else - { - if ((++_repetitionCount >= Repetitions) && (Repetitions > 0)) - Detach(); - _currentPhaseValue = Attack; - _currentPhase = ADSRPhase.Attack; - } - - // ReSharper restore InvertIf - } - - /// - /// - public override void OnAttached(IDecoratable decoratable) - { - base.OnAttached(decoratable); - - _currentPhase = ADSRPhase.Attack; - _currentPhaseValue = Attack; - _repetitionCount = 0; - _currentValue = 0; - } - - #endregion - - // ReSharper disable once InconsistentNaming - private enum ADSRPhase - { - Attack, - Decay, - Sustain, - Release, - Pause - } - } -} diff --git a/RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs b/RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs deleted file mode 100644 index 9e7f86a0..00000000 --- a/RGB.NET.Decorators/Gradient/MoveGradientDecorator.cs +++ /dev/null @@ -1,73 +0,0 @@ -using RGB.NET.Brushes; -using RGB.NET.Brushes.Gradients; -using RGB.NET.Core; - -namespace RGB.NET.Decorators.Gradient -{ - /// - /// - /// - /// Represents a decorator which allows to move an by modifying his offset. - /// - public class MoveGradientDecorator : AbstractUpdateAwareDecorator, IGradientDecorator - { - #region Properties & Fields - // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global - // ReSharper disable MemberCanBePrivate.Global - - /// - /// Gets or sets the direction the is moved. - /// True leads to an offset-increment (normaly moving to the right), false to an offset-decrement (normaly moving to the left). - /// - public bool Direction { get; set; } - - /// - /// Gets or sets the speed of the movement in units per second. - /// The meaning of units differs for the different , but 360 units will always be one complete cycle: - /// : 360 unit = 1 offset. - /// : 1 unit = 1 degree. - /// - public double Speed { get; set; } - - // ReSharper restore MemberCanBePrivate.Global - // ReSharper restore AutoPropertyCanBeMadeGetOnly.Global - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The speed of the movement in units per second. - /// The meaning of units differs for the different but 360 units will always be one complete cycle: - /// : 360 unit = 1 offset. - /// : 1 unit = 1 degree. - /// The direction the is moved. - /// True leads to an offset-increment (normaly moving to the right), false to an offset-decrement (normaly moving to the left). - public MoveGradientDecorator(double speed = 180.0, bool direction = true) - { - this.Speed = speed; - this.Direction = direction; - } - - #endregion - - #region Methods - - /// - protected override void Update(double deltaTime) - { - double movement = Speed * deltaTime; - - if (!Direction) - movement = -movement; - - foreach (IDecoratable decoratedObject in DecoratedObjects) - if (decoratedObject is IGradient gradient) - gradient.Move(movement); - } - - #endregion - } -} diff --git a/RGB.NET.Decorators/RGB.NET.Decorators.csproj b/RGB.NET.Decorators/RGB.NET.Decorators.csproj deleted file mode 100644 index f76251d8..00000000 --- a/RGB.NET.Decorators/RGB.NET.Decorators.csproj +++ /dev/null @@ -1,69 +0,0 @@ - - - netstandard2.0;net45 - win7-x86;win7-x64 - - Darth Affe - Wyrez - en-US - en-US - RGB.NET.Decorators - RGB.NET.Decorators - RGB.NET.Decorators - RGB.NET.Decorators - RGB.NET.Decorators - Decorators-Presets of RGB.NET - Decorators-Presets of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png - https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE - Github - https://github.com/DarthAffe/RGB.NET - True - - - - 0.0.1 - 0.0.1 - 0.0.1 - - ..\bin\ - true - True - True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL - - - - $(DefineConstants);TRACE;DEBUG - true - full - false - - - - pdbonly - true - $(NoWarn);CS1591;CS1572;CS1573 - $(DefineConstants);RELEASE - - - - - - - - - - - \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs index 8547b14e..2e09b528 100644 --- a/RGB.NET.Devices.Asus/AsusDeviceProvider.cs +++ b/RGB.NET.Devices.Asus/AsusDeviceProvider.cs @@ -3,177 +3,92 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; using AuraServiceLib; using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// +/// Represents a device provider responsible for Cooler Master devices. +/// +public class AsusDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static AsusDeviceProvider? _instance; /// - /// Represents a device provider responsible for Cooler Master devices. + /// Gets the singleton instance. /// - public class AsusDeviceProvider : IRGBDeviceProvider - { - #region Properties & Fields - - private static AsusDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static AsusDeviceProvider Instance => _instance ?? new AsusDeviceProvider(); - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; - - /// - /// The used to trigger the updates for asus devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } - - private IAuraSdk2 _sdk; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public AsusDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(AsusDeviceProvider)}"); - _instance = this; + public static AsusDeviceProvider Instance => _instance ?? new AsusDeviceProvider(); - UpdateTrigger = new DeviceUpdateTrigger(); - } + private IAuraSdk2? _sdk; + private IAuraSyncDeviceCollection? _devices; //HACK DarthAffe 05.04.2021: Due to some researches this might fix the access violation in the asus-sdk - #endregion + #endregion - #region Methods + #region Constructors - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - IsInitialized = false; + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public AsusDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(AsusDeviceProvider)}"); + _instance = this; + } - try - { - UpdateTrigger?.Stop(); - - // ReSharper disable once SuspiciousTypeConversion.Global - _sdk = (IAuraSdk2)new AuraSdk(); - _sdk.SwitchMode(); - - IList devices = new List(); - foreach (IAuraSyncDevice device in _sdk.Enumerate(0)) - { - try - { - IAsusRGBDevice rgbDevice; - switch ((AsusDeviceType)device.Type) - { - case AsusDeviceType.MB_RGB: - rgbDevice = new AsusMainboardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mainboard, device, WMIHelper.GetMainboardInfo()?.model ?? device.Name)); - break; - - case AsusDeviceType.MB_ADDRESABLE: - rgbDevice = new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.LedStripe, device), LedId.LedStripe1); - break; - - case AsusDeviceType.VGA_RGB: - rgbDevice = new AsusGraphicsCardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.GraphicsCard, device)); - break; - - case AsusDeviceType.HEADSET_RGB: - rgbDevice = new AsusHeadsetRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Headset, device)); - break; - - case AsusDeviceType.DRAM_RGB: - rgbDevice = new AsusDramRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.DRAM, device)); - break; - - case AsusDeviceType.KEYBOARD_RGB: - case AsusDeviceType.NB_KB_RGB: - case AsusDeviceType.NB_KB_4ZONE_RGB: - rgbDevice = new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device, CultureInfo.CurrentCulture)); - break; - - case AsusDeviceType.MOUSE_RGB: - rgbDevice = new AsusMouseRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mouse, device)); - break; - - default: - rgbDevice = new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Unknown, device), LedId.Custom1); - break; - } - - if (loadFilter.HasFlag(rgbDevice.DeviceInfo.DeviceType)) - { - rgbDevice.Initialize(UpdateTrigger); - devices.Add(rgbDevice); - } - } - catch - { - if (throwExceptions) - throw; - } - } - - UpdateTrigger?.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) - throw; - return false; - } - return true; - } + #endregion + + #region Methods - /// - public void ResetDevices() + /// + protected override void InitializeSDK() + { + // ReSharper disable once SuspiciousTypeConversion.Global + _sdk = (IAuraSdk2)new AuraSdk(); + _sdk.SwitchMode(); + } + + /// + protected override IEnumerable LoadDevices() + { + if (_sdk == null) yield break; + + _devices = _sdk.Enumerate(0); + for (int i = 0; i < _devices.Count; i++) { - _sdk?.ReleaseControl(0); - _sdk?.SwitchMode(); + IAuraSyncDevice device = _devices[i]; + yield return (AsusDeviceType)device.Type switch + { + AsusDeviceType.MB_RGB => new AsusMainboardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mainboard, device, WMIHelper.GetMainboardInfo()?.model ?? device.Name), GetUpdateTrigger()), + AsusDeviceType.MB_ADDRESABLE => new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.LedStripe, device), LedId.LedStripe1, GetUpdateTrigger()), + AsusDeviceType.VGA_RGB => new AsusGraphicsCardRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.GraphicsCard, device), GetUpdateTrigger()), + AsusDeviceType.HEADSET_RGB => new AsusHeadsetRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Headset, device), GetUpdateTrigger()), + AsusDeviceType.DRAM_RGB => new AsusDramRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.DRAM, device), GetUpdateTrigger()), + AsusDeviceType.KEYBOARD_RGB => new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device), LedMappings.KeyboardMapping, GetUpdateTrigger()), + AsusDeviceType.NB_KB_RGB => new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device), LedMappings.KeyboardMapping, GetUpdateTrigger()), + AsusDeviceType.NB_KB_4ZONE_RGB => new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(device), null, GetUpdateTrigger()), + AsusDeviceType.MOUSE_RGB => new AsusMouseRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Mouse, device), GetUpdateTrigger()), + _ => new AsusUnspecifiedRGBDevice(new AsusRGBDeviceInfo(RGBDeviceType.Unknown, device), LedId.Custom1, GetUpdateTrigger()) + }; } + } - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } + /// + public override void Dispose() + { + base.Dispose(); - try { _sdk?.ReleaseControl(0); } - catch { /* at least we tried */ } + try { _sdk?.ReleaseControl(0); } + catch { /* at least we tried */ } - _sdk = null; - } + _devices = null; + _sdk = null; - #endregion + GC.SuppressFinalize(this); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/AsusDeviceProviderLoader.cs b/RGB.NET.Devices.Asus/AsusDeviceProviderLoader.cs deleted file mode 100644 index 576dfb51..00000000 --- a/RGB.NET.Devices.Asus/AsusDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// Represents a device provider loaded used to dynamically load asus devices into an application. - /// - public class AsusDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => AsusDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs b/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs index 7ee21835..2fe53503 100644 --- a/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Dram/AsusDramRGBDevice.cs @@ -1,44 +1,40 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// +/// Represents a Asus dram. +/// +public class AsusDramRGBDevice : AsusRGBDevice, IDRAM { - /// + #region Constructors + + /// /// - /// Represents a Asus dram. + /// Initializes a new instance of the class. /// - public class AsusDramRGBDevice : AsusRGBDevice, IDRAM + /// The specific information provided by Asus for the DRAM. + /// The update trigger used to update this device. + internal AsusDramRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the DRAM. - internal AsusDramRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - //TODO DarthAffe 07.10.2017: Look for a good default layout - int ledCount = DeviceInfo.Device.Lights.Count; - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.DRAM1 + i, new Rectangle(i * 10, 0, 10, 10)); - - //TODO DarthAffe 21.10.2017: We don't know the model, how to save layouts and images? - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Drams", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.DRAM1; - - #endregion + InitializeLayout(); } -} + + #endregion + + #region Methods + + private void InitializeLayout() + { + int ledCount = DeviceInfo.Device.Lights.Count; + for (int i = 0; i < ledCount; i++) + AddLed(LedId.DRAM1 + i, new Point(i * 10, 0), new Size(10, 10)); + } + + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.DRAM1; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Enum/AsusDeviceType.cs b/RGB.NET.Devices.Asus/Enum/AsusDeviceType.cs index 7990bce5..ad529ed2 100644 --- a/RGB.NET.Devices.Asus/Enum/AsusDeviceType.cs +++ b/RGB.NET.Devices.Asus/Enum/AsusDeviceType.cs @@ -1,25 +1,24 @@ // ReSharper disable InconsistentNaming -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +internal enum AsusDeviceType : uint { - internal enum AsusDeviceType : uint - { - ALL = 0, - MB_RGB = 0x10000, - MB_ADDRESABLE = 0x11000, - DESKTOP_RGB = 0x12000, - VGA_RGB = 0x20000, - DISPLAY_RGB = 0x30000, - HEADSET_RGB = 0x40000, - MICROPHONE_RGB = 0x50000, - EXTERNAL_HARD_DRIVER_RGB = 0x60000, - EXTERNAL_BLUE_RAY_RGB = 0x61000, - DRAM_RGB = 0x70000, - KEYBOARD_RGB = 0x80000, - NB_KB_RGB = 0x81000, - NB_KB_4ZONE_RGB = 0x81001, - MOUSE_RGB = 0x90000, - CHASSIS_RGB = 0xB0000, - PROJECTOR_RGB = 0xC0000 - } -} + ALL = 0, + MB_RGB = 0x10000, + MB_ADDRESABLE = 0x11000, + DESKTOP_RGB = 0x12000, + VGA_RGB = 0x20000, + DISPLAY_RGB = 0x30000, + HEADSET_RGB = 0x40000, + MICROPHONE_RGB = 0x50000, + EXTERNAL_HARD_DRIVER_RGB = 0x60000, + EXTERNAL_BLUE_RAY_RGB = 0x61000, + DRAM_RGB = 0x70000, + KEYBOARD_RGB = 0x80000, + NB_KB_RGB = 0x81000, + NB_KB_4ZONE_RGB = 0x81001, + MOUSE_RGB = 0x90000, + CHASSIS_RGB = 0xB0000, + PROJECTOR_RGB = 0xC0000 +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Enum/AsusLedId.cs b/RGB.NET.Devices.Asus/Enum/AsusLedId.cs index f56d64a4..baac0003 100644 --- a/RGB.NET.Devices.Asus/Enum/AsusLedId.cs +++ b/RGB.NET.Devices.Asus/Enum/AsusLedId.cs @@ -1,160 +1,164 @@ // ReSharper disable InconsistentNaming +#pragma warning disable 1591 -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// Represents a LED ID as they are known by the ASUS SDK +/// +public enum AsusLedId : ushort { - internal enum AsusLedId : ushort - { - KEY_ESCAPE = 0x01, - KEY_1 = 0x02, - KEY_2 = 0x03, - KEY_3 = 0x04, - KEY_4 = 0x05, - KEY_5 = 0x06, - KEY_6 = 0x07, - KEY_7 = 0x08, - KEY_8 = 0x09, - KEY_9 = 0x0A, - KEY_0 = 0x0B, - KEY_MINUS = 0x0C, // - on main keyboard - KEY_EQUALS = 0x0D, - KEY_BACK = 0x0E, // backspace - KEY_TAB = 0x0F, - KEY_Q = 0x10, - KEY_W = 0x11, - KEY_E = 0x12, - KEY_R = 0x13, - KEY_T = 0x14, - KEY_Y = 0x15, - KEY_U = 0x16, - KEY_I = 0x17, - KEY_O = 0x18, - KEY_P = 0x19, - KEY_LBRACKET = 0x1A, - KEY_RBRACKET = 0x1B, - KEY_RETURN = 0x1C, // Enter on main keyboard - KEY_LCONTROL = 0x1D, - KEY_A = 0x1E, - KEY_S = 0x1F, - KEY_D = 0x20, - KEY_F = 0x21, - KEY_G = 0x22, - KEY_H = 0x23, - KEY_J = 0x24, - KEY_K = 0x25, - KEY_L = 0x26, - KEY_SEMICOLON = 0x27, - KEY_APOSTROPHE = 0x28, - KEY_GRAVE = 0x29, // accent grave - KEY_LSHIFT = 0x2A, - KEY_BACKSLASH = 0x2B, - KEY_Z = 0x2C, - KEY_X = 0x2D, - KEY_C = 0x2E, - KEY_V = 0x2F, - KEY_B = 0x30, - KEY_N = 0x31, - KEY_M = 0x32, - KEY_COMMA = 0x33, - KEY_PERIOD = 0x34, // . on main keyboard - KEY_SLASH = 0x35, // / on main keyboard - KEY_RSHIFT = 0x36, - KEY_MULTIPLY = 0x37, // * on numeric keypad - KEY_LMENU = 0x38, // left Alt - KEY_SPACE = 0x39, - KEY_CAPITAL = 0x3A, - KEY_F1 = 0x3B, - KEY_F2 = 0x3C, - KEY_F3 = 0x3D, - KEY_F4 = 0x3E, - KEY_F5 = 0x3F, - KEY_F6 = 0x40, - KEY_F7 = 0x41, - KEY_F8 = 0x42, - KEY_F9 = 0x43, - KEY_F10 = 0x44, - KEY_NUMLOCK = 0x45, - KEY_SCROLL = 0x46, // Scroll Lock - KEY_NUMPAD7 = 0x47, - KEY_NUMPAD8 = 0x48, - KEY_NUMPAD9 = 0x49, - KEY_SUBTRACT = 0x4A, // - on numeric keypad - KEY_NUMPAD4 = 0x4B, - KEY_NUMPAD5 = 0x4C, - KEY_NUMPAD6 = 0x4D, - KEY_ADD = 0x4E, // + on numeric keypad - KEY_NUMPAD1 = 0x4F, - KEY_NUMPAD2 = 0x50, - KEY_NUMPAD3 = 0x51, - KEY_NUMPAD0 = 0x52, - KEY_DECIMAL = 0x53, // . on numeric keypad - KEY_OEM_102 = 0x56, // < > | on UK/Germany keyboards - KEY_F11 = 0x57, - KEY_F12 = 0x58, - KEY_F13 = 0x64, // (NEC PC98) - KEY_F14 = 0x65, // (NEC PC98) - KEY_F15 = 0x66, // (NEC PC98) - KEY_KANA = 0x70, // (Japanese keyboard) - KEY_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards - KEY_CONVERT = 0x79, // (Japanese keyboard) - KEY_NOCONVERT = 0x7B, // (Japanese keyboard) - KEY_YEN = 0x7D, // (Japanese keyboard) - KEY_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards - KEY_NUMPADEQUALS = 0x8D, // = on numeric keypad (NEC PC98) - KEY_CIRCUMFLEX = 0x90, // (Japanese keyboard) - KEY_AT = 0x91, // (NEC PC98) - KEY_COLON = 0x92, // (NEC PC98) - KEY_UNDERLINE = 0x93, // (NEC PC98) - KEY_KANJI = 0x94, // (Japanese keyboard) - KEY_STOP = 0x95, // (NEC PC98) - KEY_AX = 0x96, // (Japan AX) - KEY_UNLABELED = 0x97, // (J3100) - KEY_NEXTTRACK = 0x99, // Next Track - KEY_NUMPADENTER = 0x9C, // Enter on numeric keypad - KEY_RCONTROL = 0x9D, // - KEY_MUTE = 0xA0, // Mute - KEY_CALCULATOR = 0xA1, // Calculator - KEY_PLAYPAUSE = 0xA2, // Play / Pause - KEY_MEDIASTOP = 0xA4, // Media Stop - KEY_VOLUMEDOWN = 0xAE, // Volume - - KEY_VOLUMEUP = 0xB0, // Volume + - KEY_WEBHOME = 0xB2, // Web home - KEY_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98) - KEY_DIVIDE = 0xB5, // / on numeric keypad - KEY_SYSRQ = 0xB7, // - KEY_RMENU = 0xB8, // right Alt - KEY_PAUSE = 0xC5, // Pause - KEY_HOME = 0xC7, // Home on arrow keypad - KEY_UP = 0xC8, // UpArrow on arrow keypad - KEY_PRIOR = 0xC9, // PgUp on arrow keypad - KEY_LEFT = 0xCB, // LeftArrow on arrow keypad - KEY_RIGHT = 0xCD, // RightArrow on arrow keypad - KEY_END = 0xCF, // End on arrow keypad - KEY_DOWN = 0xD0, // DownArrow on arrow keypad - KEY_NEXT = 0xD1, // PgDn on arrow keypad - KEY_INSERT = 0xD2, // Insert on arrow keypad - KEY_DELETE = 0xD3, // Delete on arrow keypad - KEY_LWIN = 0xDB, // Left Windows key - KEY_RWIN = 0xDC, // Right Windows key - KEY_APPS = 0xDD, // AppMenu key - KEY_POWER = 0xDE, // - KEY_SLEEP = 0xDF, // - KEY_WAKE = 0xE3, // System Wake - KEY_WEBSEARCH = 0xE5, // Web Search - KEY_WEBFAVORITES = 0xE6, // Web Favorites - KEY_WEBREFRESH = 0xE7, // Web Refresh - KEY_WEBSTOP = 0xE8, // Web Stop - KEY_WEBFORWARD = 0xE9, // Web Forward - KEY_WEBBACK = 0xEA, // Web Back - KEY_MYCOMPUTER = 0xEB, // My Computer - KEY_MAIL = 0xEC, // Mail - KEY_MEDIASELECT = 0xED, // Media Select - KEY_FN = 0x100, // Function key + KEY_ESCAPE = 0x01, + KEY_1 = 0x02, + KEY_2 = 0x03, + KEY_3 = 0x04, + KEY_4 = 0x05, + KEY_5 = 0x06, + KEY_6 = 0x07, + KEY_7 = 0x08, + KEY_8 = 0x09, + KEY_9 = 0x0A, + KEY_0 = 0x0B, + KEY_MINUS = 0x0C, // - on main keyboard + KEY_EQUALS = 0x0D, + KEY_BACK = 0x0E, // backspace + KEY_TAB = 0x0F, + KEY_Q = 0x10, + KEY_W = 0x11, + KEY_E = 0x12, + KEY_R = 0x13, + KEY_T = 0x14, + KEY_Y = 0x15, + KEY_U = 0x16, + KEY_I = 0x17, + KEY_O = 0x18, + KEY_P = 0x19, + KEY_LBRACKET = 0x1A, + KEY_RBRACKET = 0x1B, + KEY_RETURN = 0x1C, // Enter on main keyboard + KEY_LCONTROL = 0x1D, + KEY_A = 0x1E, + KEY_S = 0x1F, + KEY_D = 0x20, + KEY_F = 0x21, + KEY_G = 0x22, + KEY_H = 0x23, + KEY_J = 0x24, + KEY_K = 0x25, + KEY_L = 0x26, + KEY_SEMICOLON = 0x27, + KEY_APOSTROPHE = 0x28, + KEY_GRAVE = 0x29, // accent grave + KEY_LSHIFT = 0x2A, + KEY_BACKSLASH = 0x2B, + KEY_Z = 0x2C, + KEY_X = 0x2D, + KEY_C = 0x2E, + KEY_V = 0x2F, + KEY_B = 0x30, + KEY_N = 0x31, + KEY_M = 0x32, + KEY_COMMA = 0x33, + KEY_PERIOD = 0x34, // . on main keyboard + KEY_SLASH = 0x35, // / on main keyboard + KEY_RSHIFT = 0x36, + KEY_MULTIPLY = 0x37, // * on numeric keypad + KEY_LMENU = 0x38, // left Alt + KEY_SPACE = 0x39, + KEY_CAPITAL = 0x3A, + KEY_F1 = 0x3B, + KEY_F2 = 0x3C, + KEY_F3 = 0x3D, + KEY_F4 = 0x3E, + KEY_F5 = 0x3F, + KEY_F6 = 0x40, + KEY_F7 = 0x41, + KEY_F8 = 0x42, + KEY_F9 = 0x43, + KEY_F10 = 0x44, + KEY_NUMLOCK = 0x45, + KEY_SCROLL = 0x46, // Scroll Lock + KEY_NUMPAD7 = 0x47, + KEY_NUMPAD8 = 0x48, + KEY_NUMPAD9 = 0x49, + KEY_SUBTRACT = 0x4A, // - on numeric keypad + KEY_NUMPAD4 = 0x4B, + KEY_NUMPAD5 = 0x4C, + KEY_NUMPAD6 = 0x4D, + KEY_ADD = 0x4E, // + on numeric keypad + KEY_NUMPAD1 = 0x4F, + KEY_NUMPAD2 = 0x50, + KEY_NUMPAD3 = 0x51, + KEY_NUMPAD0 = 0x52, + KEY_DECIMAL = 0x53, // . on numeric keypad + KEY_OEM_102 = 0x56, // < > | on UK/Germany keyboards + KEY_F11 = 0x57, + KEY_F12 = 0x58, + KEY_F13 = 0x64, // (NEC PC98) + KEY_F14 = 0x65, // (NEC PC98) + KEY_F15 = 0x66, // (NEC PC98) + KEY_KANA = 0x70, // (Japanese keyboard) + KEY_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards + KEY_CONVERT = 0x79, // (Japanese keyboard) + KEY_NOCONVERT = 0x7B, // (Japanese keyboard) + KEY_YEN = 0x7D, // (Japanese keyboard) + KEY_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards + KEY_NUMPADEQUALS = 0x8D, // = on numeric keypad (NEC PC98) + KEY_CIRCUMFLEX = 0x90, // (Japanese keyboard) + KEY_AT = 0x91, // (NEC PC98) + KEY_COLON = 0x92, // (NEC PC98) + KEY_UNDERLINE = 0x93, // (NEC PC98) + KEY_KANJI = 0x94, // (Japanese keyboard) + KEY_STOP = 0x95, // (NEC PC98) + KEY_AX = 0x96, // (Japan AX) + KEY_UNLABELED = 0x97, // (J3100) + KEY_NEXTTRACK = 0x99, // Next Track + KEY_NUMPADENTER = 0x9C, // Enter on numeric keypad + KEY_RCONTROL = 0x9D, // + KEY_MUTE = 0xA0, // Mute + KEY_CALCULATOR = 0xA1, // Calculator + KEY_PLAYPAUSE = 0xA2, // Play / Pause + KEY_MEDIASTOP = 0xA4, // Media Stop + KEY_VOLUMEDOWN = 0xAE, // Volume - + KEY_VOLUMEUP = 0xB0, // Volume + + KEY_WEBHOME = 0xB2, // Web home + KEY_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98) + KEY_DIVIDE = 0xB5, // / on numeric keypad + KEY_SYSRQ = 0xB7, // + KEY_RMENU = 0xB8, // right Alt + KEY_PAUSE = 0xC5, // Pause + KEY_HOME = 0xC7, // Home on arrow keypad + KEY_UP = 0xC8, // UpArrow on arrow keypad + KEY_PRIOR = 0xC9, // PgUp on arrow keypad + KEY_LEFT = 0xCB, // LeftArrow on arrow keypad + KEY_RIGHT = 0xCD, // RightArrow on arrow keypad + KEY_END = 0xCF, // End on arrow keypad + KEY_DOWN = 0xD0, // DownArrow on arrow keypad + KEY_NEXT = 0xD1, // PgDn on arrow keypad + KEY_INSERT = 0xD2, // Insert on arrow keypad + KEY_DELETE = 0xD3, // Delete on arrow keypad + KEY_LWIN = 0xDB, // Left Windows key + KEY_RWIN = 0xDC, // Right Windows key + KEY_APPS = 0xDD, // AppMenu key + KEY_POWER = 0xDE, // + KEY_SLEEP = 0xDF, // + KEY_WAKE = 0xE3, // System Wake + KEY_WEBSEARCH = 0xE5, // Web Search + KEY_WEBFAVORITES = 0xE6, // Web Favorites + KEY_WEBREFRESH = 0xE7, // Web Refresh + KEY_WEBSTOP = 0xE8, // Web Stop + KEY_WEBFORWARD = 0xE9, // Web Forward + KEY_WEBBACK = 0xEA, // Web Back + KEY_MYCOMPUTER = 0xEB, // My Computer + KEY_MAIL = 0xEC, // Mail + KEY_MEDIASELECT = 0xED, // Media Select + KEY_FN = 0x100, // Function key - // Undocumented - UNDOCUMENTED_1 = 0x59, - UNDOCUMENTED_2 = 0x56, - UNDOCUMENTED_3 = 0x101, - UNDOCUMENTED_4 = 0x102, - UNDOCUMENTED_5 = 0x103, - } -} + // Undocumented + UNDOCUMENTED_1 = 0x59, + UNDOCUMENTED_2 = 0x56, + UNDOCUMENTED_3 = 0x101, + UNDOCUMENTED_4 = 0x102, + UNDOCUMENTED_5 = 0x103, + UNDOCUMENTED_6 = 0xDA, // Bottom-left function on the ROG Zephyrus Duo 15 +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Enum/AsusLedType.cs b/RGB.NET.Devices.Asus/Enum/AsusLedType.cs new file mode 100644 index 00000000..ddff60af --- /dev/null +++ b/RGB.NET.Devices.Asus/Enum/AsusLedType.cs @@ -0,0 +1,17 @@ +namespace RGB.NET.Devices.Asus; + +/// +/// Represents a type of ASUS LED as known by the ASUS SDK +/// +public enum AsusLedType +{ + /// + /// An ASUS LED that is present on a device's IAuraSyncKeyboard.Keys enumerable + /// + Key, + + /// + /// An ASUS LED that is present on a device's IAuraSyncDevice.Lights enumerable + /// + Light +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Enum/AsusLogicalKeyboardLayout.cs b/RGB.NET.Devices.Asus/Enum/AsusLogicalKeyboardLayout.cs deleted file mode 100644 index 60105e50..00000000 --- a/RGB.NET.Devices.Asus/Enum/AsusLogicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Asus -{ - /// - /// Contains list of available logical layouts for asus keyboards. - /// - public enum AsusLogicalKeyboardLayout - { - TODO - }; -} diff --git a/RGB.NET.Devices.Asus/Enum/AsusPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Asus/Enum/AsusPhysicalKeyboardLayout.cs deleted file mode 100644 index b5e80de7..00000000 --- a/RGB.NET.Devices.Asus/Enum/AsusPhysicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable UnusedMember.Global -// ReSharper disable InconsistentNaming - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Asus -{ - /// - /// Contains list of available physical layouts for asus keyboards. - /// - public enum AsusPhysicalKeyboardLayout - { - TODO - } -} diff --git a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs index 42caff97..0e7bb5fa 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusRGBDevice.cs @@ -1,94 +1,24 @@ -using System.Collections.Generic; -using System.Linq; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// +/// Represents a generic Asus-device. (keyboard, mouse, headset, mousepad). +/// +public abstract class AsusRGBDevice : AbstractRGBDevice, IAsusRGBDevice + where TDeviceInfo : AsusRGBDeviceInfo { - /// - /// + #region Constructors + /// - /// Represents a generic Asus-device. (keyboard, mouse, headset, mousepad). + /// Initializes a new instance of the class. /// - public abstract class AsusRGBDevice : AbstractRGBDevice, IAsusRGBDevice - where TDeviceInfo : AsusRGBDeviceInfo - { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected AsusUpdateQueue UpdateQueue { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by Asus for the device. - protected AsusRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - - UpdateQueue = new AsusUpdateQueue(updateTrigger); - UpdateQueue.Initialize(DeviceInfo.Device); - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); - - /// - public override void SyncBack() - { - // DarthAffe 16.06.2019: This doesn't work since the SDK only returns the colors we set. - //foreach (Led led in LedMapping.Values) - //{ - // int index = (int)led.CustomData; - // IAuraRgbLight light = DeviceInfo.Device.Lights[index]; - // SetLedColorWithoutRequest(led, new Color(light.Red, light.Green, light.Blue)); - //} - } - - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } - - #endregion - } -} + /// The generic information provided by Asus for the device. + /// The update trigger used to update this device. + protected AsusRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new AsusUpdateQueue(updateTrigger, info.Device)) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Generic/AsusRGBDeviceInfo.cs b/RGB.NET.Devices.Asus/Generic/AsusRGBDeviceInfo.cs index 62c7ea9a..e259ed4b 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusRGBDeviceInfo.cs @@ -1,61 +1,56 @@ -using System; -using AuraServiceLib; +using AuraServiceLib; using RGB.NET.Core; -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a generic information for a Corsair-. - /// - public class AsusRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Devices.Asus; - /// - public RGBDeviceType DeviceType { get; } - - /// - public string DeviceName { get; } - - /// - public string Manufacturer { get; } +/// +/// +/// Represents a generic information for a Corsair-. +/// +public class AsusRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public string Model { get; } + /// + public RGBDeviceType DeviceType { get; } - /// - public Uri Image { get; set; } + /// + public string DeviceName { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public string Manufacturer { get; } - /// - public bool SupportsSyncBack => false; + /// + public string Model { get; } - public IAuraSyncDevice Device { get; } + /// + public object? LayoutMetadata { get; set; } - #endregion + /// + /// Gets the SDK-aura-device this device represents. + /// + public IAuraSyncDevice Device { get; } - #region Constructors + #endregion - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The backing this RGB.NET device. - /// The manufacturer-name of the . - /// The model-name of the . - internal AsusRGBDeviceInfo(RGBDeviceType deviceType, IAuraSyncDevice device, string model = null, string manufacturer = "Asus") - { - this.DeviceType = deviceType; - this.Device = device; - this.Model = model ?? device.Name; - this.Manufacturer = manufacturer; + #region Constructors - DeviceName = $"{Manufacturer} {Model}"; - } + /// + /// Internal constructor of managed . + /// + /// The type of the . + /// The backing this RGB.NET device. + /// The manufacturer-name of the . + /// The model-name of the . + internal AsusRGBDeviceInfo(RGBDeviceType deviceType, IAuraSyncDevice device, string? model = null, string manufacturer = "Asus") + { + this.DeviceType = deviceType; + this.Device = device; + this.Model = model ?? device.Name; + this.Manufacturer = manufacturer; - #endregion + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs index 40eb6029..bb405782 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusUnspecifiedRGBDevice.cs @@ -1,49 +1,49 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// +/// Represents a Asus headset. +/// +public class AsusUnspecifiedRGBDevice : AsusRGBDevice, IUnknownDevice { - /// - /// - /// Represents a Asus headset. - /// - public class AsusUnspecifiedRGBDevice : AsusRGBDevice, IUnknownDevice - { - #region Properties & Fields + #region Properties & Fields - private LedId _baseLedId; + private LedId _baseLedId; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the headset. - internal AsusUnspecifiedRGBDevice(AsusRGBDeviceInfo info, LedId baseLedId) - : base(info) - { - this._baseLedId = baseLedId; - } + /// + /// + /// Initializes a new instance of the class. + /// + /// The specific information provided by Asus for the headset. + /// The ledId of the first led of this device. All other leds are created by incrementing this base-id by 1. + /// The update trigger used to update this device. + internal AsusUnspecifiedRGBDevice(AsusRGBDeviceInfo info, LedId baseLedId, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) + { + this._baseLedId = baseLedId; - #endregion + InitializeLayout(); + } - #region Methods + #endregion - /// - protected override void InitializeLayout() - { - int ledCount = DeviceInfo.Device.Lights.Count; - for (int i = 0; i < ledCount; i++) - InitializeLed(_baseLedId + i, new Rectangle(i * 10, 0, 10, 10)); + #region Methods - //TODO DarthAffe 19.05.2019: Add a way to define a layout for this kind of devies - } + private void InitializeLayout() + { + int ledCount = DeviceInfo.Device.Lights.Count; + for (int i = 0; i < ledCount; i++) + AddLed(_baseLedId + i, new Point(i * 10, 0), new Size(10, 10)); + } - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)_baseLedId; + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)_baseLedId; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs index 9a3b2602..6de33faa 100644 --- a/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs +++ b/RGB.NET.Devices.Asus/Generic/AsusUpdateQueue.cs @@ -1,103 +1,98 @@ -using System.Collections.Generic; +using System; using AuraServiceLib; using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// +/// Represents the update-queue performing updates for asus devices. +/// +public class AsusUpdateQueue : UpdateQueue { - /// + #region Properties & Fields + + private readonly IAuraRgbLight[] _lights; + /// - /// Represents the update-queue performing updates for asus devices. + /// The device to be updated. /// - public class AsusUpdateQueue : UpdateQueue - { - #region Properties & Fields - - /// - /// The device to be updated. - /// - protected IAuraSyncDevice Device { get; private set; } + protected IAuraSyncDevice Device { get; } - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - public AsusUpdateQueue(IDeviceUpdateTrigger updateTrigger) - : base(updateTrigger) - { } + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The SDK-aura-device this device represents. + public AsusUpdateQueue(IDeviceUpdateTrigger updateTrigger, IAuraSyncDevice device) + : base(updateTrigger) + { + this.Device = device; - #endregion + this._lights = new IAuraRgbLight[device.Lights.Count]; + for (int i = 0; i < device.Lights.Count; i++) + _lights[i] = device.Lights[i]; + } - #region Methods + #endregion - /// - /// Initializes the queue. - /// - /// The device to be updated. - public void Initialize(IAuraSyncDevice device) - { - Device = device; - } + #region Methods - /// - protected override void Update(Dictionary dataSet) + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + try { - try + if ((Device.Type == (uint)AsusDeviceType.KEYBOARD_RGB) || (Device.Type == (uint)AsusDeviceType.NB_KB_RGB)) { - if ((Device.Type == (uint)AsusDeviceType.KEYBOARD_RGB) || (Device.Type == (uint)AsusDeviceType.NB_KB_RGB)) + if (Device is not IAuraSyncKeyboard keyboard) + return; + + foreach ((object customData, Color value) in dataSet) { - foreach (KeyValuePair data in dataSet) + (AsusLedType ledType, int id) = (AsusKeyboardLedCustomData)customData; + if (ledType == AsusLedType.Key) { - AsusLedId index = (AsusLedId)data.Key; - IAuraSyncKeyboard keyboard = (IAuraSyncKeyboard)Device; - if (keyboard != null) - { - IAuraRgbLight light = index switch - { - //UK keyboard Layout - AsusLedId.KEY_OEM_102 => keyboard.Lights[(int)((3 * keyboard.Width) + 13)], - AsusLedId.UNDOCUMENTED_1 => keyboard.Lights[(int)((4 * keyboard.Width) + 1)], - _ => keyboard.Key[(ushort)index] - }; - - // Asus Strix Scope - if (keyboard.Name == "Charm") - light = index switch - { - AsusLedId.KEY_LWIN => keyboard.Lights[(int)((5 * keyboard.Width) + 2)], - AsusLedId.KEY_LMENU => keyboard.Lights[(int)((5 * keyboard.Width) + 3)], - _ => light - }; - - (_, byte r, byte g, byte b) = data.Value.GetRGBBytes(); - light.Red = r; - light.Green = g; - light.Blue = b; - } + IAuraRgbLight light = keyboard.Key[(ushort)id]; + (_, byte r, byte g, byte b) = value.GetRGBBytes(); + light.Red = r; + light.Green = g; + light.Blue = b; } - } - else - { - foreach (KeyValuePair data in dataSet) + else { - int index = (int)data.Key; - IAuraRgbLight light = Device.Lights[index]; - - (_, byte r, byte g, byte b) = data.Value.GetRGBBytes(); + IAuraRgbLight light = _lights[id]; + (_, byte r, byte g, byte b) = value.GetRGBBytes(); light.Red = r; light.Green = g; light.Blue = b; } } + } + else + { + foreach ((object key, Color value) in dataSet) + { + int index = (int)key; + IAuraRgbLight light = _lights[index]; - Device.Apply(); + (_, byte r, byte g, byte b) = value.GetRGBBytes(); + light.Red = r; + light.Green = g; + light.Blue = b; + } } - catch - { /* "The server threw an exception." seems to be a thing here ... */ } + + Device.Apply(); + } + catch + { /* "The server threw an exception." seems to be a thing here ... */ } - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs b/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs index 720fd3cd..cb7d4a93 100644 --- a/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Generic/IAsusRGBDevice.cs @@ -1,12 +1,9 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Asus -{ - /// - /// Represents a asus RGB-device. - /// - internal interface IAsusRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } -} +namespace RGB.NET.Devices.Asus; + +/// +/// Represents a asus RGB-device. +/// +public interface IAsusRGBDevice : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs index f50f70f0..15c23831 100644 --- a/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs +++ b/RGB.NET.Devices.Asus/GraphicsCard/AsusGraphicsCardRGBDevice.cs @@ -1,43 +1,40 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// +/// Represents a Asus graphicsCard. +/// +public class AsusGraphicsCardRGBDevice : AsusRGBDevice, IGraphicsCard { - /// + #region Constructors + + /// /// - /// Represents a Asus graphicsCard. + /// Initializes a new instance of the class. /// - public class AsusGraphicsCardRGBDevice : AsusRGBDevice, IGraphicsCard + /// The specific information provided by Asus for the graphics card. + /// The update trigger used to update this device. + internal AsusGraphicsCardRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the graphics card. - internal AsusGraphicsCardRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } - - #endregion + InitializeLayout(); + } - #region Methods + #endregion - /// - protected override void InitializeLayout() - { - //TODO DarthAffe 07.10.2017: Look for a good default layout - int ledCount = DeviceInfo.Device.Lights.Count; - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.GraphicsCard1 + i, new Rectangle(i * 10, 0, 10, 10)); + #region Methods - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\GraphicsCards", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } + private void InitializeLayout() + { + int ledCount = DeviceInfo.Device.Lights.Count; + for (int i = 0; i < ledCount; i++) + AddLed(LedId.GraphicsCard1 + i, new Point(i * 10, 0), new Size(10, 10)); + } - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs b/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs index a3727d1b..71f9e109 100644 --- a/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Headset/AsusHeadsetRGBDevice.cs @@ -1,43 +1,40 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// +/// Represents a Asus headset. +/// +public class AsusHeadsetRGBDevice : AsusRGBDevice, IHeadset { - /// + #region Constructors + + /// /// - /// Represents a Asus headset. + /// Initializes a new instance of the class. /// - public class AsusHeadsetRGBDevice : AsusRGBDevice, IHeadset + /// The specific information provided by Asus for the headset. + /// The update trigger used to update this device. + internal AsusHeadsetRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the headset. - internal AsusHeadsetRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } - - #endregion + InitializeLayout(); + } - #region Methods + #endregion - /// - protected override void InitializeLayout() - { - //TODO DarthAffe 07.10.2017: Look for a good default layout - int ledCount = DeviceInfo.Device.Lights.Count; - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Headset1 + i, new Rectangle(i * 40, 0, 40, 8)); + #region Methods - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Headsets", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } + private void InitializeLayout() + { + int ledCount = DeviceInfo.Device.Lights.Count; + for (int i = 0; i < ledCount; i++) + AddLed(LedId.Headset1 + i, new Point(i * 40, 0), new Size(40, 8)); + } - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1; + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Helper/WMIHelper.cs b/RGB.NET.Devices.Asus/Helper/WMIHelper.cs index 0ea746e6..5aa49c75 100644 --- a/RGB.NET.Devices.Asus/Helper/WMIHelper.cs +++ b/RGB.NET.Devices.Asus/Helper/WMIHelper.cs @@ -1,63 +1,82 @@ -#if NETFULL +using System; using System.Management; -namespace RGB.NET.Devices.Asus -{ - // ReSharper disable once InconsistentNaming - internal static class WMIHelper - { - #region Properties & Fields +namespace RGB.NET.Devices.Asus; - private static ManagementObjectSearcher _mainboardSearcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT Manufacturer,Product FROM Win32_BaseBoard"); - private static ManagementObjectSearcher _graphicsCardSearcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT Name FROM Win32_VideoController"); +// ReSharper disable once InconsistentNaming +internal static class WMIHelper +{ + #region Properties & Fields - private static (string manufacturer, string model)? _mainboardInfo; - private static string _graphicsCardInfo; + // ReSharper disable InconsistentNaming + private static readonly ManagementObjectSearcher? _systemModelSearcher; + private static readonly ManagementObjectSearcher? _mainboardSearcher; + private static readonly ManagementObjectSearcher? _graphicsCardSearcher; + // ReSharper restore InconsistentNaming - #endregion + private static string? _systemModelInfo; + private static (string manufacturer, string model)? _mainboardInfo; + private static string? _graphicsCardInfo; + + #endregion - #region Methods + #region Constructors - internal static (string manufacturer, string model)? GetMainboardInfo() + static WMIHelper() + { + if (OperatingSystem.IsWindows()) { - if (!_mainboardInfo.HasValue) - foreach (ManagementBaseObject managementBaseObject in _mainboardSearcher.Get()) - { - _mainboardInfo = (managementBaseObject["Manufacturer"]?.ToString(), managementBaseObject["Product"]?.ToString()); - break; - } - - return _mainboardInfo; + _systemModelSearcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT Model FROM Win32_ComputerSystem"); + _mainboardSearcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT Manufacturer,Product FROM Win32_BaseBoard"); + _graphicsCardSearcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT Name FROM Win32_VideoController"); } + } - internal static string GetGraphicsCardsInfo() - { - if (_graphicsCardInfo == null) - foreach (ManagementBaseObject managementBaseObject in _graphicsCardSearcher.Get()) - { - _graphicsCardInfo = managementBaseObject["Name"]?.ToString(); - break; - } - - return _graphicsCardInfo; - } + #endregion + + #region Methods + + internal static string? GetSystemModelInfo() + { + if (!OperatingSystem.IsWindows()) return null; + + if ((_systemModelInfo == null) && (_systemModelSearcher != null)) + foreach (ManagementBaseObject managementBaseObject in _systemModelSearcher.Get()) + { + _systemModelInfo = managementBaseObject["Model"]?.ToString(); + break; + } - #endregion + return _systemModelInfo; } -} -#else -namespace RGB.NET.Devices.Asus -{ - // ReSharper disable once InconsistentNaming - internal static class WMIHelper + + internal static (string manufacturer, string model)? GetMainboardInfo() { - #region Methods + if (!OperatingSystem.IsWindows()) return null; - internal static (string manufacturer, string model)? GetMainboardInfo() => null; + if (!_mainboardInfo.HasValue && (_mainboardSearcher != null)) + foreach (ManagementBaseObject managementBaseObject in _mainboardSearcher.Get()) + { + _mainboardInfo = (managementBaseObject["Manufacturer"]?.ToString() ?? string.Empty, managementBaseObject["Product"]?.ToString() ?? string.Empty); + break; + } - internal static string GetGraphicsCardsInfo() => null; + return _mainboardInfo; + } - #endregion + internal static string? GetGraphicsCardsInfo() + { + if (!OperatingSystem.IsWindows()) return null; + + if ((_graphicsCardInfo == null) && (_graphicsCardSearcher != null)) + foreach (ManagementBaseObject managementBaseObject in _graphicsCardSearcher.Get()) + { + _graphicsCardInfo = managementBaseObject["Name"]?.ToString(); + break; + } + + return _graphicsCardInfo; } -} -#endif + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardLedMapping.cs b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardLedMapping.cs index 2b489615..9eb8d1fd 100644 --- a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardLedMapping.cs +++ b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardLedMapping.cs @@ -1,161 +1,191 @@ -using System.Collections.Generic; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// Contains mappings for to . +/// +public static class LedMappings { - internal static class AsusKeyboardLedMapping + /// + /// A LED mapping containing ASUS keyboard LED IDs + /// + public static LedMapping KeyboardMapping { get; } = new() + { + { LedId.Keyboard_Escape, AsusLedId.KEY_ESCAPE }, + { LedId.Keyboard_F1, AsusLedId.KEY_F1 }, + { LedId.Keyboard_F2, AsusLedId.KEY_F2 }, + { LedId.Keyboard_F3, AsusLedId.KEY_F3 }, + { LedId.Keyboard_F4, AsusLedId.KEY_F4 }, + { LedId.Keyboard_F5, AsusLedId.KEY_F5 }, + { LedId.Keyboard_F6, AsusLedId.KEY_F6 }, + { LedId.Keyboard_F7, AsusLedId.KEY_F7 }, + { LedId.Keyboard_F8, AsusLedId.KEY_F8 }, + { LedId.Keyboard_F9, AsusLedId.KEY_F9 }, + { LedId.Keyboard_F10, AsusLedId.KEY_F10 }, + { LedId.Keyboard_F11, AsusLedId.KEY_F11 }, + { LedId.Keyboard_F12, AsusLedId.KEY_F12 }, + { LedId.Keyboard_1, AsusLedId.KEY_1 }, + { LedId.Keyboard_2, AsusLedId.KEY_2 }, + { LedId.Keyboard_3, AsusLedId.KEY_3 }, + { LedId.Keyboard_4, AsusLedId.KEY_4 }, + { LedId.Keyboard_5, AsusLedId.KEY_5 }, + { LedId.Keyboard_6, AsusLedId.KEY_6 }, + { LedId.Keyboard_7, AsusLedId.KEY_7 }, + { LedId.Keyboard_8, AsusLedId.KEY_8 }, + { LedId.Keyboard_9, AsusLedId.KEY_9 }, + { LedId.Keyboard_0, AsusLedId.KEY_0 }, + { LedId.Keyboard_MinusAndUnderscore, AsusLedId.KEY_MINUS }, + { LedId.Keyboard_EqualsAndPlus, AsusLedId.KEY_EQUALS }, + { LedId.Keyboard_Backspace, AsusLedId.KEY_BACK }, + { LedId.Keyboard_Tab, AsusLedId.KEY_TAB }, + { LedId.Keyboard_Q, AsusLedId.KEY_Q }, + { LedId.Keyboard_W, AsusLedId.KEY_W }, + { LedId.Keyboard_E, AsusLedId.KEY_E }, + { LedId.Keyboard_R, AsusLedId.KEY_R }, + { LedId.Keyboard_T, AsusLedId.KEY_T }, + { LedId.Keyboard_Y, AsusLedId.KEY_Y }, + { LedId.Keyboard_U, AsusLedId.KEY_U }, + { LedId.Keyboard_I, AsusLedId.KEY_I }, + { LedId.Keyboard_O, AsusLedId.KEY_O }, + { LedId.Keyboard_P, AsusLedId.KEY_P }, + { LedId.Keyboard_BracketLeft, AsusLedId.KEY_LBRACKET }, + { LedId.Keyboard_BracketRight, AsusLedId.KEY_RBRACKET }, + { LedId.Keyboard_Enter, AsusLedId.KEY_RETURN }, + { LedId.Keyboard_CapsLock, AsusLedId.KEY_CAPITAL }, + { LedId.Keyboard_A, AsusLedId.KEY_A }, + { LedId.Keyboard_S, AsusLedId.KEY_S }, + { LedId.Keyboard_D, AsusLedId.KEY_D }, + { LedId.Keyboard_F, AsusLedId.KEY_F }, + { LedId.Keyboard_G, AsusLedId.KEY_G }, + { LedId.Keyboard_H, AsusLedId.KEY_H }, + { LedId.Keyboard_J, AsusLedId.KEY_J }, + { LedId.Keyboard_K, AsusLedId.KEY_K }, + { LedId.Keyboard_L, AsusLedId.KEY_L }, + { LedId.Keyboard_SemicolonAndColon, AsusLedId.KEY_SEMICOLON }, + { LedId.Keyboard_ApostropheAndDoubleQuote, AsusLedId.KEY_APOSTROPHE }, + { LedId.Keyboard_GraveAccentAndTilde, AsusLedId.KEY_GRAVE }, + { LedId.Keyboard_LeftShift, AsusLedId.KEY_LSHIFT }, + { LedId.Keyboard_Backslash, AsusLedId.KEY_BACKSLASH }, + { LedId.Keyboard_Z, AsusLedId.KEY_Z }, + { LedId.Keyboard_X, AsusLedId.KEY_X }, + { LedId.Keyboard_C, AsusLedId.KEY_C }, + { LedId.Keyboard_V, AsusLedId.KEY_V }, + { LedId.Keyboard_B, AsusLedId.KEY_B }, + { LedId.Keyboard_N, AsusLedId.KEY_N }, + { LedId.Keyboard_M, AsusLedId.KEY_M }, + { LedId.Keyboard_CommaAndLessThan, AsusLedId.KEY_COMMA }, + { LedId.Keyboard_PeriodAndBiggerThan, AsusLedId.KEY_PERIOD }, + { LedId.Keyboard_SlashAndQuestionMark, AsusLedId.KEY_SLASH }, + { LedId.Keyboard_RightShift, AsusLedId.KEY_RSHIFT }, + { LedId.Keyboard_LeftCtrl, AsusLedId.KEY_LCONTROL }, + { LedId.Keyboard_LeftGui, AsusLedId.KEY_LWIN }, + { LedId.Keyboard_LeftAlt, AsusLedId.KEY_LMENU }, + { LedId.Keyboard_Space, AsusLedId.KEY_SPACE }, + { LedId.Keyboard_RightAlt, AsusLedId.KEY_RMENU }, + { LedId.Keyboard_RightGui, AsusLedId.KEY_RWIN }, + { LedId.Keyboard_Application, AsusLedId.KEY_APPS }, + { LedId.Keyboard_RightCtrl, AsusLedId.KEY_RCONTROL }, + { LedId.Keyboard_PrintScreen, AsusLedId.KEY_SYSRQ }, + { LedId.Keyboard_ScrollLock, AsusLedId.KEY_SCROLL }, + { LedId.Keyboard_PauseBreak, AsusLedId.KEY_PAUSE }, + { LedId.Keyboard_Insert, AsusLedId.KEY_INSERT }, + { LedId.Keyboard_Home, AsusLedId.KEY_HOME }, + { LedId.Keyboard_PageUp, AsusLedId.KEY_PRIOR }, + { LedId.Keyboard_Delete, AsusLedId.KEY_DELETE }, + { LedId.Keyboard_End, AsusLedId.KEY_END }, + { LedId.Keyboard_PageDown, AsusLedId.KEY_NEXT }, + { LedId.Keyboard_ArrowUp, AsusLedId.KEY_UP }, + { LedId.Keyboard_ArrowLeft, AsusLedId.KEY_LEFT }, + { LedId.Keyboard_ArrowDown, AsusLedId.KEY_DOWN }, + { LedId.Keyboard_ArrowRight, AsusLedId.KEY_RIGHT }, + { LedId.Keyboard_NumLock, AsusLedId.KEY_NUMLOCK }, + { LedId.Keyboard_NumSlash, AsusLedId.KEY_DIVIDE }, + { LedId.Keyboard_NumAsterisk, AsusLedId.KEY_MULTIPLY }, + { LedId.Keyboard_NumMinus, AsusLedId.KEY_SUBTRACT }, + { LedId.Keyboard_Num7, AsusLedId.KEY_NUMPAD7 }, + { LedId.Keyboard_Num8, AsusLedId.KEY_NUMPAD8 }, + { LedId.Keyboard_Num9, AsusLedId.KEY_NUMPAD9 }, + { LedId.Keyboard_NumPeriodAndDelete, AsusLedId.KEY_DECIMAL }, + { LedId.Keyboard_NumPlus, AsusLedId.KEY_ADD }, + { LedId.Keyboard_Num4, AsusLedId.KEY_NUMPAD4 }, + { LedId.Keyboard_Num5, AsusLedId.KEY_NUMPAD5 }, + { LedId.Keyboard_Num6, AsusLedId.KEY_NUMPAD6 }, + { LedId.Keyboard_Num1, AsusLedId.KEY_NUMPAD1 }, + { LedId.Keyboard_Num2, AsusLedId.KEY_NUMPAD2 }, + { LedId.Keyboard_Num3, AsusLedId.KEY_NUMPAD3 }, + { LedId.Keyboard_Num0, AsusLedId.KEY_NUMPAD0 }, + { LedId.Keyboard_NumEnter, AsusLedId.KEY_NUMPADENTER }, + { LedId.Keyboard_NonUsBackslash, AsusLedId.UNDOCUMENTED_1 }, + { LedId.Keyboard_NonUsTilde, AsusLedId.UNDOCUMENTED_2 }, + { LedId.Keyboard_NumComma, AsusLedId.KEY_NUMPADCOMMA }, + { LedId.Logo, AsusLedId.UNDOCUMENTED_3 }, + { LedId.Keyboard_Function, AsusLedId.KEY_FN }, + { LedId.Keyboard_MediaMute, AsusLedId.KEY_MUTE }, + { LedId.Keyboard_MediaPlay, AsusLedId.KEY_PLAYPAUSE }, + { LedId.Keyboard_MediaStop, AsusLedId.KEY_MEDIASTOP }, + { LedId.Keyboard_MediaVolumeDown, AsusLedId.KEY_VOLUMEDOWN }, + { LedId.Keyboard_MediaVolumeUp, AsusLedId.KEY_VOLUMEUP }, + { LedId.Keyboard_Custom1, AsusLedId.KEY_F13 }, + { LedId.Keyboard_Custom2, AsusLedId.KEY_F14 }, + { LedId.Keyboard_Custom3, AsusLedId.KEY_F15 }, + { LedId.Keyboard_Custom4, AsusLedId.KEY_KANA }, + { LedId.Keyboard_Custom5, AsusLedId.KEY_ABNT_C1 }, + { LedId.Keyboard_Custom6, AsusLedId.KEY_CONVERT }, + { LedId.Keyboard_Custom7, AsusLedId.KEY_NOCONVERT }, + { LedId.Keyboard_Custom8, AsusLedId.KEY_YEN }, + { LedId.Keyboard_Custom9, AsusLedId.KEY_ABNT_C2 }, + { LedId.Keyboard_Custom10, AsusLedId.KEY_NUMPADEQUALS }, + { LedId.Keyboard_Custom11, AsusLedId.KEY_CIRCUMFLEX }, + { LedId.Keyboard_Custom12, AsusLedId.KEY_AT }, + { LedId.Keyboard_Custom13, AsusLedId.KEY_COLON }, + { LedId.Keyboard_Custom14, AsusLedId.KEY_UNDERLINE }, + { LedId.Keyboard_Custom15, AsusLedId.KEY_KANJI }, + { LedId.Keyboard_Custom16, AsusLedId.KEY_STOP }, + { LedId.Keyboard_Custom17, AsusLedId.KEY_AX }, + { LedId.Keyboard_Custom18, AsusLedId.KEY_UNLABELED }, + { LedId.Keyboard_Custom19, AsusLedId.KEY_NEXTTRACK }, + { LedId.Keyboard_Custom20, AsusLedId.KEY_CALCULATOR }, + { LedId.Keyboard_Custom21, AsusLedId.KEY_POWER }, + { LedId.Keyboard_Custom22, AsusLedId.KEY_SLEEP }, + { LedId.Keyboard_Custom23, AsusLedId.KEY_WAKE }, + { LedId.Keyboard_Custom24, AsusLedId.KEY_WEBSEARCH }, + { LedId.Keyboard_Custom25, AsusLedId.KEY_WEBFAVORITES }, + { LedId.Keyboard_Custom26, AsusLedId.KEY_WEBREFRESH }, + { LedId.Keyboard_Custom27, AsusLedId.KEY_WEBSTOP }, + { LedId.Keyboard_Custom28, AsusLedId.KEY_WEBFORWARD }, + { LedId.Keyboard_Custom29, AsusLedId.KEY_WEBHOME }, + { LedId.Keyboard_Custom30, AsusLedId.KEY_WEBBACK }, + { LedId.Keyboard_Custom31, AsusLedId.KEY_MYCOMPUTER }, + { LedId.Keyboard_Custom32, AsusLedId.KEY_MAIL }, + { LedId.Keyboard_Custom33, AsusLedId.KEY_MEDIASELECT }, + { LedId.Keyboard_Custom34, AsusLedId.UNDOCUMENTED_4 }, + { LedId.Keyboard_Custom35, AsusLedId.UNDOCUMENTED_5 }, + { LedId.Keyboard_Custom36, AsusLedId.UNDOCUMENTED_6 } + }; + + /// + /// A LED mapping containing extra lights for the ROG Zephyrus Duo 15 + /// + /// + /// + /// ASUS notebooks have extra lights under wide keys like space and backspace, these do not appear as keys on the device. + /// Instead they only appear in the Lights enumerable, this mapping maps LED IDs to the index of these lights. + /// + /// You may add more of these by further populating . + /// + public static LedMapping ROGZephyrusDuo15 { get; } = new() { - public static readonly Dictionary MAPPING = new Dictionary - { - { LedId.Keyboard_Escape, AsusLedId.KEY_ESCAPE }, - { LedId.Keyboard_F1, AsusLedId.KEY_F1 }, - { LedId.Keyboard_F2, AsusLedId.KEY_F2 }, - { LedId.Keyboard_F3, AsusLedId.KEY_F3 }, - { LedId.Keyboard_F4, AsusLedId.KEY_F4 }, - { LedId.Keyboard_F5, AsusLedId.KEY_F5 }, - { LedId.Keyboard_F6, AsusLedId.KEY_F6 }, - { LedId.Keyboard_F7, AsusLedId.KEY_F7 }, - { LedId.Keyboard_F8, AsusLedId.KEY_F8 }, - { LedId.Keyboard_F9, AsusLedId.KEY_F9 }, - { LedId.Keyboard_F10, AsusLedId.KEY_F10 }, - { LedId.Keyboard_F11, AsusLedId.KEY_F11 }, - { LedId.Keyboard_F12, AsusLedId.KEY_F12 }, - { LedId.Keyboard_1, AsusLedId.KEY_1 }, - { LedId.Keyboard_2, AsusLedId.KEY_2 }, - { LedId.Keyboard_3, AsusLedId.KEY_3 }, - { LedId.Keyboard_4, AsusLedId.KEY_4 }, - { LedId.Keyboard_5, AsusLedId.KEY_5 }, - { LedId.Keyboard_6, AsusLedId.KEY_6 }, - { LedId.Keyboard_7, AsusLedId.KEY_7 }, - { LedId.Keyboard_8, AsusLedId.KEY_8 }, - { LedId.Keyboard_9, AsusLedId.KEY_9 }, - { LedId.Keyboard_0, AsusLedId.KEY_0 }, - { LedId.Keyboard_MinusAndUnderscore, AsusLedId.KEY_MINUS }, - { LedId.Keyboard_EqualsAndPlus, AsusLedId.KEY_EQUALS }, - { LedId.Keyboard_Backspace, AsusLedId.KEY_BACK }, - { LedId.Keyboard_Tab, AsusLedId.KEY_TAB }, - { LedId.Keyboard_Q, AsusLedId.KEY_Q }, - { LedId.Keyboard_W, AsusLedId.KEY_W }, - { LedId.Keyboard_E, AsusLedId.KEY_E }, - { LedId.Keyboard_R, AsusLedId.KEY_R }, - { LedId.Keyboard_T, AsusLedId.KEY_T }, - { LedId.Keyboard_Y, AsusLedId.KEY_Y }, - { LedId.Keyboard_U, AsusLedId.KEY_U }, - { LedId.Keyboard_I, AsusLedId.KEY_I }, - { LedId.Keyboard_O, AsusLedId.KEY_O }, - { LedId.Keyboard_P, AsusLedId.KEY_P }, - { LedId.Keyboard_BracketLeft, AsusLedId.KEY_LBRACKET }, - { LedId.Keyboard_BracketRight, AsusLedId.KEY_RBRACKET }, - { LedId.Keyboard_Enter, AsusLedId.KEY_RETURN }, - { LedId.Keyboard_CapsLock, AsusLedId.KEY_CAPITAL }, - { LedId.Keyboard_A, AsusLedId.KEY_A }, - { LedId.Keyboard_S, AsusLedId.KEY_S }, - { LedId.Keyboard_D, AsusLedId.KEY_D }, - { LedId.Keyboard_F, AsusLedId.KEY_F }, - { LedId.Keyboard_G, AsusLedId.KEY_G }, - { LedId.Keyboard_H, AsusLedId.KEY_H }, - { LedId.Keyboard_J, AsusLedId.KEY_J }, - { LedId.Keyboard_K, AsusLedId.KEY_K }, - { LedId.Keyboard_L, AsusLedId.KEY_L }, - { LedId.Keyboard_SemicolonAndColon, AsusLedId.KEY_SEMICOLON }, - { LedId.Keyboard_ApostropheAndDoubleQuote, AsusLedId.KEY_APOSTROPHE }, - { LedId.Keyboard_GraveAccentAndTilde, AsusLedId.KEY_GRAVE }, - { LedId.Keyboard_LeftShift, AsusLedId.KEY_LSHIFT }, - { LedId.Keyboard_Backslash, AsusLedId.KEY_BACKSLASH }, - { LedId.Keyboard_Z, AsusLedId.KEY_Z }, - { LedId.Keyboard_X, AsusLedId.KEY_X }, - { LedId.Keyboard_C, AsusLedId.KEY_C }, - { LedId.Keyboard_V, AsusLedId.KEY_V }, - { LedId.Keyboard_B, AsusLedId.KEY_B }, - { LedId.Keyboard_N, AsusLedId.KEY_N }, - { LedId.Keyboard_M, AsusLedId.KEY_M }, - { LedId.Keyboard_CommaAndLessThan, AsusLedId.KEY_COMMA }, - { LedId.Keyboard_PeriodAndBiggerThan, AsusLedId.KEY_PERIOD }, - { LedId.Keyboard_SlashAndQuestionMark, AsusLedId.KEY_SLASH }, - { LedId.Keyboard_RightShift, AsusLedId.KEY_RSHIFT }, - { LedId.Keyboard_LeftCtrl, AsusLedId.KEY_LCONTROL }, - { LedId.Keyboard_LeftGui, AsusLedId.KEY_LWIN }, - { LedId.Keyboard_LeftAlt, AsusLedId.KEY_LMENU }, - { LedId.Keyboard_Space, AsusLedId.KEY_SPACE }, - { LedId.Keyboard_RightAlt, AsusLedId.KEY_RMENU }, - { LedId.Keyboard_RightGui, AsusLedId.KEY_RWIN }, - { LedId.Keyboard_Application, AsusLedId.KEY_APPS }, - { LedId.Keyboard_RightCtrl, AsusLedId.KEY_RCONTROL }, - { LedId.Keyboard_PrintScreen, AsusLedId.KEY_SYSRQ }, - { LedId.Keyboard_ScrollLock, AsusLedId.KEY_SCROLL }, - { LedId.Keyboard_PauseBreak, AsusLedId.KEY_PAUSE }, - { LedId.Keyboard_Insert, AsusLedId.KEY_INSERT }, - { LedId.Keyboard_Home, AsusLedId.KEY_HOME }, - { LedId.Keyboard_PageUp, AsusLedId.KEY_PRIOR }, - { LedId.Keyboard_Delete, AsusLedId.KEY_DELETE }, - { LedId.Keyboard_End, AsusLedId.KEY_END }, - { LedId.Keyboard_PageDown, AsusLedId.KEY_NEXT }, - { LedId.Keyboard_ArrowUp, AsusLedId.KEY_UP }, - { LedId.Keyboard_ArrowLeft, AsusLedId.KEY_LEFT }, - { LedId.Keyboard_ArrowDown, AsusLedId.KEY_DOWN }, - { LedId.Keyboard_ArrowRight, AsusLedId.KEY_RIGHT }, - { LedId.Keyboard_NumLock, AsusLedId.KEY_NUMLOCK }, - { LedId.Keyboard_NumSlash, AsusLedId.KEY_DIVIDE }, - { LedId.Keyboard_NumAsterisk, AsusLedId.KEY_MULTIPLY }, - { LedId.Keyboard_NumMinus, AsusLedId.KEY_SUBTRACT }, - { LedId.Keyboard_Num7, AsusLedId.KEY_NUMPAD7 }, - { LedId.Keyboard_Num8, AsusLedId.KEY_NUMPAD8 }, - { LedId.Keyboard_Num9, AsusLedId.KEY_NUMPAD9 }, - { LedId.Keyboard_NumPeriodAndDelete, AsusLedId.KEY_DECIMAL }, - { LedId.Keyboard_NumPlus, AsusLedId.KEY_ADD }, - { LedId.Keyboard_Num4, AsusLedId.KEY_NUMPAD4 }, - { LedId.Keyboard_Num5, AsusLedId.KEY_NUMPAD5 }, - { LedId.Keyboard_Num6, AsusLedId.KEY_NUMPAD6 }, - { LedId.Keyboard_Num1, AsusLedId.KEY_NUMPAD1 }, - { LedId.Keyboard_Num2, AsusLedId.KEY_NUMPAD2 }, - { LedId.Keyboard_Num3, AsusLedId.KEY_NUMPAD3 }, - { LedId.Keyboard_Num0, AsusLedId.KEY_NUMPAD0 }, - { LedId.Keyboard_NumEnter, AsusLedId.KEY_NUMPADENTER }, - { LedId.Keyboard_NonUsBackslash, AsusLedId.UNDOCUMENTED_1 }, - { LedId.Keyboard_NonUsTilde, AsusLedId.UNDOCUMENTED_2 }, - { LedId.Keyboard_NumComma, AsusLedId.KEY_NUMPADCOMMA }, - { LedId.Logo, AsusLedId.UNDOCUMENTED_3 }, - { LedId.Keyboard_Custom1, AsusLedId.UNDOCUMENTED_4 }, - { LedId.Keyboard_Custom2, AsusLedId.UNDOCUMENTED_5 }, - { LedId.Keyboard_Custom3, AsusLedId.KEY_F13 }, - { LedId.Keyboard_Custom4, AsusLedId.KEY_F14 }, - { LedId.Keyboard_Custom5, AsusLedId.KEY_F15 }, - { LedId.Keyboard_Custom6, AsusLedId.KEY_KANA }, - { LedId.Keyboard_Custom7, AsusLedId.KEY_ABNT_C1 }, - { LedId.Keyboard_Custom8, AsusLedId.KEY_CONVERT }, - { LedId.Keyboard_Custom9, AsusLedId.KEY_NOCONVERT }, - { LedId.Keyboard_Custom10, AsusLedId.KEY_YEN }, - { LedId.Keyboard_Custom11, AsusLedId.KEY_ABNT_C2 }, - { LedId.Keyboard_Custom12, AsusLedId.KEY_NUMPADEQUALS }, - { LedId.Keyboard_Custom13, AsusLedId.KEY_CIRCUMFLEX }, - { LedId.Keyboard_Custom14, AsusLedId.KEY_AT }, - { LedId.Keyboard_Custom15, AsusLedId.KEY_COLON }, - { LedId.Keyboard_Custom16, AsusLedId.KEY_UNDERLINE }, - { LedId.Keyboard_Custom17, AsusLedId.KEY_KANJI }, - { LedId.Keyboard_Custom18, AsusLedId.KEY_STOP }, - { LedId.Keyboard_Custom19, AsusLedId.KEY_AX }, - { LedId.Keyboard_Custom20, AsusLedId.KEY_UNLABELED }, - { LedId.Keyboard_Custom21, AsusLedId.KEY_NEXTTRACK }, - { LedId.Keyboard_Custom22, AsusLedId.KEY_CALCULATOR }, - { LedId.Keyboard_Custom23, AsusLedId.KEY_POWER }, - { LedId.Keyboard_Custom24, AsusLedId.KEY_SLEEP }, - { LedId.Keyboard_Custom25, AsusLedId.KEY_WAKE }, - { LedId.Keyboard_Custom26, AsusLedId.KEY_WEBSEARCH }, - { LedId.Keyboard_Custom27, AsusLedId.KEY_WEBFAVORITES }, - { LedId.Keyboard_Custom28, AsusLedId.KEY_WEBREFRESH }, - { LedId.Keyboard_Custom29, AsusLedId.KEY_WEBSTOP }, - { LedId.Keyboard_Custom30, AsusLedId.KEY_WEBFORWARD }, - { LedId.Keyboard_Custom31, AsusLedId.KEY_WEBHOME }, - { LedId.Keyboard_Custom32, AsusLedId.KEY_WEBBACK }, - { LedId.Keyboard_Custom33, AsusLedId.KEY_MYCOMPUTER }, - { LedId.Keyboard_Custom34, AsusLedId.KEY_MAIL }, - { LedId.Keyboard_Custom35, AsusLedId.KEY_MEDIASELECT }, - { LedId.Keyboard_Custom36, AsusLedId.KEY_FN }, - { LedId.Keyboard_MediaMute, AsusLedId.KEY_MUTE }, - { LedId.Keyboard_MediaPlay, AsusLedId.KEY_PLAYPAUSE }, - { LedId.Keyboard_MediaStop, AsusLedId.KEY_MEDIASTOP }, - { LedId.Keyboard_MediaVolumeDown, AsusLedId.KEY_VOLUMEDOWN }, - { LedId.Keyboard_MediaVolumeUp, AsusLedId.KEY_VOLUMEUP }, - }; - } -} + { LedId.Keyboard_Custom50, 39 }, // Mapping starts at Custom50 to avoid possible conflicts with KeyboardMapping above + { LedId.Keyboard_Custom51, 40 }, + { LedId.Keyboard_Custom52, 55 }, + { LedId.Keyboard_Custom53, 57 }, + { LedId.Keyboard_Custom54, 97 }, + { LedId.Keyboard_Custom55, 99 }, + { LedId.Keyboard_Custom56, 118 }, + { LedId.Keyboard_Custom57, 120 }, + { LedId.Keyboard_Custom58, 130 }, + { LedId.Keyboard_Custom59, 131 }, + { LedId.Keyboard_Custom60, 133 }, + }; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs index 7c444cf3..86f64aad 100644 --- a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDevice.cs @@ -1,67 +1,133 @@ using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using AuraServiceLib; using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// Represents custom LED data for ASUS keyboard LEDs. +/// +public record AsusKeyboardLedCustomData(AsusLedType LedType, int Id); + +/// +/// Represents a record containing regex that matches to an ASUS device model and a LED mapping mapping to Light indexes. +/// +public record AsusKeyboardExtraMapping(Regex Regex, LedMapping LedMapping); + +/// +/// +/// Represents a Asus keyboard. +/// +public class AsusKeyboardRGBDevice : AsusRGBDevice, IKeyboard { - /// + #region Properties & Fields + + private readonly LedMapping? _ledMapping; + private readonly Dictionary _ledAsusLed = new(); + private readonly Dictionary _ledAsusLights = new(); + + IKeyboardDeviceInfo IKeyboard.DeviceInfo => DeviceInfo; + /// - /// Represents a Asus keyboard. + /// Gets or sets a list of extra LED mappings to apply to modes that match the provided regex. + /// Note: These LED mappings should be based on light indexes. /// - public class AsusKeyboardRGBDevice : AsusRGBDevice, IKeyboard + // ReSharper disable once InconsistentNaming + public static readonly List ExtraLedMappings = new() + { + new AsusKeyboardExtraMapping(new Regex("(ROG Zephyrus Duo 15).*?"), LedMappings.ROGZephyrusDuo15) + }; + + #endregion + + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The specific information provided by Asus for the keyboard. + /// A mapping of leds this device is initialized with. + /// The update trigger used to update this device. + internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info, LedMapping? ledMapping, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors + this._ledMapping = ledMapping; - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the keyboard. - internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info) - : base(info) - { } + InitializeLayout(); + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void InitializeLayout() + private void InitializeLayout() + { + if (DeviceInfo.Device.Type != (uint)AsusDeviceType.NB_KB_4ZONE_RGB) { - Dictionary reversedMapping = AsusKeyboardLedMapping.MAPPING.ToDictionary(x => x.Value, x => x.Key); + int pos = 0; + int unknownLed = (int)LedId.Unknown1; - if (DeviceInfo.Device.Type != (uint)AsusDeviceType.NB_KB_4ZONE_RGB) + foreach (IAuraRgbKey key in ((IAuraSyncKeyboard)DeviceInfo.Device).Keys) { - int pos = 0; - foreach (IAuraRgbKey key in ((IAuraSyncKeyboard)DeviceInfo.Device).Keys) - InitializeLed(reversedMapping[(AsusLedId)key.Code], new Point(pos++ * 19, 0), new Size(19, 19)); - - //UK Layout - InitializeLed(reversedMapping[AsusLedId.KEY_OEM_102], new Point(pos++ * 19, 0), new Size(19, 19)); - - InitializeLed(reversedMapping[AsusLedId.UNDOCUMENTED_1], new Point(pos * 19, 0), new Size(19, 19)); + if ((_ledMapping != null) && _ledMapping.TryGetValue((AsusLedId)key.Code, out LedId ledId)) + AddAsusLed((AsusLedId)key.Code, ledId, new Point(pos++ * 19, 0), new Size(19, 19)); + else + { + AddAsusLed((AsusLedId)key.Code, (LedId)unknownLed, new Point(pos++ * 19, 0), new Size(19, 19)); + unknownLed++; + } } - else + + // Add extra LED mapping if required + AsusKeyboardExtraMapping? extraMapping = ExtraLedMappings.FirstOrDefault(m => m.Regex.IsMatch(this.DeviceInfo.Model)); + if (extraMapping != null) { - int ledCount = DeviceInfo.Device.Lights.Count; - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Keyboard_Custom1 + i, new Point(i * 19, 0), new Size(19, 19)); + foreach ((LedId ledId, int lightIndex) in extraMapping.LedMapping) + AddAsusLed(lightIndex, ledId, new Point(pos++ * 19, 0), new Size(19, 19)); } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\Asus\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), DeviceInfo.LogicalLayout.ToString()); } - - /// - protected override object CreateLedCustomData(LedId ledId) + else { - if (DeviceInfo.Device.Type == (uint)AsusDeviceType.NB_KB_4ZONE_RGB) - return ledId - LedId.Keyboard_Custom1; - - return AsusKeyboardLedMapping.MAPPING[ledId]; + int ledCount = DeviceInfo.Device.Lights.Count; + for (int i = 0; i < ledCount; i++) + AddLed(LedId.Keyboard_Custom1 + i, new Point(i * 19, 0), new Size(19, 19)); } + } + + /// + protected override object? GetLedCustomData(LedId ledId) + { + if (this._ledAsusLed.TryGetValue(ledId, out AsusLedId asusLedId)) + return new AsusKeyboardLedCustomData(AsusLedType.Key, (int)asusLedId); + if (this._ledAsusLights.TryGetValue(ledId, out int lightIndex)) + return new AsusKeyboardLedCustomData(AsusLedType.Light, lightIndex); + return null; + } + + /// + /// Add an ASUS LED by its LED ID + /// + private void AddAsusLed(AsusLedId asusLedId, LedId ledId, Point position, Size size) + { + if (this._ledAsusLed.TryGetValue(ledId, out AsusLedId firstAsusLed)) + throw new RGBDeviceException($"Got LED '{ledId}' twice, first ASUS LED '{firstAsusLed}' " + + $"second ASUS LED '{asusLedId}' on device '{DeviceInfo.DeviceName}'"); + + this._ledAsusLed.Add(ledId, asusLedId); + AddLed(ledId, position, size); + } - #endregion + /// + /// Add an ASUS LED by its light index + /// + private void AddAsusLed(int index, LedId ledId, Point position, Size size) + { + this._ledAsusLights.Add(ledId, index); + AddLed(ledId, position, size); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDeviceInfo.cs index 5b8a55ec..41732713 100644 --- a/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Asus/Keyboard/AsusKeyboardRGBDeviceInfo.cs @@ -1,59 +1,43 @@ -using System.Globalization; +using System.Collections.Generic; using AuraServiceLib; using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// Represents a generic information for a . +/// +public class AsusKeyboardRGBDeviceInfo : AsusRGBDeviceInfo, IKeyboardDeviceInfo { + #region Properties & Fields + + /// + /// The ASUS SDK returns useless names for notebook keyboards, possibly for others as well. + /// Keep a list of those and rely on to get the real model + /// + private static readonly List GENERIC_DEVICE_NAMES = new() { "NotebookKeyboard" }; + + /// + public KeyboardLayoutType Layout => KeyboardLayoutType.Unknown; + + #endregion + + #region Constructors + /// /// - /// Represents a generic information for a . + /// Internal constructor of managed . /// - public class AsusKeyboardRGBDeviceInfo : AsusRGBDeviceInfo - { - #region Properties & Fields - - /// - /// Gets the physical layout of the keyboard. - /// - public AsusPhysicalKeyboardLayout PhysicalLayout { get; private set; } - - /// - /// Gets the logical layout of the keyboard. - /// - public AsusLogicalKeyboardLayout LogicalLayout { get; private set; } - - #endregion - - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The backing this RGB.NET device. - /// The of the layout this keyboard is using. - internal AsusKeyboardRGBDeviceInfo(IAuraSyncDevice device, CultureInfo culture) - : base(RGBDeviceType.Keyboard, device, device.Name) - { - SetLayouts(culture.KeyboardLayoutId); - } - - #endregion - - #region Methods - - private void SetLayouts(int keyboardLayoutId) - { - switch (keyboardLayoutId) - { - //TODO DarthAffe 07.10.2017: Implement - default: - PhysicalLayout = AsusPhysicalKeyboardLayout.TODO; - LogicalLayout = AsusLogicalKeyboardLayout.TODO; - break; - } - } - - #endregion - } -} + /// The backing this RGB.NET device. + internal AsusKeyboardRGBDeviceInfo(IAuraSyncDevice device) + : base(RGBDeviceType.Keyboard, device, GetKeyboardModel(device.Name)) + { } + + #endregion + + #region Methods + + private static string? GetKeyboardModel(string deviceName) => GENERIC_DEVICE_NAMES.Contains(deviceName) ? WMIHelper.GetSystemModelInfo() : deviceName; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs b/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs index 2109aee8..2f92bb63 100644 --- a/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Mainboard/AsusMainboardRGBDevice.cs @@ -1,43 +1,40 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// +/// Represents a Asus mainboard. +/// +public class AsusMainboardRGBDevice : AsusRGBDevice, IMainboard { - /// + #region Constructors + + /// /// - /// Represents a Asus mainboard. + /// Initializes a new instance of the class. /// - public class AsusMainboardRGBDevice : AsusRGBDevice, IKeyboard + /// The specific information provided by Asus for the mainboard. + /// The update trigger used to update this device. + internal AsusMainboardRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the mainboard. - internal AsusMainboardRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } - - #endregion + InitializeLayout(); + } - #region Methods + #endregion - /// - protected override void InitializeLayout() - { - //TODO DarthAffe 07.10.2017: Look for a good default layout - int ledCount = DeviceInfo.Device.Lights.Count; - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Mainboard1 + i, new Rectangle(i * 40, 0, 40, 8)); + #region Methods - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Mainboards", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } + private void InitializeLayout() + { + int ledCount = DeviceInfo.Device.Lights.Count; + for (int i = 0; i < ledCount; i++) + AddLed(LedId.Mainboard1 + i, new Point(i * 40, 0), new Size(40, 8)); + } - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs b/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs index 030e5471..3db166ad 100644 --- a/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs +++ b/RGB.NET.Devices.Asus/Mouse/AsusMouseRGBDevice.cs @@ -1,42 +1,40 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Asus +namespace RGB.NET.Devices.Asus; + +/// +/// +/// Represents a Asus mouse. +/// +public class AsusMouseRGBDevice : AsusRGBDevice, IMouse { - /// + #region Constructors + + /// /// - /// Represents a Asus mouse. + /// Initializes a new instance of the class. /// - public class AsusMouseRGBDevice : AsusRGBDevice, IMouse + /// The specific information provided by Asus for the mouse. + /// The update trigger used to update this device. + internal AsusMouseRGBDevice(AsusRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the mouse. - internal AsusMouseRGBDevice(AsusRGBDeviceInfo info) - : base(info) - { } - - #endregion + InitializeLayout(); + } - #region Methods + #endregion - /// - protected override void InitializeLayout() - { - //TODO DarthAffe 07.10.2017: Look for a good default layout - int ledCount = DeviceInfo.Device.Lights.Count; - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Mouse1 + i, new Rectangle(i * 10, 0, 10, 10)); + #region Methods - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Mouses", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } + private void InitializeLayout() + { + int ledCount = DeviceInfo.Device.Lights.Count; + for (int i = 0; i < ledCount; i++) + AddLed(LedId.Mouse1 + i, new Point(i * 10, 0), new Size(10, 10)); + } - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Asus/README.md b/RGB.NET.Devices.Asus/README.md new file mode 100644 index 00000000..41abee01 --- /dev/null +++ b/RGB.NET.Devices.Asus/README.md @@ -0,0 +1,13 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for Asus-Devices. + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(AsusDeviceProvider.Instance); +``` + +# Required SDK +This providers requires the `Interop.AuraServiceLib.dll` to be present on the system. Normally this dll is installed with ASUS Aura and registered in the GAC. +There are some known issue with this dll missing and it's recommended to pack it with your application. You can get it from your Aura-Installation or get a copy from [https://redist.arge.be/Asus/Interop.AuraServiceLib.dll](https://redist.arge.be/Asus/Interop.AuraServiceLib.dll). +If packed it has to be located in a spot that your application is loading runtime dlls from. diff --git a/RGB.NET.Devices.Asus/RGB.NET.Devices.Asus.csproj b/RGB.NET.Devices.Asus/RGB.NET.Devices.Asus.csproj index fb26c954..b4ac280b 100644 --- a/RGB.NET.Devices.Asus/RGB.NET.Devices.Asus.csproj +++ b/RGB.NET.Devices.Asus/RGB.NET.Devices.Asus.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.Asus Asus-Device-Implementations of RGB.NET Asus-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,42 +35,42 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - <_PackageFiles Include="$(OutputPath)\net45\Interop.AuraServiceLib.dll"> + + + + + + + + + + <_PackageFiles Include="$(OutputPath)\net6.0\Interop.AuraServiceLib.dll"> None - lib\net45\ + lib\net6.0\ - <_PackageFiles Include="$(OutputPath)\netstandard2.0\Interop.AuraServiceLib.dll"> + <_PackageFiles Include="$(OutputPath)\net5.0\Interop.AuraServiceLib.dll"> None - lib\netstandard2.0\ + lib\net5.0\ @@ -76,11 +78,6 @@ - - - - - lib\Interop.AuraServiceLib.dll diff --git a/RGB.NET.Devices.Asus/RGB.NET.Devices.Asus.csproj.DotSettings b/RGB.NET.Devices.Asus/RGB.NET.Devices.Asus.csproj.DotSettings index 942f8869..e6bee89f 100644 --- a/RGB.NET.Devices.Asus/RGB.NET.Devices.Asus.csproj.DotSettings +++ b/RGB.NET.Devices.Asus/RGB.NET.Devices.Asus.csproj.DotSettings @@ -8,4 +8,5 @@ True True True - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Devices.Asus_Legacy/AsusDeviceProvider.cs b/RGB.NET.Devices.Asus_Legacy/AsusDeviceProvider.cs deleted file mode 100644 index 6dbae090..00000000 --- a/RGB.NET.Devices.Asus_Legacy/AsusDeviceProvider.cs +++ /dev/null @@ -1,280 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedMember.Global - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; -using System.Runtime.InteropServices; -using RGB.NET.Core; -using RGB.NET.Devices.Asus.Native; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a device provider responsible for Cooler Master devices. - /// - [Obsolete("Use this only if you need syncback-capability")] - public class AsusDeviceProvider : IRGBDeviceProvider - { - #region Properties & Fields - - private static AsusDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static AsusDeviceProvider Instance => _instance ?? new AsusDeviceProvider(); - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. - /// The first match will be used. - /// - public static List PossibleX86NativePaths { get; } = new List { "x86/AURA_SDK.dll" }; - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. - /// The first match will be used. - /// - public static List PossibleX64NativePaths { get; } = new List { }; - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _AsusSDK.LoadedArchitecture; - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; - - /// - /// The used to trigger the updates for asus devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public AsusDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(AsusDeviceProvider)}"); - _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); - } - - #endregion - - #region Methods - - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - IsInitialized = false; - - try - { - UpdateTrigger?.Stop(); - - _AsusSDK.Reload(); - - IList devices = new List(); - - #region Mainboard - - if (loadFilter.HasFlag(RGBDeviceType.Mainboard)) - try - { - //TODO DarthAffe 26.11.2017: This is not a fix! There might really be a second controller on the mainboard, but for now this should prevent the random crash for some guys. - // DarthAffe 26.11.2017: https://rog.asus.com/forum/showthread.php?97754-Access-Violation-Wrong-EnumerateMB-Result&p=688901#post688901 - int mainboardCount = Math.Min(1, _AsusSDK.EnumerateMbController(IntPtr.Zero, 0)); - if (mainboardCount > 0) - { - IntPtr mainboardHandles = Marshal.AllocHGlobal(mainboardCount * IntPtr.Size); - _AsusSDK.EnumerateMbController(mainboardHandles, mainboardCount); - - for (int i = 0; i < mainboardCount; i++) - { - try - { - IntPtr handle = Marshal.ReadIntPtr(mainboardHandles, i); - _AsusSDK.SetMbMode(handle, 1); - AsusMainboardRGBDevice device = new AsusMainboardRGBDevice(new AsusMainboardRGBDeviceInfo(RGBDeviceType.Mainboard, handle)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - } - } - } - catch { if (throwExceptions) throw; } - - #endregion - - #region Graphics cards - - //TODO DarthAffe 21.10.2017: This somehow returns non-existant gpus (at least for me) which cause huge lags (if a real asus-ready gpu is connected this doesn't happen) - - if (loadFilter.HasFlag(RGBDeviceType.GraphicsCard)) - try - { - int graphicCardCount = _AsusSDK.EnumerateGPU(IntPtr.Zero, 0); - if (graphicCardCount > 0) - { - IntPtr grapicsCardHandles = Marshal.AllocHGlobal(graphicCardCount * IntPtr.Size); - _AsusSDK.EnumerateGPU(grapicsCardHandles, graphicCardCount); - - for (int i = 0; i < graphicCardCount; i++) - { - try - { - IntPtr handle = Marshal.ReadIntPtr(grapicsCardHandles, i); - _AsusSDK.SetGPUMode(handle, 1); - AsusGraphicsCardRGBDevice device = new AsusGraphicsCardRGBDevice(new AsusGraphicsCardRGBDeviceInfo(RGBDeviceType.GraphicsCard, handle)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - } - } - } - catch { if (throwExceptions) throw; } - - #endregion - - #region DRAM - - //TODO DarthAffe 29.10.2017: I don't know why they are even documented, but the asus guy said they aren't in the SDK right now. - //try - //{ - //int dramCount = _AsusSDK.EnumerateDram(IntPtr.Zero, 0); - //if (dramCount > 0) - //{ - // IntPtr dramHandles = Marshal.AllocHGlobal(dramCount * IntPtr.Size); - // _AsusSDK.EnumerateDram(dramHandles, dramCount); - - // for (int i = 0; i < dramCount; i++) - // { - //try - //{ - // IntPtr handle = Marshal.ReadIntPtr(dramHandles, i); - // _AsusSDK.SetDramMode(handle, 1); - // AsusDramRGBDevice device = new AsusDramRGBDevice(new AsusDramRGBDeviceInfo(RGBDeviceType.DRAM, handle)); - // device.Initialize(UpdateTrigger); - // devices.Add(device); - // } - //catch { if (throwExceptions) throw; } - // } - //} - //} - // catch { if (throwExceptions) throw; } - - #endregion - - #region Keyboard - - if (loadFilter.HasFlag(RGBDeviceType.Keyboard)) - try - { - IntPtr keyboardHandle = Marshal.AllocHGlobal(IntPtr.Size); - if (_AsusSDK.CreateClaymoreKeyboard(keyboardHandle)) - { - _AsusSDK.SetClaymoreKeyboardMode(keyboardHandle, 1); - AsusKeyboardRGBDevice device = new AsusKeyboardRGBDevice(new AsusKeyboardRGBDeviceInfo(RGBDeviceType.Keyboard, keyboardHandle, GetCulture())); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - } - catch { if (throwExceptions) throw; } - - #endregion - - #region Mouse - - if (loadFilter.HasFlag(RGBDeviceType.Mouse)) - try - { - IntPtr mouseHandle = Marshal.AllocHGlobal(IntPtr.Size); - if (_AsusSDK.CreateRogMouse(mouseHandle)) - { - _AsusSDK.SetRogMouseMode(mouseHandle, 1); - AsusMouseRGBDevice device = new AsusMouseRGBDevice(new AsusMouseRGBDeviceInfo(RGBDeviceType.Mouse, mouseHandle)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - } - catch { if (throwExceptions) throw; } - - #endregion - - UpdateTrigger?.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) - throw; - return false; - } - - return true; - } - - /// - public void ResetDevices() - { - foreach (IRGBDevice device in Devices) - { - AsusRGBDeviceInfo deviceInfo = (AsusRGBDeviceInfo)device.DeviceInfo; - switch (deviceInfo.DeviceType) - { - case RGBDeviceType.Mainboard: - _AsusSDK.SetMbMode(deviceInfo.Handle, 0); - break; - case RGBDeviceType.GraphicsCard: - _AsusSDK.SetGPUMode(deviceInfo.Handle, 0); - break; - //case RGBDeviceType.DRAM: - // _AsusSDK.SetDramMode(deviceInfo.Handle, 0); - // break; - } - } - } - - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } - - try { _AsusSDK.UnloadAsusSDK(); } - catch { /* at least we tried */ } - } - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/AsusDeviceProviderLoader.cs b/RGB.NET.Devices.Asus_Legacy/AsusDeviceProviderLoader.cs deleted file mode 100644 index 576dfb51..00000000 --- a/RGB.NET.Devices.Asus_Legacy/AsusDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// Represents a device provider loaded used to dynamically load asus devices into an application. - /// - public class AsusDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => AsusDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Dram/AsusDramRGBDevice.cs b/RGB.NET.Devices.Asus_Legacy/Dram/AsusDramRGBDevice.cs deleted file mode 100644 index 6cdc398b..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Dram/AsusDramRGBDevice.cs +++ /dev/null @@ -1,56 +0,0 @@ -//using RGB.NET.Core; -//using RGB.NET.Devices.Asus.Native; - -//namespace RGB.NET.Devices.Asus -//{ -// /// -// /// -// /// Represents a Asus dram. -// /// -// public class AsusDramRGBDevice : AsusRGBDevice -// { -// #region Properties & Fields - -// /// -// /// Gets information about the . -// /// -// public AsusDramRGBDeviceInfo DramDeviceInfo { get; } - -// #endregion - -// #region Constructors - -// /// -// /// -// /// Initializes a new instance of the class. -// /// -// /// The specific information provided by Asus for the DRAM. -// internal AsusDramRGBDevice(AsusDramRGBDeviceInfo info) -// : base(info) -// { -// this.DramDeviceInfo = info; -// } - -// #endregion - -// #region Methods - -// /// -// protected override void InitializeLayout() -// { -// //TODO DarthAffe 21.10.2017: Look for a good default layout -// int ledCount = _AsusSDK.GetGPULedCount(DramDeviceInfo.Handle); -// for (int i = 0; i < ledCount; i++) -// InitializeLed(new AsusLedId(this, AsusLedIds.DramLed1 + i, i), new Rectangle(i * 10, 0, 10, 10)); - -// //TODO DarthAffe 21.10.2017: We don't know the model, how to save layouts and images? -// ApplyLayoutFromFile(PathHelper.GetAbsolutePath($@"Layouts\Asus\Drams\{DramDeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), -// null, PathHelper.GetAbsolutePath(@"Images\Asus\Drams")); -// } - -// /// -// protected override void ApplyColorData() => _AsusSDK.SetDramColor(DramDeviceInfo.Handle, ColorData); - -// #endregion -// } -//} diff --git a/RGB.NET.Devices.Asus_Legacy/Dram/AsusDramRGBDeviceInfo.cs b/RGB.NET.Devices.Asus_Legacy/Dram/AsusDramRGBDeviceInfo.cs deleted file mode 100644 index 9f92cac0..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Dram/AsusDramRGBDeviceInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a generic information for a . - /// - public class AsusDramRGBDeviceInfo : AsusRGBDeviceInfo - { - #region Properties & Fields - - /// - public override bool SupportsSyncBack => true; - - #endregion - - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The handle of the . - internal AsusDramRGBDeviceInfo(RGBDeviceType deviceType, IntPtr handle) - : base(deviceType, handle) - { } - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Enum/AsusLogicalKeyboardLayout.cs b/RGB.NET.Devices.Asus_Legacy/Enum/AsusLogicalKeyboardLayout.cs deleted file mode 100644 index 60105e50..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Enum/AsusLogicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Asus -{ - /// - /// Contains list of available logical layouts for asus keyboards. - /// - public enum AsusLogicalKeyboardLayout - { - TODO - }; -} diff --git a/RGB.NET.Devices.Asus_Legacy/Enum/AsusPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Asus_Legacy/Enum/AsusPhysicalKeyboardLayout.cs deleted file mode 100644 index b5e80de7..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Enum/AsusPhysicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable UnusedMember.Global -// ReSharper disable InconsistentNaming - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Asus -{ - /// - /// Contains list of available physical layouts for asus keyboards. - /// - public enum AsusPhysicalKeyboardLayout - { - TODO - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDevice.cs b/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDevice.cs deleted file mode 100644 index 011383bf..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDevice.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// - /// Represents a generic Asus-device. (keyboard, mouse, headset, mousepad). - /// - public abstract class AsusRGBDevice : AbstractRGBDevice, IAsusRGBDevice - where TDeviceInfo : AsusRGBDeviceInfo - { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected AsusUpdateQueue UpdateQueue { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by Asus for the device. - protected AsusRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - - UpdateQueue = new AsusUpdateQueue(updateTrigger); - UpdateQueue.Initialize(GetUpdateColorAction(), DeviceInfo.Handle, LedMapping.Count); - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); - - /// - /// Gets a action to update the physical device. - /// - /// - protected abstract Action GetUpdateColorAction(); - - /// - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - if ((DeviceInfo is AsusRGBDeviceInfo deviceInfo) && (deviceInfo.Handle != IntPtr.Zero)) - Marshal.FreeHGlobal(deviceInfo.Handle); - - base.Dispose(); - } - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDeviceInfo.cs b/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDeviceInfo.cs deleted file mode 100644 index 7c6ff693..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Generic/AsusRGBDeviceInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a generic information for a Corsair-. - /// - public abstract class AsusRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields - - /// - public RGBDeviceType DeviceType { get; } - - /// - public string DeviceName { get; } - - /// - public string Manufacturer { get; } - - /// - public string Model { get; } - - /// - public Uri Image { get; set; } - - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - - /// - public abstract bool SupportsSyncBack { get; } - - /// - /// Gets the index of the . - /// - internal IntPtr Handle { get; } - - #endregion - - #region Constructors - - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The handle of the . - /// The manufacturer-name of the . - /// The model-name of the . - internal AsusRGBDeviceInfo(RGBDeviceType deviceType, IntPtr handle, string model = "Generic Asus-Device", string manufacturer = "Asus") - { - this.DeviceType = deviceType; - this.Handle = handle; - this.Model = model; - this.Manufacturer = manufacturer; - - DeviceName = $"{Manufacturer} {Model}"; - } - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Generic/AsusUpdateQueue.cs b/RGB.NET.Devices.Asus_Legacy/Generic/AsusUpdateQueue.cs deleted file mode 100644 index 28fa9368..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Generic/AsusUpdateQueue.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents the update-queue performing updates for asus devices. - /// - public class AsusUpdateQueue : UpdateQueue - { - #region Properties & Fields - - /// - /// Gets or sets the internal color-data cache. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected byte[] ColorData { get; private set; } - - private Action _updateAction; - private IntPtr _handle; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - public AsusUpdateQueue(IDeviceUpdateTrigger updateTrigger) - : base(updateTrigger) - { } - - #endregion - - #region Methods - - /// - /// Initializes the queue. - /// - /// The update-action called by the queue to perform updates. - /// The handle of the device this queue performs updates for. - /// The amount of leds of the device this queue performs updates for. - public void Initialize(Action updateAction, IntPtr handle, int ledCount) - { - _updateAction = updateAction; - _handle = handle; - - ColorData = new byte[ledCount * 3]; - } - - /// - protected override void Update(Dictionary dataSet) - { - foreach (KeyValuePair data in dataSet) - { - int index = ((int)data.Key) * 3; - ColorData[index] = data.Value.GetR(); - ColorData[index + 1] = data.Value.GetB(); - ColorData[index + 2] = data.Value.GetG(); - } - - _updateAction(_handle, ColorData); - } - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Generic/IAsusRGBDevice.cs b/RGB.NET.Devices.Asus_Legacy/Generic/IAsusRGBDevice.cs deleted file mode 100644 index 720fd3cd..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Generic/IAsusRGBDevice.cs +++ /dev/null @@ -1,12 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// Represents a asus RGB-device. - /// - internal interface IAsusRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/GraphicsCard/AsusGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Asus_Legacy/GraphicsCard/AsusGraphicsCardRGBDevice.cs deleted file mode 100644 index 67a49889..00000000 --- a/RGB.NET.Devices.Asus_Legacy/GraphicsCard/AsusGraphicsCardRGBDevice.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using RGB.NET.Core; -using RGB.NET.Devices.Asus.Native; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a Asus graphicsCard. - /// - public class AsusGraphicsCardRGBDevice : AsusRGBDevice, IGraphicsCard - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the graphics card. - internal AsusGraphicsCardRGBDevice(AsusGraphicsCardRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - //TODO DarthAffe 07.10.2017: Look for a good default layout - int ledCount = _AsusSDK.GetGPULedCount(DeviceInfo.Handle); - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.GraphicsCard1 + i, new Rectangle(i * 10, 0, 10, 10)); - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\GraphicsCards", $"{ DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; - - /// - protected override Action GetUpdateColorAction() => _AsusSDK.SetGPUColor; - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/GraphicsCard/AsusGraphicsCardRGBDeviceInfo.cs b/RGB.NET.Devices.Asus_Legacy/GraphicsCard/AsusGraphicsCardRGBDeviceInfo.cs deleted file mode 100644 index ccf27c7c..00000000 --- a/RGB.NET.Devices.Asus_Legacy/GraphicsCard/AsusGraphicsCardRGBDeviceInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a generic information for a . - /// - public class AsusGraphicsCardRGBDeviceInfo : AsusRGBDeviceInfo - { - #region Properties & Fields - - /// - public override bool SupportsSyncBack => false; - - #endregion - - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The handle of the . - internal AsusGraphicsCardRGBDeviceInfo(RGBDeviceType deviceType, IntPtr handle) - : base(deviceType, handle, WMIHelper.GetGraphicsCardsInfo() ?? "Generic Asus-Device") - { } - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Helper/WMIHelper.cs b/RGB.NET.Devices.Asus_Legacy/Helper/WMIHelper.cs deleted file mode 100644 index 0ea746e6..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Helper/WMIHelper.cs +++ /dev/null @@ -1,63 +0,0 @@ -#if NETFULL -using System.Management; - -namespace RGB.NET.Devices.Asus -{ - // ReSharper disable once InconsistentNaming - internal static class WMIHelper - { - #region Properties & Fields - - private static ManagementObjectSearcher _mainboardSearcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT Manufacturer,Product FROM Win32_BaseBoard"); - private static ManagementObjectSearcher _graphicsCardSearcher = new ManagementObjectSearcher(@"root\CIMV2", "SELECT Name FROM Win32_VideoController"); - - private static (string manufacturer, string model)? _mainboardInfo; - private static string _graphicsCardInfo; - - #endregion - - #region Methods - - internal static (string manufacturer, string model)? GetMainboardInfo() - { - if (!_mainboardInfo.HasValue) - foreach (ManagementBaseObject managementBaseObject in _mainboardSearcher.Get()) - { - _mainboardInfo = (managementBaseObject["Manufacturer"]?.ToString(), managementBaseObject["Product"]?.ToString()); - break; - } - - return _mainboardInfo; - } - - internal static string GetGraphicsCardsInfo() - { - if (_graphicsCardInfo == null) - foreach (ManagementBaseObject managementBaseObject in _graphicsCardSearcher.Get()) - { - _graphicsCardInfo = managementBaseObject["Name"]?.ToString(); - break; - } - - return _graphicsCardInfo; - } - - #endregion - } -} -#else -namespace RGB.NET.Devices.Asus -{ - // ReSharper disable once InconsistentNaming - internal static class WMIHelper - { - #region Methods - - internal static (string manufacturer, string model)? GetMainboardInfo() => null; - - internal static string GetGraphicsCardsInfo() => null; - - #endregion - } -} -#endif diff --git a/RGB.NET.Devices.Asus_Legacy/Keyboard/AsusKeyboardRGBDevice.cs b/RGB.NET.Devices.Asus_Legacy/Keyboard/AsusKeyboardRGBDevice.cs deleted file mode 100644 index 8b72fb56..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Keyboard/AsusKeyboardRGBDevice.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using RGB.NET.Core; -using RGB.NET.Devices.Asus.Native; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a Asus keyboard. - /// - public class AsusKeyboardRGBDevice : AsusRGBDevice, IKeyboard - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the keyboard. - internal AsusKeyboardRGBDevice(AsusKeyboardRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - //TODO DarthAffe 07.10.2017: This doesn't make sense at all ... Find someone with such a keyboard! - int ledCount = _AsusSDK.GetClaymoreKeyboardLedCount(DeviceInfo.Handle); - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Keyboard_Escape + i, new Rectangle(i * 19, 0, 19, 19)); - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\Asus\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), DeviceInfo.LogicalLayout.ToString()); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keyboard_Escape; - - /// - protected override Action GetUpdateColorAction() => _AsusSDK.SetClaymoreKeyboardColor; - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Keyboard/AsusKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Asus_Legacy/Keyboard/AsusKeyboardRGBDeviceInfo.cs deleted file mode 100644 index db343c01..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Keyboard/AsusKeyboardRGBDeviceInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Globalization; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a generic information for a . - /// - public class AsusKeyboardRGBDeviceInfo : AsusRGBDeviceInfo - { - #region Properties & Fields - - /// - public override bool SupportsSyncBack => false; - - /// - /// Gets the physical layout of the keyboard. - /// - public AsusPhysicalKeyboardLayout PhysicalLayout { get; private set; } - - /// - /// Gets the logical layout of the keyboard. - /// - public AsusLogicalKeyboardLayout LogicalLayout { get; private set; } - - #endregion - - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The handle of the . - /// The of the layout this keyboard is using. - internal AsusKeyboardRGBDeviceInfo(RGBDeviceType deviceType, IntPtr handle, CultureInfo culture) - : base(deviceType, handle, "Claymore") - { - SetLayouts(culture.KeyboardLayoutId); - } - - #endregion - - #region Methods - - private void SetLayouts(int keyboardLayoutId) - { - switch (keyboardLayoutId) - { - //TODO DarthAffe 07.10.2017: Implement - default: - PhysicalLayout = AsusPhysicalKeyboardLayout.TODO; - LogicalLayout = AsusLogicalKeyboardLayout.TODO; - break; - } - } - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Mainboard/AsusMainboardRGBDevice.cs b/RGB.NET.Devices.Asus_Legacy/Mainboard/AsusMainboardRGBDevice.cs deleted file mode 100644 index 52035f00..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Mainboard/AsusMainboardRGBDevice.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using RGB.NET.Core; -using RGB.NET.Devices.Asus.Native; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a Asus mainboard. - /// - public class AsusMainboardRGBDevice : AsusRGBDevice, IMainboard - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the mainboard. - internal AsusMainboardRGBDevice(AsusMainboardRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - //TODO DarthAffe 07.10.2017: Look for a good default layout - int ledCount = _AsusSDK.GetMbLedCount(DeviceInfo.Handle); - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Mainboard1 + i, new Rectangle(i * 40, 0, 40, 8)); - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Mainboards", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; - - /// - public override void SyncBack() - { - byte[] colorData = _AsusSDK.GetMbColor(DeviceInfo.Handle); - for (int i = 0; i < LedMapping.Count; i++) - SetLedColorWithoutRequest(LedMapping[LedId.Mainboard1 + i], new Color(colorData[(i * 3)], colorData[(i * 3) + 2], colorData[(i * 3) + 1])); - } - - /// - protected override Action GetUpdateColorAction() => _AsusSDK.SetMbColor; - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Mainboard/AsusMainboardRGBDeviceInfo.cs b/RGB.NET.Devices.Asus_Legacy/Mainboard/AsusMainboardRGBDeviceInfo.cs deleted file mode 100644 index 172f55d4..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Mainboard/AsusMainboardRGBDeviceInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a generic information for a . - /// - public class AsusMainboardRGBDeviceInfo : AsusRGBDeviceInfo - { - #region Properties & Fields - - /// - public override bool SupportsSyncBack => true; - - #endregion - - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The handle of the . - internal AsusMainboardRGBDeviceInfo(RGBDeviceType deviceType, IntPtr handle) - : base(deviceType, handle, WMIHelper.GetMainboardInfo()?.model ?? "Generic Asus-Device") - { } - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Mouse/AsusMouseRGBDevice.cs b/RGB.NET.Devices.Asus_Legacy/Mouse/AsusMouseRGBDevice.cs deleted file mode 100644 index e238b0c2..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Mouse/AsusMouseRGBDevice.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using RGB.NET.Core; -using RGB.NET.Devices.Asus.Native; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a Asus mouse. - /// - public class AsusMouseRGBDevice : AsusRGBDevice, IMouse - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Asus for the mouse. - internal AsusMouseRGBDevice(AsusMouseRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - //TODO DarthAffe 07.10.2017: Look for a good default layout - int ledCount = _AsusSDK.GetRogMouseLedCount(DeviceInfo.Handle); - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.Mouse1 + i, new Rectangle(i * 10, 0, 10, 10)); - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Asus\Mouses", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; - - /// - protected override Action GetUpdateColorAction() => _AsusSDK.SetRogMouseColor; - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Mouse/AsusMouseRGBDeviceInfo.cs b/RGB.NET.Devices.Asus_Legacy/Mouse/AsusMouseRGBDeviceInfo.cs deleted file mode 100644 index ddb71353..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Mouse/AsusMouseRGBDeviceInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus -{ - /// - /// - /// Represents a generic information for a . - /// - public class AsusMouseRGBDeviceInfo : AsusRGBDeviceInfo - { - #region Properties & Fields - - /// - public override bool SupportsSyncBack => false; - - #endregion - - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The handle of the . - internal AsusMouseRGBDeviceInfo(RGBDeviceType deviceType, IntPtr handle) - : base(deviceType, handle, "Rog") - { } - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/Native/_AsusSDK.cs b/RGB.NET.Devices.Asus_Legacy/Native/_AsusSDK.cs deleted file mode 100644 index 437a3ea8..00000000 --- a/RGB.NET.Devices.Asus_Legacy/Native/_AsusSDK.cs +++ /dev/null @@ -1,341 +0,0 @@ -// ReSharper disable UnusedMethodReturnValue.Global -// ReSharper disable UnusedMember.Global - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; -using System.Security; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Asus.Native -{ - // ReSharper disable once InconsistentNaming - internal static class _AsusSDK - { - #region Libary Management - - private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - - /// - /// Reloads the SDK. - /// - internal static void Reload() - { - UnloadAsusSDK(); - LoadAsusSDK(); - } - - private static void LoadAsusSDK() - { - if (_dllHandle != IntPtr.Zero) return; - - // HACK: Load library at runtime to support both, x86 and x64 with one managed dll - List possiblePathList = Environment.Is64BitProcess ? AsusDeviceProvider.PossibleX64NativePaths : AsusDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); - if (dllPath == null) throw new RGBDeviceException($"Can't find the Asus-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - - SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))); - - _dllHandle = LoadLibrary(dllPath); - - _enumerateMbControllerPointer = (EnumerateMbControllerPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "EnumerateMbController"), typeof(EnumerateMbControllerPointer)); - _getMbLedCountPointer = (GetMbLedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetMbLedCount"), typeof(GetMbLedCountPointer)); - _setMbModePointer = (SetMbModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetMbMode"), typeof(SetMbModePointer)); - _setMbColorPointer = (SetMbColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetMbColor"), typeof(SetMbColorPointer)); - _getMbColorPointer = (GetMbColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetMbColor"), typeof(GetMbColorPointer)); - - _enumerateGPUPointer = (EnumerateGPUPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "EnumerateGPU"), typeof(EnumerateGPUPointer)); - _getGPULedCountPointer = (GetGPULedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetGPULedCount"), typeof(GetGPULedCountPointer)); - _setGPUModePointer = (SetGPUModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetGPUMode"), typeof(SetGPUModePointer)); - _setGPUColorPointer = (SetGPUColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetGPUColor"), typeof(SetGPUColorPointer)); - - _createClaymoreKeyboardPointer = (CreateClaymoreKeyboardPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateClaymoreKeyboard"), typeof(CreateClaymoreKeyboardPointer)); - _getClaymoreKeyboardLedCountPointer = (GetClaymoreKeyboardLedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetClaymoreKeyboardLedCount"), typeof(GetClaymoreKeyboardLedCountPointer)); - _setClaymoreKeyboardModePointer = (SetClaymoreKeyboardModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetClaymoreKeyboardMode"), typeof(SetClaymoreKeyboardModePointer)); - _setClaymoreKeyboardColorPointer = (SetClaymoreKeyboardColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetClaymoreKeyboardColor"), typeof(SetClaymoreKeyboardColorPointer)); - - _enumerateRogMousePointer = (CreateRogMousePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateRogMouse"), typeof(CreateRogMousePointer)); - _getRogMouseLedCountPointer = (GetRogMouseLedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "RogMouseLedCount"), typeof(GetRogMouseLedCountPointer)); // DarthAffe 07.10.2017: Be careful with the naming here - i don't know why but there is no 'Get'! - _setRogMouseModePointer = (SetRogMouseModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetRogMouseMode"), typeof(SetRogMouseModePointer)); - _setRogMouseColorPointer = (SetRogMouseColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetRogMouseColor"), typeof(SetRogMouseColorPointer)); - - //TODO DarthAffe 29.10.2017: I don't know why they are even documented, but the asus guy said they aren't in the SDK right now. - //_enumerateDramPointer = (EnumerateDramPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "EnumerateDram"), typeof(EnumerateDramPointer)); - //_getDramLedCountPointer = (GetDramLedCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetDramLedCount"), typeof(GetDramLedCountPointer)); - //_setDramModePointer = (SetDramModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetDramMode"), typeof(SetDramModePointer)); - //_setDramColorPointer = (SetDramColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetDramColor"), typeof(SetDramColorPointer)); - //_getDramColorPointer = (GetDramColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetDramColor"), typeof(GetDramColorPointer)); - } - - internal static void UnloadAsusSDK() - { - if (_dllHandle == IntPtr.Zero) return; - - // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 07.10.2017: We might need to reduce the internal reference counter more than once to set the library free - while (FreeLibrary(_dllHandle)) ; - _dllHandle = IntPtr.Zero; - } - - [DllImport("kernel32.dll")] - private static extern bool SetDllDirectory(string lpPathName); - - [DllImport("kernel32.dll")] - private static extern IntPtr LoadLibrary(string dllToLoad); - - [DllImport("kernel32.dll")] - private static extern bool FreeLibrary(IntPtr dllHandle); - - [DllImport("kernel32.dll")] - private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); - - #endregion - - #region SDK-METHODS - - #region Pointers - - private static EnumerateMbControllerPointer _enumerateMbControllerPointer; - private static GetMbLedCountPointer _getMbLedCountPointer; - private static SetMbModePointer _setMbModePointer; - private static SetMbColorPointer _setMbColorPointer; - private static GetMbColorPointer _getMbColorPointer; - - private static EnumerateGPUPointer _enumerateGPUPointer; - private static GetGPULedCountPointer _getGPULedCountPointer; - private static SetGPUModePointer _setGPUModePointer; - private static SetGPUColorPointer _setGPUColorPointer; - - private static CreateClaymoreKeyboardPointer _createClaymoreKeyboardPointer; - private static GetClaymoreKeyboardLedCountPointer _getClaymoreKeyboardLedCountPointer; - private static SetClaymoreKeyboardModePointer _setClaymoreKeyboardModePointer; - private static SetClaymoreKeyboardColorPointer _setClaymoreKeyboardColorPointer; - - private static CreateRogMousePointer _enumerateRogMousePointer; - private static GetRogMouseLedCountPointer _getRogMouseLedCountPointer; - private static SetRogMouseModePointer _setRogMouseModePointer; - private static SetRogMouseColorPointer _setRogMouseColorPointer; - - //private static EnumerateDramPointer _enumerateDramPointer; - //private static SetDramModePointer _setDramModePointer; - //private static GetDramLedCountPointer _getDramLedCountPointer; - //private static SetDramColorPointer _setDramColorPointer; - //private static GetDramColorPointer _getDramColorPointer; - - #endregion - - #region Delegates - - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate int EnumerateMbControllerPointer(IntPtr handles, int size); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate int GetMbLedCountPointer(IntPtr handle); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate void SetMbModePointer(IntPtr handle, int mode); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate void SetMbColorPointer(IntPtr handle, byte[] colors, int size); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate int GetMbColorPointer(IntPtr handle, IntPtr colors, int size); - - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate int EnumerateGPUPointer(IntPtr handles, int size); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate int GetGPULedCountPointer(IntPtr handle); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate void SetGPUModePointer(IntPtr handle, int mode); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate void SetGPUColorPointer(IntPtr handle, byte[] colors, int size); - - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate bool CreateClaymoreKeyboardPointer(IntPtr handle); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate int GetClaymoreKeyboardLedCountPointer(IntPtr handle); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate void SetClaymoreKeyboardModePointer(IntPtr handle, int mode); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate void SetClaymoreKeyboardColorPointer(IntPtr handle, byte[] colors, int size); - - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate bool CreateRogMousePointer(IntPtr handle); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate int GetRogMouseLedCountPointer(IntPtr handle); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate void SetRogMouseModePointer(IntPtr handle, int mode); - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - private delegate void SetRogMouseColorPointer(IntPtr handle, byte[] colors, int size); - - //[UnmanagedFunctionPointer(CallingConvention.StdCall)] - //private delegate int EnumerateDramPointer(IntPtr handles, int size); - //[UnmanagedFunctionPointer(CallingConvention.StdCall)] - //private delegate int GetDramLedCountPointer(IntPtr handle); - //[UnmanagedFunctionPointer(CallingConvention.StdCall)] - //private delegate void SetDramModePointer(IntPtr handle, int mode); - //[UnmanagedFunctionPointer(CallingConvention.StdCall)] - //private delegate void SetDramColorPointer(IntPtr handle, byte[] colors, int size); - //[UnmanagedFunctionPointer(CallingConvention.StdCall)] - //private delegate int GetDramColorPointer(IntPtr handle, IntPtr colors, int size); - - #endregion - - // ReSharper disable EventExceptionNotDocumented - - //HACK DarthAffe 12.05.2019: Using HandleProcessCorruptedStateExceptions and SecurityCritical allows to capture AccessViolationExceptions - // which is used here to prevent hard crashes on wrong pointers. - // Since this might cause isntabilities in the running application it's only a workaround and should be fixed in depth. - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static int EnumerateMbController(IntPtr handles, int size) - { - try { return _enumerateMbControllerPointer(handles, size); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static int GetMbLedCount(IntPtr handle) - { - try { return _getMbLedCountPointer(handle); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static void SetMbMode(IntPtr handle, int mode) - { - try { _setMbModePointer(handle, mode); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static void SetMbColor(IntPtr handle, byte[] colors) - { - try { _setMbColorPointer(handle, colors, colors.Length); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static byte[] GetMbColor(IntPtr handle) - { - int count = _getMbColorPointer(handle, IntPtr.Zero, 0); - byte[] colors = new byte[count]; - IntPtr readColorsPtr = Marshal.AllocHGlobal(colors.Length); - _getMbColorPointer(handle, readColorsPtr, colors.Length); - Marshal.Copy(readColorsPtr, colors, 0, colors.Length); - Marshal.FreeHGlobal(readColorsPtr); - return colors; - } - - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static int EnumerateGPU(IntPtr handles, int size) - { - try { return _enumerateGPUPointer(handles, size); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static int GetGPULedCount(IntPtr handle) - { - try { return _getGPULedCountPointer(handle); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static void SetGPUMode(IntPtr handle, int mode) - { - try { _setGPUModePointer(handle, mode); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static void SetGPUColor(IntPtr handle, byte[] colors) - { - try { _setGPUColorPointer(handle, colors, colors.Length); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static bool CreateClaymoreKeyboard(IntPtr handle) - { - try { return _createClaymoreKeyboardPointer(handle); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static int GetClaymoreKeyboardLedCount(IntPtr handle) - { - try { return _getClaymoreKeyboardLedCountPointer(handle); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static void SetClaymoreKeyboardMode(IntPtr handle, int mode) - { - try { _setClaymoreKeyboardModePointer(handle, mode); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static void SetClaymoreKeyboardColor(IntPtr handle, byte[] colors) - { - try { _setClaymoreKeyboardColorPointer(handle, colors, colors.Length); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static bool CreateRogMouse(IntPtr handle) - { - try { return _enumerateRogMousePointer(handle); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static int GetRogMouseLedCount(IntPtr handle) - { - try { return _getRogMouseLedCountPointer(handle); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static void SetRogMouseMode(IntPtr handle, int mode) - { - try { _setRogMouseModePointer(handle, mode); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - [SecurityCritical] - [HandleProcessCorruptedStateExceptions] - internal static void SetRogMouseColor(IntPtr handle, byte[] colors) - { - try { _setRogMouseColorPointer(handle, colors, colors.Length); } catch (Exception ex) { throw new RGBDeviceException(ex.Message); }; - } - - //internal static int EnumerateDram(IntPtr handles, int size) => _enumerateDramPointer(handles, size); - //internal static int GetDramLedCount(IntPtr handle) => _getDramLedCountPointer(handle); - //internal static void SetDramMode(IntPtr handle, int mode) => _setDramModePointer(handle, mode); - //internal static void SetDramColor(IntPtr handle, byte[] colors) => _setDramColorPointer(handle, colors, colors.Length); - - //internal static byte[] GetDramColor(IntPtr handle) - //{ - // int count = _getDramColorPointer(handle, IntPtr.Zero, 0); - // byte[] colors = new byte[count]; - // IntPtr readColorsPtr = Marshal.AllocHGlobal(colors.Length); - // _getDramColorPointer(handle, readColorsPtr, colors.Length); - // Marshal.Copy(readColorsPtr, colors, 0, colors.Length); - // Marshal.FreeHGlobal(readColorsPtr); - // return colors; - //} - - // ReSharper restore EventExceptionNotDocumented - - #endregion - } -} diff --git a/RGB.NET.Devices.Asus_Legacy/RGB.NET.Devices.Asus_Legacy.csproj b/RGB.NET.Devices.Asus_Legacy/RGB.NET.Devices.Asus_Legacy.csproj deleted file mode 100644 index dacc703b..00000000 --- a/RGB.NET.Devices.Asus_Legacy/RGB.NET.Devices.Asus_Legacy.csproj +++ /dev/null @@ -1,69 +0,0 @@ - - - netstandard2.0;net45 - win7-x86;win7-x64 - - Darth Affe - Wyrez - en-US - en-US - RGB.NET.Devices.Asus - RGB.NET.Devices.Asus_Legacy - RGB.NET.Devices.Asus - RGB.NET.Devices.Asus_Legacy - RGB.NET.Devices.Asus - Asus-Device-Implementations of RGB.NET based on the v2-SDK - Asus-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png - https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE - Github - https://github.com/DarthAffe/RGB.NET - True - - - - 0.0.1 - 0.0.1 - 0.0.1 - - ..\bin\ - true - True - True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL - - - - $(DefineConstants);TRACE;DEBUG - true - full - false - - - - pdbonly - true - $(NoWarn);CS1591;CS1572;CS1573 - $(DefineConstants);RELEASE - - - - - - - - - - - \ No newline at end of file diff --git a/RGB.NET.Devices.Asus_Legacy/RGB.NET.Devices.Asus_Legacy.csproj.DotSettings b/RGB.NET.Devices.Asus_Legacy/RGB.NET.Devices.Asus_Legacy.csproj.DotSettings deleted file mode 100644 index a88918e0..00000000 --- a/RGB.NET.Devices.Asus_Legacy/RGB.NET.Devices.Asus_Legacy.csproj.DotSettings +++ /dev/null @@ -1,10 +0,0 @@ - - True - True - True - True - True - True - True - True - True \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Attributes/DeviceTypeAttribute.cs b/RGB.NET.Devices.CoolerMaster/Attributes/DeviceTypeAttribute.cs index 768a80fb..8aad3001 100644 --- a/RGB.NET.Devices.CoolerMaster/Attributes/DeviceTypeAttribute.cs +++ b/RGB.NET.Devices.CoolerMaster/Attributes/DeviceTypeAttribute.cs @@ -1,36 +1,35 @@ using System; using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// +/// Specifies the of a field. +/// +[AttributeUsage(AttributeTargets.Field)] +public class DeviceTypeAttribute : Attribute { - /// + #region Properties & Fields + /// - /// Specifies the of a field. + /// Gets the . /// - [AttributeUsage(AttributeTargets.Field)] - public class DeviceTypeAttribute : Attribute - { - #region Properties & Fields - - /// - /// Gets the . - /// - public RGBDeviceType DeviceType { get; } - - #endregion + public RGBDeviceType DeviceType { get; } - #region Constructors + #endregion - /// - /// - /// Internal constructor of the class. - /// - /// The . - public DeviceTypeAttribute(RGBDeviceType deviceType) - { - this.DeviceType = deviceType; - } + #region Constructors - #endregion + /// + /// + /// Internal constructor of the class. + /// + /// The . + public DeviceTypeAttribute(RGBDeviceType deviceType) + { + this.DeviceType = deviceType; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs index 05546aab..280e5204 100644 --- a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs +++ b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProvider.cs @@ -3,198 +3,104 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; using RGB.NET.Core; using RGB.NET.Devices.CoolerMaster.Helper; using RGB.NET.Devices.CoolerMaster.Native; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// +/// Represents a device provider responsible for Cooler Master devices. +/// +public class CoolerMasterDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static CoolerMasterDeviceProvider? _instance; /// - /// Represents a device provider responsible for Cooler Master devices. + /// Gets the singleton instance. /// - public class CoolerMasterDeviceProvider : IRGBDeviceProvider - { - #region Properties & Fields - - private static CoolerMasterDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static CoolerMasterDeviceProvider Instance => _instance ?? new CoolerMasterDeviceProvider(); - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. - /// The first match will be used. - /// - public static List PossibleX86NativePaths { get; } = new List { "x86/CMSDK.dll" }; - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. - /// The first match will be used. - /// - public static List PossibleX64NativePaths { get; } = new List { "x64/CMSDK.dll" }; - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _CoolerMasterSDK.LoadedArchitecture; - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; - - /// - /// The used to trigger the updates for cooler master devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public CoolerMasterDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(CoolerMasterDeviceProvider)}"); - _instance = this; + public static CoolerMasterDeviceProvider Instance => _instance ?? new CoolerMasterDeviceProvider(); - UpdateTrigger = new DeviceUpdateTrigger(); - } + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. + /// The first match will be used. + /// + public static List PossibleX86NativePaths { get; } = new() { "x86/CMSDK.dll" }; - #endregion + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. + /// The first match will be used. + /// + public static List PossibleX64NativePaths { get; } = new() { "x64/CMSDK.dll" }; - #region Methods + #endregion - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - IsInitialized = false; + #region Constructors - try - { - UpdateTrigger?.Stop(); + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public CoolerMasterDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(CoolerMasterDeviceProvider)}"); + _instance = this; + } - _CoolerMasterSDK.Reload(); - if (_CoolerMasterSDK.GetSDKVersion() <= 0) return false; + #endregion - IList devices = new List(); + #region Methods - foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes))) - { - try - { - RGBDeviceType deviceType = index.GetDeviceType(); - if (deviceType == RGBDeviceType.None) continue; - - if (_CoolerMasterSDK.IsDevicePlugged(index)) - { - if (!loadFilter.HasFlag(deviceType)) continue; - - ICoolerMasterRGBDevice device; - switch (deviceType) - { - case RGBDeviceType.Keyboard: - CoolerMasterPhysicalKeyboardLayout physicalLayout = _CoolerMasterSDK.GetDeviceLayout(index); - device = new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, physicalLayout, GetCulture())); - break; - - case RGBDeviceType.Mouse: - device = new CoolerMasterMouseRGBDevice(new CoolerMasterMouseRGBDeviceInfo(index)); - break; - - default: - if (throwExceptions) - throw new RGBDeviceException("Unknown Device-Type"); - else - continue; - } - - if (!_CoolerMasterSDK.EnableLedControl(true, index)) - throw new RGBDeviceException("Failed to enable LED control for device " + index); - - device.Initialize(UpdateTrigger); - devices.Add(device); - } - } - catch { if (throwExceptions) throw; } - } + /// + protected override void InitializeSDK() + { + _CoolerMasterSDK.Reload(); + if (_CoolerMasterSDK.GetSDKVersion() <= 0) Throw(new RGBDeviceException("Failed to initialize CoolerMaster-SDK"), true); + } - UpdateTrigger?.Start(); + /// + protected override IEnumerable LoadDevices() + { + foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes))) + { + RGBDeviceType deviceType = index.GetDeviceType(); + if (deviceType == RGBDeviceType.None) continue; - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch + if (_CoolerMasterSDK.IsDevicePlugged(index)) { - if (throwExceptions) - throw; - return false; - } - - return true; - } - - /// - public void ResetDevices() - { - if (IsInitialized) - foreach (IRGBDevice device in Devices) + if (!_CoolerMasterSDK.EnableLedControl(true, index)) + Throw(new RGBDeviceException("Failed to enable LED control for device " + index)); + else { - try + switch (deviceType) { - CoolerMasterRGBDeviceInfo deviceInfo = (CoolerMasterRGBDeviceInfo)device.DeviceInfo; - _CoolerMasterSDK.EnableLedControl(false, deviceInfo.DeviceIndex); - _CoolerMasterSDK.EnableLedControl(true, deviceInfo.DeviceIndex); - } - catch {/* shit happens */} - } - } + case RGBDeviceType.Keyboard: + yield return new CoolerMasterKeyboardRGBDevice(new CoolerMasterKeyboardRGBDeviceInfo(index, _CoolerMasterSDK.GetDeviceLayout(index)), GetUpdateTrigger()); + break; - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } + case RGBDeviceType.Mouse: + yield return new CoolerMasterMouseRGBDevice(new CoolerMasterMouseRGBDeviceInfo(index), GetUpdateTrigger()); + break; - if (IsInitialized) - foreach (IRGBDevice device in Devices) - { - try - { - CoolerMasterRGBDeviceInfo deviceInfo = (CoolerMasterRGBDeviceInfo)device.DeviceInfo; - _CoolerMasterSDK.EnableLedControl(false, deviceInfo.DeviceIndex); + default: + Throw(new RGBDeviceException("Unknown Device-Type")); + break; } - catch {/* shit happens */} } - - // DarthAffe 03.03.2020: Should be done but isn't possible due to an weird winodws-hook inside the sdk which corrupts the stack when unloading the dll - //try { _CoolerMasterSDK.UnloadCMSDK(); } - //catch { /* at least we tried */ } + } } + } - #endregion + /// + public override void Dispose() + { + base.Dispose(); + + try { _CoolerMasterSDK.Reload(); } + catch { /* Unlucky.. */ } } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProviderLoader.cs b/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProviderLoader.cs deleted file mode 100644 index d8c0b9ef..00000000 --- a/RGB.NET.Devices.CoolerMaster/CoolerMasterDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.CoolerMaster -{ - /// - /// Represents a device provider loaded used to dynamically load cooler-master devices into an application. - /// - public class CoolerMasterDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => CoolerMasterDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterDevicesIndexes.cs b/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterDevicesIndexes.cs index 45d8ae2e..f528ccf3 100644 --- a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterDevicesIndexes.cs +++ b/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterDevicesIndexes.cs @@ -6,82 +6,97 @@ #pragma warning disable 1591 // Missing XML comment for publicly visible type or member -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// Contains a list of available device-indexes. +/// +public enum CoolerMasterDevicesIndexes { - /// - /// Contains a list of available device-indexes. - /// - public enum CoolerMasterDevicesIndexes - { - [Description("MasterKeys Pro L")] - [DeviceType(RGBDeviceType.Keyboard)] - MasterKeys_L = 0, - - [Description("MasterKeys ProS")] - [DeviceType(RGBDeviceType.Keyboard)] - MasterKeys_S = 1, - - [Description("MasterKeys Pro L White")] - [DeviceType(RGBDeviceType.Keyboard)] - MasterKeys_L_White = 2, - - [Description("MasterKeys Pro M White")] - [DeviceType(RGBDeviceType.Keyboard)] - MasterKeys_M_White = 3, - - [Description("MasterMouse Pro L")] - [DeviceType(RGBDeviceType.Mouse)] - MasterMouse_L = 4, - - [Description("MasterMouse S")] - [DeviceType(RGBDeviceType.Mouse)] - MasterMouse_S = 5, - - [Description("MasterKeys Pro M")] - [DeviceType(RGBDeviceType.Keyboard)] - MasterKeys_M = 6, - - [Description("MasterKeys Pro S White")] - [DeviceType(RGBDeviceType.Keyboard)] - MasterKeys_S_White = 7, - - [Description("MM520")] - [DeviceType(RGBDeviceType.Mouse)] - MM520 = 8, - - [Description("MM530")] - [DeviceType(RGBDeviceType.Mouse)] - MM530 = 9, - - [Description("MasterKeys MK750")] - [DeviceType(RGBDeviceType.Keyboard)] - MasterKeys_MK750 = 10, - - [Description("CK372")] - [DeviceType(RGBDeviceType.Keyboard)] - CK372 = 11, - - [Description("CK550")] - [DeviceType(RGBDeviceType.Keyboard)] - CK550 = 12, - - [Description("CK551")] - [DeviceType(RGBDeviceType.Keyboard)] - CK551 = 13, - - [Description("MM830")] - [DeviceType(RGBDeviceType.Mouse)] - MM830 = 14, - - [Description("CK530")] - [DeviceType(RGBDeviceType.Keyboard)] - CK530 = 15, - - [Description("MK850")] - [DeviceType(RGBDeviceType.Keyboard)] - MK850 = 16, - - [DeviceType(RGBDeviceType.None)] - Default = 0xFFFF - } -} + [Description("MasterKeys Pro L")] + [DeviceType(RGBDeviceType.Keyboard)] + MasterKeys_L = 0, + + [Description("MasterKeys ProS")] + [DeviceType(RGBDeviceType.Keyboard)] + MasterKeys_S = 1, + + [Description("MasterKeys Pro L White")] + [DeviceType(RGBDeviceType.Keyboard)] + MasterKeys_L_White = 2, + + [Description("MasterKeys Pro M White")] + [DeviceType(RGBDeviceType.Keyboard)] + MasterKeys_M_White = 3, + + [Description("MasterMouse Pro L")] + [DeviceType(RGBDeviceType.Mouse)] + MasterMouse_L = 4, + + [Description("MasterMouse S")] + [DeviceType(RGBDeviceType.Mouse)] + MasterMouse_S = 5, + + [Description("MasterKeys Pro M")] + [DeviceType(RGBDeviceType.Keyboard)] + MasterKeys_M = 6, + + [Description("MasterKeys Pro S White")] + [DeviceType(RGBDeviceType.Keyboard)] + MasterKeys_S_White = 7, + + [Description("MM520")] + [DeviceType(RGBDeviceType.Mouse)] + MM520 = 8, + + [Description("MM530")] + [DeviceType(RGBDeviceType.Mouse)] + MM530 = 9, + + [Description("MasterKeys MK750")] + [DeviceType(RGBDeviceType.Keyboard)] + MasterKeys_MK750 = 10, + + [Description("CK372")] + [DeviceType(RGBDeviceType.Keyboard)] + CK372 = 11, + + [Description("CK550")] + [DeviceType(RGBDeviceType.Keyboard)] + CK550 = 12, + + [Description("CK551")] + [DeviceType(RGBDeviceType.Keyboard)] + CK551 = 13, + + [Description("MM830")] + [DeviceType(RGBDeviceType.Mouse)] + MM830 = 14, + + [Description("CK530")] + [DeviceType(RGBDeviceType.Keyboard)] + CK530 = 15, + + [Description("MK850")] + [DeviceType(RGBDeviceType.Keyboard)] + MK850 = 16, + + [Description("SK630")] + [DeviceType(RGBDeviceType.Keyboard)] + SK630 = 17, + + [Description("SK650")] + [DeviceType(RGBDeviceType.Keyboard)] + SK650 = 18, + + [Description("SK621")] + [DeviceType(RGBDeviceType.Keyboard)] + SK621 = 19, + + [Description("MK730")] + [DeviceType(RGBDeviceType.Keyboard)] + MK730 = 20, + + [DeviceType(RGBDeviceType.None)] + Default = 0xFFFF +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterEffects.cs b/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterEffects.cs index c751657b..b9fcaa1c 100644 --- a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterEffects.cs +++ b/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterEffects.cs @@ -3,39 +3,38 @@ #pragma warning disable 1591 // Missing XML comment for publicly visible type or member -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// Contains a list of available effects. +/// +public enum CoolerMasterEffects { - /// - /// Contains a list of available effects. - /// - public enum CoolerMasterEffects - { - FullOn = 0, - Breath = 1, - BreathCycle = 2, - Single = 3, - Wave = 4, - Ripple = 5, - Cross = 6, - Rain = 7, - Star = 8, - Snake = 9, - Rec = 10, + FullOn = 0, + Breath = 1, + BreathCycle = 2, + Single = 3, + Wave = 4, + Ripple = 5, + Cross = 6, + Rain = 7, + Star = 8, + Snake = 9, + Rec = 10, - Spectrum = 11, - RapidFire = 12, - Indicator = 13, //mouse Effect - FireBall = 14, - WaterRipple = 15, - ReactivePunch = 16, - Snowing = 17, - HeartBeat = 18, - ReactiveTornade = 19, + Spectrum = 11, + RapidFire = 12, + Indicator = 13, //mouse Effect + FireBall = 14, + WaterRipple = 15, + ReactivePunch = 16, + Snowing = 17, + HeartBeat = 18, + ReactiveTornade = 19, - Multi1 = 0xE0, - Multi2 = 0xE1, - Multi3 = 0xE2, - Multi4 = 0xE3, - Off = 0xFE - } -} + Multi1 = 0xE0, + Multi2 = 0xE1, + Multi3 = 0xE2, + Multi4 = 0xE3, + Off = 0xFE +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterLogicalKeyboardLayout.cs b/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterLogicalKeyboardLayout.cs deleted file mode 100644 index c41ac931..00000000 --- a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterLogicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.CoolerMaster -{ - /// - /// Contains list of available logical layouts for cooler master keyboards. - /// - public enum CoolerMasterLogicalKeyboardLayout - { - DE - }; -} diff --git a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterPhysicalKeyboardLayout.cs b/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterPhysicalKeyboardLayout.cs index e89294b1..8cf90d2c 100644 --- a/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterPhysicalKeyboardLayout.cs +++ b/RGB.NET.Devices.CoolerMaster/Enum/CoolerMasterPhysicalKeyboardLayout.cs @@ -3,16 +3,15 @@ #pragma warning disable 1591 // Missing XML comment for publicly visible type or member -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// Contains list of available physical layouts for cooler master keyboards. +/// +public enum CoolerMasterPhysicalKeyboardLayout { - /// - /// Contains list of available physical layouts for cooler master keyboards. - /// - public enum CoolerMasterPhysicalKeyboardLayout - { - UNINIT = 0, - US = 1, - EU = 2, - JP = 3 - } -} + UNINIT = 0, + US = 1, + EU = 2, + JP = 3 +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs index d33351fc..b44a90c8 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDevice.cs @@ -1,87 +1,39 @@ using System; -using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.CoolerMaster.Native; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// +/// Represents a generic CoolerMaster-device. (keyboard, mouse, headset, mousepad). +/// +public abstract class CoolerMasterRGBDevice : AbstractRGBDevice, ICoolerMasterRGBDevice + where TDeviceInfo : CoolerMasterRGBDeviceInfo { - /// - /// + #region Constructors + /// - /// Represents a generic CoolerMaster-device. (keyboard, mouse, headset, mousepad). + /// Initializes a new instance of the class. /// - public abstract class CoolerMasterRGBDevice : AbstractRGBDevice, ICoolerMasterRGBDevice - where TDeviceInfo : CoolerMasterRGBDeviceInfo - { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected CoolerMasterUpdateQueue UpdateQueue { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by CoolerMaster for the device. - protected CoolerMasterRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion + /// The generic information provided by CoolerMaster for the device. + /// The update trigger used to update this device. + protected CoolerMasterRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new CoolerMasterUpdateQueue(updateTrigger, info.DeviceIndex)) + { } - #region Methods + #endregion + #region Methods - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - - UpdateQueue = new CoolerMasterUpdateQueue(updateTrigger, DeviceInfo.DeviceIndex); - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); - - /// - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - _CoolerMasterSDK.EnableLedControl(false, DeviceInfo.DeviceIndex); - - base.Dispose(); - } + /// + /// + public override void Dispose() + { + _CoolerMasterSDK.EnableLedControl(false, DeviceInfo.DeviceIndex); - #endregion + base.Dispose(); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDeviceInfo.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDeviceInfo.cs index d10eb012..58aae327 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDeviceInfo.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterRGBDeviceInfo.cs @@ -1,61 +1,53 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.CoolerMaster.Helper; -namespace RGB.NET.Devices.CoolerMaster -{ - /// - /// - /// Represents a generic information for a Corsair-. - /// - public class CoolerMasterRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Devices.CoolerMaster; - /// - public RGBDeviceType DeviceType { get; } - - /// - public string DeviceName { get; } - - /// - public string Manufacturer => "Cooler Master"; +/// +/// +/// Represents a generic information for a Corsair-. +/// +public class CoolerMasterRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public string Model { get; } + /// + public RGBDeviceType DeviceType { get; } - /// - public Uri Image { get; set; } + /// + public string DeviceName { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public string Manufacturer => "Cooler Master"; - /// - public bool SupportsSyncBack => false; + /// + public string Model { get; } - /// - /// Gets the of the . - /// - public CoolerMasterDevicesIndexes DeviceIndex { get; } + /// + public object? LayoutMetadata { get; set; } - #endregion + /// + /// Gets the of the . + /// + public CoolerMasterDevicesIndexes DeviceIndex { get; } - #region Constructors + #endregion - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The of the . - internal CoolerMasterRGBDeviceInfo(RGBDeviceType deviceType, CoolerMasterDevicesIndexes deviceIndex) - { - this.DeviceType = deviceType; - this.DeviceIndex = deviceIndex; + #region Constructors - Model = deviceIndex.GetDescription(); - DeviceName = $"{Manufacturer} {Model}"; - } + /// + /// Internal constructor of managed . + /// + /// The type of the . + /// The of the . + internal CoolerMasterRGBDeviceInfo(RGBDeviceType deviceType, CoolerMasterDevicesIndexes deviceIndex) + { + this.DeviceType = deviceType; + this.DeviceIndex = deviceIndex; - #endregion + Model = deviceIndex.GetDescription(); + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs index 21b26ce9..6631eb1b 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/CoolerMasterUpdateQueue.cs @@ -1,54 +1,52 @@ -using System.Collections.Generic; +using System; using RGB.NET.Core; using RGB.NET.Devices.CoolerMaster.Native; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// +/// Represents the update-queue performing updates for cooler master devices. +/// +public class CoolerMasterUpdateQueue : UpdateQueue { - /// - /// - /// Represents the update-queue performing updates for cooler master devices. - /// - public class CoolerMasterUpdateQueue : UpdateQueue - { - #region Properties & Fields + #region Properties & Fields - private CoolerMasterDevicesIndexes _deviceIndex; - private readonly _CoolerMasterColorMatrix _deviceMatrix; + private readonly CoolerMasterDevicesIndexes _deviceIndex; + private readonly _CoolerMasterColorMatrix _deviceMatrix; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The of the device this queue performs updates for. - public CoolerMasterUpdateQueue(IDeviceUpdateTrigger updateTrigger, CoolerMasterDevicesIndexes deviceIndex) - : base(updateTrigger) - { - this._deviceIndex = deviceIndex; - - _deviceMatrix = new _CoolerMasterColorMatrix(); - _deviceMatrix.KeyColor = new _CoolerMasterKeyColor[_CoolerMasterColorMatrix.ROWS, _CoolerMasterColorMatrix.COLUMNS]; - } + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The of the device this queue performs updates for. + public CoolerMasterUpdateQueue(IDeviceUpdateTrigger updateTrigger, CoolerMasterDevicesIndexes deviceIndex) + : base(updateTrigger) + { + this._deviceIndex = deviceIndex; - #endregion + _deviceMatrix = new _CoolerMasterColorMatrix { KeyColor = new _CoolerMasterKeyColor[_CoolerMasterColorMatrix.ROWS, _CoolerMasterColorMatrix.COLUMNS] }; + } - #region Methods + #endregion - /// - protected override void Update(Dictionary dataSet) - { - foreach (KeyValuePair data in dataSet) - { - (int row, int column) = ((int, int))data.Key; - _deviceMatrix.KeyColor[row, column] = new _CoolerMasterKeyColor(data.Value.GetR(), data.Value.GetG(), data.Value.GetB()); - } + #region Methods - _CoolerMasterSDK.SetAllLedColor(_deviceMatrix, _deviceIndex); + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + foreach ((object key, Color color) in dataSet) + { + (int row, int column) = ((int, int))key; + _deviceMatrix.KeyColor[row, column] = new _CoolerMasterKeyColor(color.GetR(), color.GetG(), color.GetB()); } - #endregion + _CoolerMasterSDK.SetAllLedColor(_deviceMatrix, _deviceIndex); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs index 8483843e..5cf66bba 100644 --- a/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Generic/ICoolerMasterRGBDevice.cs @@ -1,12 +1,9 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster -{ - /// - /// Represents a CoolerMaster RGB-device. - /// - internal interface ICoolerMasterRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } -} +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// Represents a CoolerMaster RGB-device. +/// +public interface ICoolerMasterRGBDevice : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Helper/EnumExtension.cs b/RGB.NET.Devices.CoolerMaster/Helper/EnumExtension.cs index 9ebd4277..eb6d4c3b 100644 --- a/RGB.NET.Devices.CoolerMaster/Helper/EnumExtension.cs +++ b/RGB.NET.Devices.CoolerMaster/Helper/EnumExtension.cs @@ -3,51 +3,41 @@ using System.Reflection; using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster.Helper +namespace RGB.NET.Devices.CoolerMaster.Helper; + +/// +/// Offers some extensions and helper-methods for enum related things. +/// +internal static class EnumExtension { /// - /// Offers some extensions and helper-methods for enum related things. + /// Gets the value of the . /// - internal static class EnumExtension - { - /// - /// Gets the value of the . - /// - /// The enum value to get the description from. - /// The generic enum-type - /// The value of the or the result of the source. - internal static string GetDescription(this T source) - where T : struct - { - return source.GetAttribute()?.Description ?? source.ToString(); - } + /// The enum value to get the description from. + /// The value of the or the result of the source. + internal static string GetDescription(this Enum source) + => source.GetAttribute()?.Description ?? source.ToString(); - /// - /// Gets the value of the . - /// - /// The enum value to get the description from. - /// The generic enum-type - /// The value of the or the result of the source. - internal static RGBDeviceType GetDeviceType(this T source) - where T : struct - { - return source.GetAttribute()?.DeviceType ?? RGBDeviceType.Unknown; - } + /// + /// Gets the value of the . + /// + /// The enum value to get the description from. + /// The value of the or the result of the source. + internal static RGBDeviceType GetDeviceType(this Enum source) + => source.GetAttribute()?.DeviceType ?? RGBDeviceType.Unknown; - /// - /// Gets the attribute of type T. - /// - /// The enum value to get the attribute from - /// The generic attribute type - /// The generic enum-type - /// The . - private static T GetAttribute(this TEnum source) - where T : Attribute - where TEnum : struct - { - FieldInfo fi = source.GetType().GetField(source.ToString()); - T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); - return attributes.Length > 0 ? attributes[0] : null; - } + /// + /// Gets the attribute of type T. + /// + /// The enum value to get the attribute from + /// The generic attribute type + /// The . + private static T? GetAttribute(this Enum source) + where T : Attribute + { + FieldInfo? fi = source.GetType().GetField(source.ToString()); + if (fi == null) return null; + T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); + return attributes.Length > 0 ? attributes[0] : null; } -} +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardLedMappings.cs b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardLedMappings.cs index 57548f17..6b5d831b 100644 --- a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardLedMappings.cs +++ b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardLedMappings.cs @@ -3,1530 +3,3752 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// Contains all the hardware-id mappings for CoolerMaster devices. +/// +internal static class CoolerMasterKeyboardLedMappings { + #region Properties & Fields + + #region MasterKeysL + + private static readonly Dictionary MasterKeysL_US = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + { LedId.Keyboard_Programmable1, (0,18) }, + { LedId.Keyboard_Programmable2, (0,19) }, + { LedId.Keyboard_Programmable3, (0,20) }, + { LedId.Keyboard_Programmable4, (0,21) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + { LedId.Keyboard_NumLock, (1,18) }, + { LedId.Keyboard_NumSlash, (1,19) }, + { LedId.Keyboard_NumAsterisk, (1,20) }, + { LedId.Keyboard_NumMinus, (1,21) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + { LedId.Keyboard_Num7, (2,18) }, + { LedId.Keyboard_Num8, (2,19) }, + { LedId.Keyboard_Num9, (2,20) }, + { LedId.Keyboard_NumPlus, (2,21) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_Enter, (3,14) }, + { LedId.Keyboard_Num4, (3,18) }, + { LedId.Keyboard_Num5, (3,19) }, + { LedId.Keyboard_Num6, (3,20) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + { LedId.Keyboard_Num1, (4,18) }, + { LedId.Keyboard_Num2, (4,19) }, + { LedId.Keyboard_Num3, (4,20) }, + { LedId.Keyboard_NumEnter, (4,21) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,20) } + }; + + private static readonly Dictionary MasterKeysL_EU = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + { LedId.Keyboard_Programmable1, (0,18) }, + { LedId.Keyboard_Programmable2, (0,19) }, + { LedId.Keyboard_Programmable3, (0,20) }, + { LedId.Keyboard_Programmable4, (0,21) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + { LedId.Keyboard_NumLock, (1,18) }, + { LedId.Keyboard_NumSlash, (1,19) }, + { LedId.Keyboard_NumAsterisk, (1,20) }, + { LedId.Keyboard_NumMinus, (1,21) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Enter, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + { LedId.Keyboard_Num7, (2,18) }, + { LedId.Keyboard_Num8, (2,19) }, + { LedId.Keyboard_Num9, (2,20) }, + { LedId.Keyboard_NumPlus, (2,21) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_NonUsTilde, (3,12) }, + { LedId.Keyboard_Num4, (3,18) }, + { LedId.Keyboard_Num5, (3,19) }, + { LedId.Keyboard_Num6, (3,20) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_NonUsBackslash, (4,1) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + { LedId.Keyboard_Num1, (4,18) }, + { LedId.Keyboard_Num2, (4,19) }, + { LedId.Keyboard_Num3, (4,20) }, + { LedId.Keyboard_NumEnter, (4,21) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,20) } + }; + + #endregion + + #region MasterKeysM + + private static readonly Dictionary MasterKeysM_US = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_NumLock, (1,15) }, + { LedId.Keyboard_NumSlash, (1,16) }, + { LedId.Keyboard_NumAsterisk, (1,17) }, + { LedId.Keyboard_NumMinus, (1,18) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,14) }, + { LedId.Keyboard_Num7, (2,15) }, + { LedId.Keyboard_Num8, (2,16) }, + { LedId.Keyboard_Num9, (2,17) }, + { LedId.Keyboard_NumPlus, (2,18) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_Enter, (3,14) }, + { LedId.Keyboard_Num4, (3,15) }, + { LedId.Keyboard_Num5, (3,16) }, + { LedId.Keyboard_Num6, (3,17) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_Num1, (4,15) }, + { LedId.Keyboard_Num2, (4,16) }, + { LedId.Keyboard_Num3, (4,17) }, + { LedId.Keyboard_NumEnter, (4,18) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_Num0, (5,15) }, + { LedId.Keyboard_Num00, (5,16) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,17) } + }; + + private static readonly Dictionary MasterKeysM_EU = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_NumLock, (1,15) }, + { LedId.Keyboard_NumSlash, (1,16) }, + { LedId.Keyboard_NumAsterisk, (1,17) }, + { LedId.Keyboard_NumMinus, (1,18) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,14) }, + { LedId.Keyboard_Num7, (2,15) }, + { LedId.Keyboard_Num8, (2,16) }, + { LedId.Keyboard_Num9, (2,17) }, + { LedId.Keyboard_NumPlus, (2,18) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_NonUsTilde, (3,12) }, + { LedId.Keyboard_Num4, (3,15) }, + { LedId.Keyboard_Num5, (3,16) }, + { LedId.Keyboard_Num6, (3,17) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_NonUsBackslash, (4,1) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_Num1, (4,15) }, + { LedId.Keyboard_Num2, (4,16) }, + { LedId.Keyboard_Num3, (4,17) }, + { LedId.Keyboard_NumEnter, (4,18) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_Num0, (5,15) }, + { LedId.Keyboard_Num00, (5,16) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,17) } + }; + + #endregion + + #region MasterKeysS + + private static readonly Dictionary MasterKeysS_US = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_Enter, (3,14) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) } + }; + + private static readonly Dictionary MasterKeysS_EU = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Enter, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_NonUsTilde, (3,12) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_NonUsBackslash, (4,1) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) } + }; + + #endregion + + #region MasterKeysMK750 + + private static readonly Dictionary MasterKeysMK750_US = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + { LedId.Keyboard_Programmable1, (0,18) }, + { LedId.Keyboard_Programmable2, (0,19) }, + { LedId.Keyboard_Programmable3, (0,20) }, + { LedId.Keyboard_Programmable4, (0,21) }, + { LedId.Keyboard_Custom1, (0,22) }, + { LedId.Keyboard_Custom23, (0,23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + { LedId.Keyboard_NumLock, (1,18) }, + { LedId.Keyboard_NumSlash, (1,19) }, + { LedId.Keyboard_NumAsterisk, (1,20) }, + { LedId.Keyboard_NumMinus, (1,21) }, + { LedId.Keyboard_Custom2, (1,22) }, + { LedId.Keyboard_Custom24, (1,23) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + { LedId.Keyboard_Num7, (2,18) }, + { LedId.Keyboard_Num8, (2,19) }, + { LedId.Keyboard_Num9, (2,20) }, + { LedId.Keyboard_NumPlus, (2,21) }, + { LedId.Keyboard_Custom3, (2,22) }, + { LedId.Keyboard_Custom25, (2,23) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_Enter, (3,14) }, + { LedId.Keyboard_Num4, (3,18) }, + { LedId.Keyboard_Num5, (3,19) }, + { LedId.Keyboard_Num6, (3,20) }, + { LedId.Keyboard_Custom4, (3,22) }, + { LedId.Keyboard_Custom26, (3,23) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + { LedId.Keyboard_Num1, (4,18) }, + { LedId.Keyboard_Num2, (4,19) }, + { LedId.Keyboard_Num3, (4,20) }, + { LedId.Keyboard_NumEnter, (4,21) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,20) }, + + { LedId.Keyboard_Custom5, (6,0) }, + { LedId.Keyboard_Custom6, (6,1) }, + { LedId.Keyboard_Custom7, (6,2) }, + { LedId.Keyboard_Custom8, (6,3) }, + { LedId.Keyboard_Custom9, (6,4) }, + { LedId.Keyboard_Custom10, (6,5) }, + { LedId.Keyboard_Custom11, (6,6) }, + { LedId.Keyboard_Custom12, (6,7) }, + { LedId.Keyboard_Custom13, (6,8) }, + { LedId.Keyboard_Custom14, (6,9) }, + { LedId.Keyboard_Custom15, (6,10) }, + { LedId.Keyboard_Custom16, (6,11) }, + { LedId.Keyboard_Custom17, (6,12) }, + { LedId.Keyboard_Custom18, (6,13) }, + { LedId.Keyboard_Custom19, (6,14) }, + { LedId.Keyboard_Custom20, (6,15) }, + { LedId.Keyboard_Custom21, (6,16) }, + { LedId.Keyboard_Custom22, (6,17) }, + }; + + private static readonly Dictionary MasterKeysMK750_EU = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + { LedId.Keyboard_Programmable1, (0,18) }, + { LedId.Keyboard_Programmable2, (0,19) }, + { LedId.Keyboard_Programmable3, (0,20) }, + { LedId.Keyboard_Programmable4, (0,21) }, + { LedId.Keyboard_Custom1, (0,22) }, + { LedId.Keyboard_Custom23, (0,23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + { LedId.Keyboard_NumLock, (1,18) }, + { LedId.Keyboard_NumSlash, (1,19) }, + { LedId.Keyboard_NumAsterisk, (1,20) }, + { LedId.Keyboard_NumMinus, (1,21) }, + { LedId.Keyboard_Custom2, (1,22) }, + { LedId.Keyboard_Custom24, (1,23) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Enter, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + { LedId.Keyboard_Num7, (2,18) }, + { LedId.Keyboard_Num8, (2,19) }, + { LedId.Keyboard_Num9, (2,20) }, + { LedId.Keyboard_NumPlus, (2,21) }, + { LedId.Keyboard_Custom3, (2,22) }, + { LedId.Keyboard_Custom25, (2,23) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_NonUsTilde, (3,12) }, + { LedId.Keyboard_Num4, (3,18) }, + { LedId.Keyboard_Num5, (3,19) }, + { LedId.Keyboard_Num6, (3,20) }, + { LedId.Keyboard_Custom4, (3,22) }, + { LedId.Keyboard_Custom26, (3,23) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_NonUsBackslash, (4,1) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + { LedId.Keyboard_Num1, (4,18) }, + { LedId.Keyboard_Num2, (4,19) }, + { LedId.Keyboard_Num3, (4,20) }, + { LedId.Keyboard_NumEnter, (4,21) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,20) }, + + { LedId.Keyboard_Custom5, (6,0) }, + { LedId.Keyboard_Custom6, (6,1) }, + { LedId.Keyboard_Custom7, (6,2) }, + { LedId.Keyboard_Custom8, (6,3) }, + { LedId.Keyboard_Custom9, (6,4) }, + { LedId.Keyboard_Custom10, (6,5) }, + { LedId.Keyboard_Custom11, (6,6) }, + { LedId.Keyboard_Custom12, (6,7) }, + { LedId.Keyboard_Custom13, (6,8) }, + { LedId.Keyboard_Custom14, (6,9) }, + { LedId.Keyboard_Custom15, (6,10) }, + { LedId.Keyboard_Custom16, (6,11) }, + { LedId.Keyboard_Custom17, (6,12) }, + { LedId.Keyboard_Custom18, (6,13) }, + { LedId.Keyboard_Custom19, (6,14) }, + { LedId.Keyboard_Custom20, (6,15) }, + { LedId.Keyboard_Custom21, (6,16) }, + { LedId.Keyboard_Custom22, (6,17) } + }; + + private static readonly Dictionary MasterKeysMK750_JP = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + { LedId.Keyboard_Programmable1, (0,18) }, + { LedId.Keyboard_Programmable2, (0,19) }, + { LedId.Keyboard_Programmable3, (0,20) }, + { LedId.Keyboard_Programmable4, (0,21) }, + { LedId.Keyboard_Custom1, (0,22) }, + { LedId.Keyboard_Custom23, (0,23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_International1, (1,13) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + { LedId.Keyboard_NumLock, (1,18) }, + { LedId.Keyboard_NumSlash, (1,19) }, + { LedId.Keyboard_NumAsterisk, (1,20) }, + { LedId.Keyboard_NumMinus, (1,21) }, + { LedId.Keyboard_Custom2, (1,22) }, + { LedId.Keyboard_Custom24, (1,23) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Enter, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + { LedId.Keyboard_Num7, (2,18) }, + { LedId.Keyboard_Num8, (2,19) }, + { LedId.Keyboard_Num9, (2,20) }, + { LedId.Keyboard_NumPlus, (2,21) }, + { LedId.Keyboard_Custom3, (2,22) }, + { LedId.Keyboard_Custom25, (2,23) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_Backslash, (3,14) }, + { LedId.Keyboard_Num4, (3,18) }, + { LedId.Keyboard_Num5, (3,19) }, + { LedId.Keyboard_Num6, (3,20) }, + { LedId.Keyboard_Custom4, (3,22) }, + { LedId.Keyboard_Custom26, (3,23) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_International2, (4,12) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + { LedId.Keyboard_Num1, (4,18) }, + { LedId.Keyboard_Num2, (4,19) }, + { LedId.Keyboard_Num3, (4,20) }, + { LedId.Keyboard_NumEnter, (4,21) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_International3, (5,4) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_International4, (5,8) }, + { LedId.Keyboard_International5, (5,9) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,20) }, + + { LedId.Keyboard_Custom5, (6,0) }, + { LedId.Keyboard_Custom6, (6,1) }, + { LedId.Keyboard_Custom7, (6,2) }, + { LedId.Keyboard_Custom8, (6,3) }, + { LedId.Keyboard_Custom9, (6,4) }, + { LedId.Keyboard_Custom10, (6,5) }, + { LedId.Keyboard_Custom11, (6,6) }, + { LedId.Keyboard_Custom12, (6,7) }, + { LedId.Keyboard_Custom13, (6,8) }, + { LedId.Keyboard_Custom14, (6,9) }, + { LedId.Keyboard_Custom15, (6,10) }, + { LedId.Keyboard_Custom16, (6,11) }, + { LedId.Keyboard_Custom17, (6,12) }, + { LedId.Keyboard_Custom18, (6,13) }, + { LedId.Keyboard_Custom19, (6,14) }, + { LedId.Keyboard_Custom20, (6,15) }, + { LedId.Keyboard_Custom21, (6,16) }, + { LedId.Keyboard_Custom22, (6,17) }, + }; + + #endregion + + #region CKxxx + + private static readonly Dictionary CKxxx_US = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + { LedId.Keyboard_NumLock, (1,18) }, + { LedId.Keyboard_NumSlash, (1,19) }, + { LedId.Keyboard_NumAsterisk, (1,20) }, + { LedId.Keyboard_NumMinus, (1,21) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Backslash, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + { LedId.Keyboard_Num7, (2,18) }, + { LedId.Keyboard_Num8, (2,19) }, + { LedId.Keyboard_Num9, (2,20) }, + { LedId.Keyboard_NumPlus, (2,21) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_Enter, (3,14) }, + { LedId.Keyboard_Num4, (3,18) }, + { LedId.Keyboard_Num5, (3,19) }, + { LedId.Keyboard_Num6, (3,20) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + { LedId.Keyboard_Num1, (4,18) }, + { LedId.Keyboard_Num2, (4,19) }, + { LedId.Keyboard_Num3, (4,20) }, + { LedId.Keyboard_NumEnter, (4,21) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,20) } + }; + + private static readonly Dictionary CKxxx_EU = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + { LedId.Keyboard_NumLock, (1,18) }, + { LedId.Keyboard_NumSlash, (1,19) }, + { LedId.Keyboard_NumAsterisk, (1,20) }, + { LedId.Keyboard_NumMinus, (1,21) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Enter, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + { LedId.Keyboard_Num7, (2,18) }, + { LedId.Keyboard_Num8, (2,19) }, + { LedId.Keyboard_Num9, (2,20) }, + { LedId.Keyboard_NumPlus, (2,21) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_NonUsTilde, (3,12) }, + { LedId.Keyboard_Num4, (3,18) }, + { LedId.Keyboard_Num5, (3,19) }, + { LedId.Keyboard_Num6, (3,20) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_NonUsBackslash, (4,1) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + { LedId.Keyboard_Num1, (4,18) }, + { LedId.Keyboard_Num2, (4,19) }, + { LedId.Keyboard_Num3, (4,20) }, + { LedId.Keyboard_NumEnter, (4,21) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,20) } + }; + + private static readonly Dictionary CKxxx_JP = new() + { + { LedId.Keyboard_Escape, (0,0) }, + { LedId.Keyboard_F1, (0,1) }, + { LedId.Keyboard_F2, (0,2) }, + { LedId.Keyboard_F3, (0,3) }, + { LedId.Keyboard_F4, (0,4) }, + { LedId.Keyboard_F5, (0,6) }, + { LedId.Keyboard_F6, (0,7) }, + { LedId.Keyboard_F7, (0,8) }, + { LedId.Keyboard_F8, (0,9) }, + { LedId.Keyboard_F9, (0,11) }, + { LedId.Keyboard_F10, (0,12) }, + { LedId.Keyboard_F11, (0,13) }, + { LedId.Keyboard_F12, (0,14) }, + { LedId.Keyboard_PrintScreen, (0,15) }, + { LedId.Keyboard_ScrollLock, (0,16) }, + { LedId.Keyboard_PauseBreak, (0,17) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, + { LedId.Keyboard_1, (1,1) }, + { LedId.Keyboard_2, (1,2) }, + { LedId.Keyboard_3, (1,3) }, + { LedId.Keyboard_4, (1,4) }, + { LedId.Keyboard_5, (1,5) }, + { LedId.Keyboard_6, (1,6) }, + { LedId.Keyboard_7, (1,7) }, + { LedId.Keyboard_8, (1,8) }, + { LedId.Keyboard_9, (1,9) }, + { LedId.Keyboard_0, (1,10) }, + { LedId.Keyboard_MinusAndUnderscore, (1,11) }, + { LedId.Keyboard_EqualsAndPlus, (1,12) }, + { LedId.Keyboard_International1, (1,13) }, + { LedId.Keyboard_Backspace, (1,14) }, + { LedId.Keyboard_Insert, (1,15) }, + { LedId.Keyboard_Home, (1,16) }, + { LedId.Keyboard_PageUp, (1,17) }, + { LedId.Keyboard_NumLock, (1,18) }, + { LedId.Keyboard_NumSlash, (1,19) }, + { LedId.Keyboard_NumAsterisk, (1,20) }, + { LedId.Keyboard_NumMinus, (1,21) }, + + { LedId.Keyboard_Tab, (2,0) }, + { LedId.Keyboard_Q, (2,1) }, + { LedId.Keyboard_W, (2,2) }, + { LedId.Keyboard_E, (2,3) }, + { LedId.Keyboard_R, (2,4) }, + { LedId.Keyboard_T, (2,5) }, + { LedId.Keyboard_Y, (2,6) }, + { LedId.Keyboard_U, (2,7) }, + { LedId.Keyboard_I, (2,8) }, + { LedId.Keyboard_O, (2,9) }, + { LedId.Keyboard_P, (2,10) }, + { LedId.Keyboard_BracketLeft, (2,11) }, + { LedId.Keyboard_BracketRight, (2,12) }, + { LedId.Keyboard_Enter, (2,14) }, + { LedId.Keyboard_Delete, (2,15) }, + { LedId.Keyboard_End, (2,16) }, + { LedId.Keyboard_PageDown, (2,17) }, + { LedId.Keyboard_Num7, (2,18) }, + { LedId.Keyboard_Num8, (2,19) }, + { LedId.Keyboard_Num9, (2,20) }, + { LedId.Keyboard_NumPlus, (2,21) }, + + { LedId.Keyboard_CapsLock, (3,0) }, + { LedId.Keyboard_A, (3,1) }, + { LedId.Keyboard_S, (3,2) }, + { LedId.Keyboard_D, (3,3) }, + { LedId.Keyboard_F, (3,4) }, + { LedId.Keyboard_G, (3,5) }, + { LedId.Keyboard_H, (3,6) }, + { LedId.Keyboard_J, (3,7) }, + { LedId.Keyboard_K, (3,8) }, + { LedId.Keyboard_L, (3,9) }, + { LedId.Keyboard_SemicolonAndColon, (3,10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, + { LedId.Keyboard_Backslash, (3,14) }, + { LedId.Keyboard_Num4, (3,18) }, + { LedId.Keyboard_Num5, (3,19) }, + { LedId.Keyboard_Num6, (3,20) }, + + { LedId.Keyboard_LeftShift, (4,0) }, + { LedId.Keyboard_Z, (4,2) }, + { LedId.Keyboard_X, (4,3) }, + { LedId.Keyboard_C, (4,4) }, + { LedId.Keyboard_V, (4,5) }, + { LedId.Keyboard_B, (4,6) }, + { LedId.Keyboard_N, (4,7) }, + { LedId.Keyboard_M, (4,8) }, + { LedId.Keyboard_CommaAndLessThan, (4,9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, + { LedId.Keyboard_International2, (4,12) }, + { LedId.Keyboard_RightShift, (4,14) }, + { LedId.Keyboard_ArrowUp, (4,16) }, + { LedId.Keyboard_Num1, (4,18) }, + { LedId.Keyboard_Num2, (4,19) }, + { LedId.Keyboard_Num3, (4,20) }, + { LedId.Keyboard_NumEnter, (4,21) }, + + { LedId.Keyboard_LeftCtrl, (5,0) }, + { LedId.Keyboard_LeftGui, (5,1) }, + { LedId.Keyboard_LeftAlt, (5,2) }, + { LedId.Keyboard_International3, (5,4) }, + { LedId.Keyboard_Space, (5,6) }, + { LedId.Keyboard_International4, (5,8) }, + { LedId.Keyboard_International5, (5,9) }, + { LedId.Keyboard_RightAlt, (5,10) }, + { LedId.Keyboard_RightGui, (5,11) }, + { LedId.Keyboard_Application, (5,12) }, + { LedId.Keyboard_RightCtrl, (5,14) }, + { LedId.Keyboard_ArrowLeft, (5,15) }, + { LedId.Keyboard_ArrowDown, (5,16) }, + { LedId.Keyboard_ArrowRight, (5,17) }, + { LedId.Keyboard_Num0, (5,18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5,20) } + }; + + #endregion + + #region CK530 + + private static readonly Dictionary CK530_US = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Backslash, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Enter, (3, 14) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + }; + + private static readonly Dictionary CK530_EU = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_NonUsTilde, (3, 12) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_NonUsBackslash, (4, 1) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + }; + + private static readonly Dictionary CK530_JP = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_International1, (1, 13) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Backslash, (3, 14) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_International2, (4, 12) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_International3, (5, 4) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_International4, (5, 8) }, + { LedId.Keyboard_International5, (5, 9) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + }; + + #endregion + + #region MasterKeysMK850 + + private static readonly Dictionary MasterKeysMK850_US = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Programmable1, (0, 19) }, + { LedId.Keyboard_Programmable2, (0, 20) }, + { LedId.Keyboard_Programmable3, (0, 21) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom21, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_NumLock, (1, 18) }, + { LedId.Keyboard_NumSlash, (1, 19) }, + { LedId.Keyboard_NumAsterisk, (1, 20) }, + { LedId.Keyboard_NumMinus, (1, 21) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom22, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Backslash, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Num7, (2, 18) }, + { LedId.Keyboard_Num8, (2, 19) }, + { LedId.Keyboard_Num9, (2, 20) }, + { LedId.Keyboard_NumPlus, (2, 21) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom23, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Enter, (3, 14) }, + { LedId.Keyboard_Num4, (3, 18) }, + { LedId.Keyboard_Num5, (3, 19) }, + { LedId.Keyboard_Num6, (3, 20) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom24, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + { LedId.Keyboard_Num1, (4, 18) }, + { LedId.Keyboard_Num2, (4, 19) }, + { LedId.Keyboard_Num3, (4, 20) }, + { LedId.Keyboard_NumEnter, (4, 21) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + { LedId.Keyboard_Num0, (5, 18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5, 20) }, + + { LedId.Keyboard_Custom5, (6, 0) }, + { LedId.Keyboard_Custom6, (6, 1) }, + { LedId.Keyboard_Custom7, (6, 2) }, + { LedId.Keyboard_Custom8, (6, 3) }, + { LedId.Keyboard_Custom9, (6, 4) }, + { LedId.Keyboard_Custom10, (6, 5) }, + { LedId.Keyboard_Custom11, (6, 6) }, + { LedId.Keyboard_Custom12, (6, 7) }, + { LedId.Keyboard_Custom13, (6, 8) }, + { LedId.Keyboard_Custom14, (6, 9) }, + { LedId.Keyboard_Custom15, (6, 10) }, + { LedId.Keyboard_Custom16, (6, 11) }, + { LedId.Keyboard_Custom17, (6, 12) }, + { LedId.Keyboard_Custom18, (6, 13) }, + { LedId.Keyboard_Custom19, (6, 14) }, + { LedId.Keyboard_Custom20, (6, 15) } + }; + + private static readonly Dictionary MasterKeysMK850_EU = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Programmable1, (0, 18) }, + { LedId.Keyboard_Programmable2, (0, 19) }, + { LedId.Keyboard_Programmable3, (0, 20) }, + { LedId.Keyboard_Programmable4, (0, 21) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom23, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_NumLock, (1, 18) }, + { LedId.Keyboard_NumSlash, (1, 19) }, + { LedId.Keyboard_NumAsterisk, (1, 20) }, + { LedId.Keyboard_NumMinus, (1, 21) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom24, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Num7, (2, 18) }, + { LedId.Keyboard_Num8, (2, 19) }, + { LedId.Keyboard_Num9, (2, 20) }, + { LedId.Keyboard_NumPlus, (2, 21) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom25, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_NonUsTilde, (3, 12) }, + { LedId.Keyboard_Num4, (3, 18) }, + { LedId.Keyboard_Num5, (3, 19) }, + { LedId.Keyboard_Num6, (3, 20) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom26, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_NonUsBackslash, (4, 1) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + { LedId.Keyboard_Num1, (4, 18) }, + { LedId.Keyboard_Num2, (4, 19) }, + { LedId.Keyboard_Num3, (4, 20) }, + { LedId.Keyboard_NumEnter, (4, 21) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + { LedId.Keyboard_Num0, (5, 18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5, 20) }, + + { LedId.Keyboard_Custom5, (6, 0) }, + { LedId.Keyboard_Custom6, (6, 1) }, + { LedId.Keyboard_Custom7, (6, 2) }, + { LedId.Keyboard_Custom8, (6, 3) }, + { LedId.Keyboard_Custom9, (6, 4) }, + { LedId.Keyboard_Custom10, (6, 5) }, + { LedId.Keyboard_Custom11, (6, 6) }, + { LedId.Keyboard_Custom12, (6, 7) }, + { LedId.Keyboard_Custom13, (6, 8) }, + { LedId.Keyboard_Custom14, (6, 9) }, + { LedId.Keyboard_Custom15, (6, 10) }, + { LedId.Keyboard_Custom16, (6, 11) }, + { LedId.Keyboard_Custom17, (6, 12) }, + { LedId.Keyboard_Custom18, (6, 13) }, + { LedId.Keyboard_Custom19, (6, 14) }, + { LedId.Keyboard_Custom20, (6, 15) }, + { LedId.Keyboard_Custom21, (6, 16) }, + { LedId.Keyboard_Custom22, (6, 17) } + }; + + #endregion + + #region SK630 + + private static readonly Dictionary SK630_US = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom25, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom26, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Backslash, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom27, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Enter, (3, 14) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom28, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + { LedId.Keyboard_Custom5, (4, 22) }, + { LedId.Keyboard_Custom29, (4, 23) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + + { LedId.Keyboard_Custom6, (6, 0) }, + { LedId.Keyboard_Custom7, (6, 1) }, + { LedId.Keyboard_Custom8, (6, 2) }, + { LedId.Keyboard_Custom9, (6, 3) }, + { LedId.Keyboard_Custom10, (6, 4) }, + { LedId.Keyboard_Custom11, (6, 5) }, + { LedId.Keyboard_Custom12, (6, 6) }, + { LedId.Keyboard_Custom13, (6, 7) }, + { LedId.Keyboard_Custom14, (6, 8) }, + { LedId.Keyboard_Custom15, (6, 9) }, + { LedId.Keyboard_Custom16, (6, 10) }, + { LedId.Keyboard_Custom17, (6, 11) }, + { LedId.Keyboard_Custom18, (6, 12) }, + { LedId.Keyboard_Custom19, (6, 13) }, + { LedId.Keyboard_Custom20, (6, 14) }, + { LedId.Keyboard_Custom21, (6, 15) }, + { LedId.Keyboard_Custom22, (6, 16) }, + { LedId.Keyboard_Custom23, (6, 17) }, + { LedId.Keyboard_Custom24, (6, 18) }, + + { LedId.Keyboard_Custom30, (7, 0) }, + { LedId.Keyboard_Custom31, (7, 1) }, + { LedId.Keyboard_Custom32, (7, 2) }, + { LedId.Keyboard_Custom33, (7, 3) }, + { LedId.Keyboard_Custom34, (7, 4) }, + { LedId.Keyboard_Custom35, (7, 5) }, + { LedId.Keyboard_Custom36, (7, 6) }, + { LedId.Keyboard_Custom37, (7, 7) }, + { LedId.Keyboard_Custom38, (7, 8) }, + { LedId.Keyboard_Custom39, (7, 9) }, + { LedId.Keyboard_Custom40, (7, 10) }, + { LedId.Keyboard_Custom41, (7, 11) }, + { LedId.Keyboard_Custom42, (7, 12) }, + { LedId.Keyboard_Custom43, (7, 13) }, + { LedId.Keyboard_Custom44, (7, 14) }, + { LedId.Keyboard_Custom45, (7, 15) }, + { LedId.Keyboard_Custom46, (7, 16) }, + { LedId.Keyboard_Custom47, (7, 17) }, + { LedId.Keyboard_Custom48, (7, 18) }, + { LedId.Keyboard_Custom49, (7, 19) }, + { LedId.Keyboard_Custom50, (7, 20) }, + }; + + private static readonly Dictionary SK630_EU = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom25, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom26, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom27, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_NonUsTilde, (3, 12) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom28, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_NonUsBackslash, (4, 1) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + { LedId.Keyboard_Custom5, (4, 22) }, + { LedId.Keyboard_Custom29, (4, 23) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + + { LedId.Keyboard_Custom6, (6, 0) }, + { LedId.Keyboard_Custom7, (6, 1) }, + { LedId.Keyboard_Custom8, (6, 2) }, + { LedId.Keyboard_Custom9, (6, 3) }, + { LedId.Keyboard_Custom10, (6, 4) }, + { LedId.Keyboard_Custom11, (6, 5) }, + { LedId.Keyboard_Custom12, (6, 6) }, + { LedId.Keyboard_Custom13, (6, 7) }, + { LedId.Keyboard_Custom14, (6, 8) }, + { LedId.Keyboard_Custom15, (6, 9) }, + { LedId.Keyboard_Custom16, (6, 10) }, + { LedId.Keyboard_Custom17, (6, 11) }, + { LedId.Keyboard_Custom18, (6, 12) }, + { LedId.Keyboard_Custom19, (6, 13) }, + { LedId.Keyboard_Custom20, (6, 14) }, + { LedId.Keyboard_Custom21, (6, 15) }, + { LedId.Keyboard_Custom22, (6, 16) }, + { LedId.Keyboard_Custom23, (6, 17) }, + { LedId.Keyboard_Custom24, (6, 18) }, + + { LedId.Keyboard_Custom30, (7, 0) }, + { LedId.Keyboard_Custom31, (7, 1) }, + { LedId.Keyboard_Custom32, (7, 2) }, + { LedId.Keyboard_Custom33, (7, 3) }, + { LedId.Keyboard_Custom34, (7, 4) }, + { LedId.Keyboard_Custom35, (7, 5) }, + { LedId.Keyboard_Custom36, (7, 6) }, + { LedId.Keyboard_Custom37, (7, 7) }, + { LedId.Keyboard_Custom38, (7, 8) }, + { LedId.Keyboard_Custom39, (7, 9) }, + { LedId.Keyboard_Custom40, (7, 10) }, + { LedId.Keyboard_Custom41, (7, 11) }, + { LedId.Keyboard_Custom42, (7, 12) }, + { LedId.Keyboard_Custom43, (7, 13) }, + { LedId.Keyboard_Custom44, (7, 14) }, + { LedId.Keyboard_Custom45, (7, 15) }, + { LedId.Keyboard_Custom46, (7, 16) }, + { LedId.Keyboard_Custom47, (7, 17) }, + { LedId.Keyboard_Custom48, (7, 18) }, + { LedId.Keyboard_Custom49, (7, 19) }, + { LedId.Keyboard_Custom50, (7, 20) }, + }; + + private static readonly Dictionary SK630_JP = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom25, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_International1, (1, 13) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom26, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom27, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Backslash, (3, 14) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom28, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_International2, (4, 12) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + { LedId.Keyboard_Custom5, (4, 22) }, + { LedId.Keyboard_Custom29, (4, 23) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_International3, (5, 4) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_International4, (5, 8) }, + { LedId.Keyboard_International5, (5, 9) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + + { LedId.Keyboard_Custom6, (6, 0) }, + { LedId.Keyboard_Custom7, (6, 1) }, + { LedId.Keyboard_Custom8, (6, 2) }, + { LedId.Keyboard_Custom9, (6, 3) }, + { LedId.Keyboard_Custom10, (6, 4) }, + { LedId.Keyboard_Custom11, (6, 5) }, + { LedId.Keyboard_Custom12, (6, 6) }, + { LedId.Keyboard_Custom13, (6, 7) }, + { LedId.Keyboard_Custom14, (6, 8) }, + { LedId.Keyboard_Custom15, (6, 9) }, + { LedId.Keyboard_Custom16, (6, 10) }, + { LedId.Keyboard_Custom17, (6, 11) }, + { LedId.Keyboard_Custom18, (6, 12) }, + { LedId.Keyboard_Custom19, (6, 13) }, + { LedId.Keyboard_Custom20, (6, 14) }, + { LedId.Keyboard_Custom21, (6, 15) }, + { LedId.Keyboard_Custom22, (6, 16) }, + { LedId.Keyboard_Custom23, (6, 17) }, + { LedId.Keyboard_Custom24, (6, 18) }, + + { LedId.Keyboard_Custom30, (7, 0) }, + { LedId.Keyboard_Custom31, (7, 1) }, + { LedId.Keyboard_Custom32, (7, 2) }, + { LedId.Keyboard_Custom33, (7, 3) }, + { LedId.Keyboard_Custom34, (7, 4) }, + { LedId.Keyboard_Custom35, (7, 5) }, + { LedId.Keyboard_Custom36, (7, 6) }, + { LedId.Keyboard_Custom37, (7, 7) }, + { LedId.Keyboard_Custom38, (7, 8) }, + { LedId.Keyboard_Custom39, (7, 9) }, + { LedId.Keyboard_Custom40, (7, 10) }, + { LedId.Keyboard_Custom41, (7, 11) }, + { LedId.Keyboard_Custom42, (7, 12) }, + { LedId.Keyboard_Custom43, (7, 13) }, + { LedId.Keyboard_Custom44, (7, 14) }, + { LedId.Keyboard_Custom45, (7, 15) }, + { LedId.Keyboard_Custom46, (7, 16) }, + { LedId.Keyboard_Custom47, (7, 17) }, + { LedId.Keyboard_Custom48, (7, 18) }, + { LedId.Keyboard_Custom49, (7, 19) }, + { LedId.Keyboard_Custom50, (7, 20) }, + }; + + #endregion + + #region SK650 + + private static readonly Dictionary SK650_US = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom30, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_NumLock, (1, 18) }, + { LedId.Keyboard_NumSlash, (1, 19) }, + { LedId.Keyboard_NumAsterisk, (1, 20) }, + { LedId.Keyboard_NumMinus, (1, 21) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom31, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Backslash, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Num7, (2, 18) }, + { LedId.Keyboard_Num8, (2, 19) }, + { LedId.Keyboard_Num9, (2, 20) }, + { LedId.Keyboard_NumPlus, (2, 21) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom32, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Enter, (3, 14) }, + { LedId.Keyboard_Num4, (3, 18) }, + { LedId.Keyboard_Num5, (3, 19) }, + { LedId.Keyboard_Num6, (3, 20) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom33, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + { LedId.Keyboard_Num1, (4, 18) }, + { LedId.Keyboard_Num2, (4, 19) }, + { LedId.Keyboard_Num3, (4, 20) }, + { LedId.Keyboard_NumEnter, (4, 21) }, + { LedId.Keyboard_Custom5, (4, 22) }, + { LedId.Keyboard_Custom34, (4, 23) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + { LedId.Keyboard_Num0, (5, 18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5, 20) }, + { LedId.Keyboard_Custom59, (5, 22) }, + { LedId.Keyboard_Custom60, (5, 23) }, + + { LedId.Keyboard_Custom6, (6, 0) }, + { LedId.Keyboard_Custom7, (6, 1) }, + { LedId.Keyboard_Custom8, (6, 2) }, + { LedId.Keyboard_Custom9, (6, 3) }, + { LedId.Keyboard_Custom10, (6, 4) }, + { LedId.Keyboard_Custom11, (6, 5) }, + { LedId.Keyboard_Custom12, (6, 6) }, + { LedId.Keyboard_Custom13, (6, 7) }, + { LedId.Keyboard_Custom14, (6, 8) }, + { LedId.Keyboard_Custom15, (6, 9) }, + { LedId.Keyboard_Custom16, (6, 10) }, + { LedId.Keyboard_Custom17, (6, 11) }, + { LedId.Keyboard_Custom18, (6, 12) }, + { LedId.Keyboard_Custom19, (6, 13) }, + { LedId.Keyboard_Custom20, (6, 14) }, + { LedId.Keyboard_Custom21, (6, 15) }, + { LedId.Keyboard_Custom22, (6, 16) }, + { LedId.Keyboard_Custom23, (6, 17) }, + { LedId.Keyboard_Custom24, (6, 18) }, + { LedId.Keyboard_Custom25, (6, 19) }, + { LedId.Keyboard_Custom26, (6, 20) }, + { LedId.Keyboard_Custom27, (6, 21) }, + { LedId.Keyboard_Custom28, (6, 22) }, + { LedId.Keyboard_Custom29, (6, 23) }, + + { LedId.Keyboard_Custom35, (7, 0) }, + { LedId.Keyboard_Custom36, (7, 1) }, + { LedId.Keyboard_Custom37, (7, 2) }, + { LedId.Keyboard_Custom38, (7, 3) }, + { LedId.Keyboard_Custom39, (7, 4) }, + { LedId.Keyboard_Custom40, (7, 5) }, + { LedId.Keyboard_Custom41, (7, 6) }, + { LedId.Keyboard_Custom42, (7, 7) }, + { LedId.Keyboard_Custom43, (7, 8) }, + { LedId.Keyboard_Custom44, (7, 9) }, + { LedId.Keyboard_Custom45, (7, 10) }, + { LedId.Keyboard_Custom46, (7, 11) }, + { LedId.Keyboard_Custom47, (7, 12) }, + { LedId.Keyboard_Custom48, (7, 13) }, + { LedId.Keyboard_Custom49, (7, 14) }, + { LedId.Keyboard_Custom50, (7, 15) }, + { LedId.Keyboard_Custom51, (7, 16) }, + { LedId.Keyboard_Custom52, (7, 17) }, + { LedId.Keyboard_Custom53, (7, 18) }, + { LedId.Keyboard_Custom54, (7, 19) }, + { LedId.Keyboard_Custom55, (7, 20) }, + { LedId.Keyboard_Custom56, (7, 21) }, + { LedId.Keyboard_Custom57, (7, 22) }, + { LedId.Keyboard_Custom58, (7, 23) }, + }; + + private static readonly Dictionary SK650_EU = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom30, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_NumLock, (1, 18) }, + { LedId.Keyboard_NumSlash, (1, 19) }, + { LedId.Keyboard_NumAsterisk, (1, 20) }, + { LedId.Keyboard_NumMinus, (1, 21) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom31, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Num7, (2, 18) }, + { LedId.Keyboard_Num8, (2, 19) }, + { LedId.Keyboard_Num9, (2, 20) }, + { LedId.Keyboard_NumPlus, (2, 21) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom32, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_NonUsTilde, (3, 12) }, + { LedId.Keyboard_Num4, (3, 18) }, + { LedId.Keyboard_Num5, (3, 19) }, + { LedId.Keyboard_Num6, (3, 20) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom33, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_NonUsBackslash, (4, 1) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + { LedId.Keyboard_Num1, (4, 18) }, + { LedId.Keyboard_Num2, (4, 19) }, + { LedId.Keyboard_Num3, (4, 20) }, + { LedId.Keyboard_NumEnter, (4, 21) }, + { LedId.Keyboard_Custom5, (4, 22) }, + { LedId.Keyboard_Custom34, (4, 23) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + { LedId.Keyboard_Num0, (5, 18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5, 20) }, + { LedId.Keyboard_Custom59, (5, 22) }, + { LedId.Keyboard_Custom60, (5, 23) }, + + { LedId.Keyboard_Custom6, (6, 0) }, + { LedId.Keyboard_Custom7, (6, 1) }, + { LedId.Keyboard_Custom8, (6, 2) }, + { LedId.Keyboard_Custom9, (6, 3) }, + { LedId.Keyboard_Custom10, (6, 4) }, + { LedId.Keyboard_Custom11, (6, 5) }, + { LedId.Keyboard_Custom12, (6, 6) }, + { LedId.Keyboard_Custom13, (6, 7) }, + { LedId.Keyboard_Custom14, (6, 8) }, + { LedId.Keyboard_Custom15, (6, 9) }, + { LedId.Keyboard_Custom16, (6, 10) }, + { LedId.Keyboard_Custom17, (6, 11) }, + { LedId.Keyboard_Custom18, (6, 12) }, + { LedId.Keyboard_Custom19, (6, 13) }, + { LedId.Keyboard_Custom20, (6, 14) }, + { LedId.Keyboard_Custom21, (6, 15) }, + { LedId.Keyboard_Custom22, (6, 16) }, + { LedId.Keyboard_Custom23, (6, 17) }, + { LedId.Keyboard_Custom24, (6, 18) }, + { LedId.Keyboard_Custom25, (6, 19) }, + { LedId.Keyboard_Custom26, (6, 20) }, + { LedId.Keyboard_Custom27, (6, 21) }, + { LedId.Keyboard_Custom28, (6, 22) }, + { LedId.Keyboard_Custom29, (6, 23) }, + + { LedId.Keyboard_Custom35, (7, 0) }, + { LedId.Keyboard_Custom36, (7, 1) }, + { LedId.Keyboard_Custom37, (7, 2) }, + { LedId.Keyboard_Custom38, (7, 3) }, + { LedId.Keyboard_Custom39, (7, 4) }, + { LedId.Keyboard_Custom40, (7, 5) }, + { LedId.Keyboard_Custom41, (7, 6) }, + { LedId.Keyboard_Custom42, (7, 7) }, + { LedId.Keyboard_Custom43, (7, 8) }, + { LedId.Keyboard_Custom44, (7, 9) }, + { LedId.Keyboard_Custom45, (7, 10) }, + { LedId.Keyboard_Custom46, (7, 11) }, + { LedId.Keyboard_Custom47, (7, 12) }, + { LedId.Keyboard_Custom48, (7, 13) }, + { LedId.Keyboard_Custom49, (7, 14) }, + { LedId.Keyboard_Custom50, (7, 15) }, + { LedId.Keyboard_Custom51, (7, 16) }, + { LedId.Keyboard_Custom52, (7, 17) }, + { LedId.Keyboard_Custom53, (7, 18) }, + { LedId.Keyboard_Custom54, (7, 19) }, + { LedId.Keyboard_Custom55, (7, 20) }, + { LedId.Keyboard_Custom56, (7, 21) }, + { LedId.Keyboard_Custom57, (7, 22) }, + { LedId.Keyboard_Custom58, (7, 23) }, + }; + + private static readonly Dictionary SK650_JP = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom30, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_International1, (1, 13) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_NumLock, (1, 18) }, + { LedId.Keyboard_NumSlash, (1, 19) }, + { LedId.Keyboard_NumAsterisk, (1, 20) }, + { LedId.Keyboard_NumMinus, (1, 21) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom31, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Num7, (2, 18) }, + { LedId.Keyboard_Num8, (2, 19) }, + { LedId.Keyboard_Num9, (2, 20) }, + { LedId.Keyboard_NumPlus, (2, 21) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom32, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Backslash, (3, 14) }, + { LedId.Keyboard_Num4, (3, 18) }, + { LedId.Keyboard_Num5, (3, 19) }, + { LedId.Keyboard_Num6, (3, 20) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom33, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_International2, (4, 12) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + { LedId.Keyboard_Num1, (4, 18) }, + { LedId.Keyboard_Num2, (4, 19) }, + { LedId.Keyboard_Num3, (4, 20) }, + { LedId.Keyboard_NumEnter, (4, 21) }, + { LedId.Keyboard_Custom5, (4, 22) }, + { LedId.Keyboard_Custom34, (4, 23) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_International3, (5, 4) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_International4, (5, 8) }, + { LedId.Keyboard_International5, (5, 9) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + { LedId.Keyboard_Num0, (5, 18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5, 20) }, + { LedId.Keyboard_Custom59, (5, 22) }, + { LedId.Keyboard_Custom60, (5, 23) }, + + { LedId.Keyboard_Custom6, (6, 0) }, + { LedId.Keyboard_Custom7, (6, 1) }, + { LedId.Keyboard_Custom8, (6, 2) }, + { LedId.Keyboard_Custom9, (6, 3) }, + { LedId.Keyboard_Custom10, (6, 4) }, + { LedId.Keyboard_Custom11, (6, 5) }, + { LedId.Keyboard_Custom12, (6, 6) }, + { LedId.Keyboard_Custom13, (6, 7) }, + { LedId.Keyboard_Custom14, (6, 8) }, + { LedId.Keyboard_Custom15, (6, 9) }, + { LedId.Keyboard_Custom16, (6, 10) }, + { LedId.Keyboard_Custom17, (6, 11) }, + { LedId.Keyboard_Custom18, (6, 12) }, + { LedId.Keyboard_Custom19, (6, 13) }, + { LedId.Keyboard_Custom20, (6, 14) }, + { LedId.Keyboard_Custom21, (6, 15) }, + { LedId.Keyboard_Custom22, (6, 16) }, + { LedId.Keyboard_Custom23, (6, 17) }, + { LedId.Keyboard_Custom24, (6, 18) }, + { LedId.Keyboard_Custom25, (6, 19) }, + { LedId.Keyboard_Custom26, (6, 20) }, + { LedId.Keyboard_Custom27, (6, 21) }, + { LedId.Keyboard_Custom28, (6, 22) }, + { LedId.Keyboard_Custom29, (6, 23) }, + + { LedId.Keyboard_Custom35, (7, 0) }, + { LedId.Keyboard_Custom36, (7, 1) }, + { LedId.Keyboard_Custom37, (7, 2) }, + { LedId.Keyboard_Custom38, (7, 3) }, + { LedId.Keyboard_Custom39, (7, 4) }, + { LedId.Keyboard_Custom40, (7, 5) }, + { LedId.Keyboard_Custom41, (7, 6) }, + { LedId.Keyboard_Custom42, (7, 7) }, + { LedId.Keyboard_Custom43, (7, 8) }, + { LedId.Keyboard_Custom44, (7, 9) }, + { LedId.Keyboard_Custom45, (7, 10) }, + { LedId.Keyboard_Custom46, (7, 11) }, + { LedId.Keyboard_Custom47, (7, 12) }, + { LedId.Keyboard_Custom48, (7, 13) }, + { LedId.Keyboard_Custom49, (7, 14) }, + { LedId.Keyboard_Custom50, (7, 15) }, + { LedId.Keyboard_Custom51, (7, 16) }, + { LedId.Keyboard_Custom52, (7, 17) }, + { LedId.Keyboard_Custom53, (7, 18) }, + { LedId.Keyboard_Custom54, (7, 19) }, + { LedId.Keyboard_Custom55, (7, 20) }, + { LedId.Keyboard_Custom56, (7, 21) }, + { LedId.Keyboard_Custom57, (7, 22) }, + { LedId.Keyboard_Custom58, (7, 23) }, + }; + + #endregion + + #region SK621 + + private static readonly Dictionary SK621_US = new() + { + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom21, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom22, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Backslash, (2, 14) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom23, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Enter, (3, 14) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom24, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 2) }, + { LedId.Keyboard_ArrowUp, (4, 13) }, + { LedId.Keyboard_Delete, (4, 14) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_Function, (5, 10) }, + { LedId.Keyboard_Application, (5, 11) }, + { LedId.Keyboard_ArrowLeft, (5, 12) }, + { LedId.Keyboard_ArrowDown, (5, 13) }, + { LedId.Keyboard_ArrowRight, (5, 14) }, + + { LedId.Keyboard_Custom5, (6, 0) }, + { LedId.Keyboard_Custom6, (6, 1) }, + { LedId.Keyboard_Custom7, (6, 2) }, + { LedId.Keyboard_Custom8, (6, 3) }, + { LedId.Keyboard_Custom9, (6, 4) }, + { LedId.Keyboard_Custom10, (6, 5) }, + { LedId.Keyboard_Custom11, (6, 6) }, + { LedId.Keyboard_Custom12, (6, 7) }, + { LedId.Keyboard_Custom13, (6, 8) }, + { LedId.Keyboard_Custom14, (6, 9) }, + { LedId.Keyboard_Custom15, (6, 10) }, + { LedId.Keyboard_Custom16, (6, 11) }, + { LedId.Keyboard_Custom17, (6, 12) }, + { LedId.Keyboard_Custom18, (6, 13) }, + { LedId.Keyboard_Custom19, (6, 14) }, + { LedId.Keyboard_Custom20, (6, 15) }, + + { LedId.Keyboard_Custom25, (7, 0) }, + { LedId.Keyboard_Custom26, (7, 1) }, + { LedId.Keyboard_Custom27, (7, 2) }, + { LedId.Keyboard_Custom28, (7, 3) }, + { LedId.Keyboard_Custom29, (7, 4) }, + { LedId.Keyboard_Custom30, (7, 5) }, + { LedId.Keyboard_Custom31, (7, 6) }, + { LedId.Keyboard_Custom32, (7, 7) }, + { LedId.Keyboard_Custom33, (7, 8) }, + { LedId.Keyboard_Custom34, (7, 9) }, + { LedId.Keyboard_Custom35, (7, 10) }, + { LedId.Keyboard_Custom36, (7, 11) }, + { LedId.Keyboard_Custom37, (7, 12) }, + { LedId.Keyboard_Custom38, (7, 13) }, + { LedId.Keyboard_Custom39, (7, 14) }, + { LedId.Keyboard_Custom40, (7, 15) }, + { LedId.Keyboard_Custom41, (7, 16) }, + }; + + private static readonly Dictionary SK621_EU = new() + { + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom21, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom22, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom23, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_NonUsTilde, (3, 12) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom24, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 2) }, + { LedId.Keyboard_ArrowUp, (4, 13) }, + { LedId.Keyboard_Delete, (4, 14) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_Function, (5, 10) }, + { LedId.Keyboard_Application, (5, 11) }, + { LedId.Keyboard_ArrowLeft, (5, 12) }, + { LedId.Keyboard_ArrowDown, (5, 13) }, + { LedId.Keyboard_ArrowRight, (5, 14) }, + + { LedId.Keyboard_Custom5, (6, 0) }, + { LedId.Keyboard_Custom6, (6, 1) }, + { LedId.Keyboard_Custom7, (6, 2) }, + { LedId.Keyboard_Custom8, (6, 3) }, + { LedId.Keyboard_Custom9, (6, 4) }, + { LedId.Keyboard_Custom10, (6, 5) }, + { LedId.Keyboard_Custom11, (6, 6) }, + { LedId.Keyboard_Custom12, (6, 7) }, + { LedId.Keyboard_Custom13, (6, 8) }, + { LedId.Keyboard_Custom14, (6, 9) }, + { LedId.Keyboard_Custom15, (6, 10) }, + { LedId.Keyboard_Custom16, (6, 11) }, + { LedId.Keyboard_Custom17, (6, 12) }, + { LedId.Keyboard_Custom18, (6, 13) }, + { LedId.Keyboard_Custom19, (6, 14) }, + { LedId.Keyboard_Custom20, (6, 15) }, + + { LedId.Keyboard_Custom25, (7, 0) }, + { LedId.Keyboard_Custom26, (7, 1) }, + { LedId.Keyboard_Custom27, (7, 2) }, + { LedId.Keyboard_Custom28, (7, 3) }, + { LedId.Keyboard_Custom29, (7, 4) }, + { LedId.Keyboard_Custom30, (7, 5) }, + { LedId.Keyboard_Custom31, (7, 6) }, + { LedId.Keyboard_Custom32, (7, 7) }, + { LedId.Keyboard_Custom33, (7, 8) }, + { LedId.Keyboard_Custom34, (7, 9) }, + { LedId.Keyboard_Custom35, (7, 10) }, + { LedId.Keyboard_Custom36, (7, 11) }, + { LedId.Keyboard_Custom37, (7, 12) }, + { LedId.Keyboard_Custom38, (7, 13) }, + { LedId.Keyboard_Custom39, (7, 14) }, + { LedId.Keyboard_Custom40, (7, 15) }, + { LedId.Keyboard_Custom41, (7, 16) }, + }; + + #endregion + + #region MK730 + + private static readonly Dictionary MK730_US = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom18, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom19, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Backslash, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom20, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Enter, (3, 14) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom21, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + + { LedId.Keyboard_Custom5, (6, 0) }, + { LedId.Keyboard_Custom6, (6, 1) }, + { LedId.Keyboard_Custom7, (6, 2) }, + { LedId.Keyboard_Custom8, (6, 3) }, + { LedId.Keyboard_Custom9, (6, 4) }, + { LedId.Keyboard_Custom10, (6, 5) }, + { LedId.Keyboard_Custom11, (6, 6) }, + { LedId.Keyboard_Custom12, (6, 7) }, + { LedId.Keyboard_Custom13, (6, 8) }, + { LedId.Keyboard_Custom14, (6, 9) }, + { LedId.Keyboard_Custom15, (6, 10) }, + { LedId.Keyboard_Custom16, (6, 11) }, + { LedId.Keyboard_Custom17, (6, 12) } + }; + + private static readonly Dictionary MK730_EU = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom18, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom19, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom20, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_NonUsTilde, (3, 12) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom21, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_NonUsBackslash, (4, 1) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + + { LedId.Keyboard_Custom5, (6, 0) }, + { LedId.Keyboard_Custom6, (6, 1) }, + { LedId.Keyboard_Custom7, (6, 2) }, + { LedId.Keyboard_Custom8, (6, 3) }, + { LedId.Keyboard_Custom9, (6, 4) }, + { LedId.Keyboard_Custom10, (6, 5) }, + { LedId.Keyboard_Custom11, (6, 6) }, + { LedId.Keyboard_Custom12, (6, 7) }, + { LedId.Keyboard_Custom13, (6, 8) }, + { LedId.Keyboard_Custom14, (6, 9) }, + { LedId.Keyboard_Custom15, (6, 10) }, + { LedId.Keyboard_Custom16, (6, 11) }, + { LedId.Keyboard_Custom17, (6, 12) } + }; + + private static readonly Dictionary MK730_JP = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 1) }, + { LedId.Keyboard_F2, (0, 2) }, + { LedId.Keyboard_F3, (0, 3) }, + { LedId.Keyboard_F4, (0, 4) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 11) }, + { LedId.Keyboard_F10, (0, 12) }, + { LedId.Keyboard_F11, (0, 13) }, + { LedId.Keyboard_F12, (0, 14) }, + { LedId.Keyboard_PrintScreen, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_PauseBreak, (0, 17) }, + { LedId.Keyboard_Custom1, (0, 22) }, + { LedId.Keyboard_Custom18, (0, 23) }, + + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_International1, (1, 13) }, + { LedId.Keyboard_Backspace, (1, 14) }, + { LedId.Keyboard_Insert, (1, 15) }, + { LedId.Keyboard_Home, (1, 16) }, + { LedId.Keyboard_PageUp, (1, 17) }, + { LedId.Keyboard_Custom2, (1, 22) }, + { LedId.Keyboard_Custom19, (1, 23) }, + + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Enter, (2, 14) }, + { LedId.Keyboard_Delete, (2, 15) }, + { LedId.Keyboard_End, (2, 16) }, + { LedId.Keyboard_PageDown, (2, 17) }, + { LedId.Keyboard_Custom3, (2, 22) }, + { LedId.Keyboard_Custom20, (2, 23) }, + + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_Backslash, (3, 14) }, + { LedId.Keyboard_Custom4, (3, 22) }, + { LedId.Keyboard_Custom21, (3, 23) }, + + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_International2, (4, 12) }, + { LedId.Keyboard_RightShift, (4, 14) }, + { LedId.Keyboard_ArrowUp, (4, 16) }, + + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_International3, (5, 4) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_International4, (5, 8) }, + { LedId.Keyboard_International5, (5, 9) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Application, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 14) }, + { LedId.Keyboard_ArrowLeft, (5, 15) }, + { LedId.Keyboard_ArrowDown, (5, 16) }, + { LedId.Keyboard_ArrowRight, (5, 17) }, + + { LedId.Keyboard_Custom5, (6, 0) }, + { LedId.Keyboard_Custom6, (6, 1) }, + { LedId.Keyboard_Custom7, (6, 2) }, + { LedId.Keyboard_Custom8, (6, 3) }, + { LedId.Keyboard_Custom9, (6, 4) }, + { LedId.Keyboard_Custom10, (6, 5) }, + { LedId.Keyboard_Custom11, (6, 6) }, + { LedId.Keyboard_Custom12, (6, 7) }, + { LedId.Keyboard_Custom13, (6, 8) }, + { LedId.Keyboard_Custom14, (6, 9) }, + { LedId.Keyboard_Custom15, (6, 10) }, + { LedId.Keyboard_Custom16, (6, 11) }, + { LedId.Keyboard_Custom17, (6, 12) } + }; + + #endregion + /// /// Contains all the hardware-id mappings for CoolerMaster devices. /// - internal static class CoolerMasterKeyboardLedMappings - { - #region Properties & Fields - - #region MasterKeysL - - private static readonly Dictionary MasterKeysL_US = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - { LedId.Keyboard_Programmable1, (0,18) }, - { LedId.Keyboard_Programmable2, (0,19) }, - { LedId.Keyboard_Programmable3, (0,20) }, - { LedId.Keyboard_Programmable4, (0,21) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - { LedId.Keyboard_NumLock, (1,18) }, - { LedId.Keyboard_NumSlash, (1,19) }, - { LedId.Keyboard_NumAsterisk, (1,20) }, - { LedId.Keyboard_NumMinus, (1,21) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - { LedId.Keyboard_Num7, (2,18) }, - { LedId.Keyboard_Num8, (2,19) }, - { LedId.Keyboard_Num9, (2,20) }, - { LedId.Keyboard_NumPlus, (2,21) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_Enter, (3,14) }, - { LedId.Keyboard_Num4, (3,18) }, - { LedId.Keyboard_Num5, (3,19) }, - { LedId.Keyboard_Num6, (3,20) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - { LedId.Keyboard_Num1, (4,18) }, - { LedId.Keyboard_Num2, (4,19) }, - { LedId.Keyboard_Num3, (4,20) }, - { LedId.Keyboard_NumEnter, (4,21) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,20) } - }; - - private static readonly Dictionary MasterKeysL_EU = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - { LedId.Keyboard_Programmable1, (0,18) }, - { LedId.Keyboard_Programmable2, (0,19) }, - { LedId.Keyboard_Programmable3, (0,20) }, - { LedId.Keyboard_Programmable4, (0,21) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - { LedId.Keyboard_NumLock, (1,18) }, - { LedId.Keyboard_NumSlash, (1,19) }, - { LedId.Keyboard_NumAsterisk, (1,20) }, - { LedId.Keyboard_NumMinus, (1,21) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Enter, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - { LedId.Keyboard_Num7, (2,18) }, - { LedId.Keyboard_Num8, (2,19) }, - { LedId.Keyboard_Num9, (2,20) }, - { LedId.Keyboard_NumPlus, (2,21) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_NonUsTilde, (3,12) }, - { LedId.Keyboard_Num4, (3,18) }, - { LedId.Keyboard_Num5, (3,19) }, - { LedId.Keyboard_Num6, (3,20) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_NonUsBackslash, (4,1) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - { LedId.Keyboard_Num1, (4,18) }, - { LedId.Keyboard_Num2, (4,19) }, - { LedId.Keyboard_Num3, (4,20) }, - { LedId.Keyboard_NumEnter, (4,21) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,20) } - }; - - #endregion - - #region MasterKeysM - - private static readonly Dictionary MasterKeysM_US = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_NumLock, (1,15) }, - { LedId.Keyboard_NumSlash, (1,16) }, - { LedId.Keyboard_NumAsterisk, (1,17) }, - { LedId.Keyboard_NumMinus, (1,18) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,14) }, - { LedId.Keyboard_Num7, (2,15) }, - { LedId.Keyboard_Num8, (2,16) }, - { LedId.Keyboard_Num9, (2,17) }, - { LedId.Keyboard_NumPlus, (2,18) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_Enter, (3,14) }, - { LedId.Keyboard_Num4, (3,15) }, - { LedId.Keyboard_Num5, (3,16) }, - { LedId.Keyboard_Num6, (3,17) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_Num1, (4,15) }, - { LedId.Keyboard_Num2, (4,16) }, - { LedId.Keyboard_Num3, (4,17) }, - { LedId.Keyboard_NumEnter, (4,18) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_Num0, (5,15) }, - { LedId.Keyboard_Num00, (5,16) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,17) } - }; - - private static readonly Dictionary MasterKeysM_EU = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_NumLock, (1,15) }, - { LedId.Keyboard_NumSlash, (1,16) }, - { LedId.Keyboard_NumAsterisk, (1,17) }, - { LedId.Keyboard_NumMinus, (1,18) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,14) }, - { LedId.Keyboard_Num7, (2,15) }, - { LedId.Keyboard_Num8, (2,16) }, - { LedId.Keyboard_Num9, (2,17) }, - { LedId.Keyboard_NumPlus, (2,18) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_NonUsTilde, (3,12) }, - { LedId.Keyboard_Num4, (3,15) }, - { LedId.Keyboard_Num5, (3,16) }, - { LedId.Keyboard_Num6, (3,17) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_NonUsBackslash, (4,1) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_Num1, (4,15) }, - { LedId.Keyboard_Num2, (4,16) }, - { LedId.Keyboard_Num3, (4,17) }, - { LedId.Keyboard_NumEnter, (4,18) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_Num0, (5,15) }, - { LedId.Keyboard_Num00, (5,16) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,17) } - }; - - #endregion - - #region MasterKeysS - - private static readonly Dictionary MasterKeysS_US = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_Enter, (3,14) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) } - }; - - private static readonly Dictionary MasterKeysS_EU = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Enter, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_NonUsTilde, (3,12) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_NonUsBackslash, (4,1) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) } - }; - - #endregion - - #region MasterKeysMK750 - - private static readonly Dictionary MasterKeysMK750_US = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - { LedId.Keyboard_Programmable1, (0,18) }, - { LedId.Keyboard_Programmable2, (0,19) }, - { LedId.Keyboard_Programmable3, (0,20) }, - { LedId.Keyboard_Programmable4, (0,21) }, - { LedId.Keyboard_Custom1, (0,22) }, - { LedId.Keyboard_Custom23, (0,23) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - { LedId.Keyboard_NumLock, (1,18) }, - { LedId.Keyboard_NumSlash, (1,19) }, - { LedId.Keyboard_NumAsterisk, (1,20) }, - { LedId.Keyboard_NumMinus, (1,21) }, - { LedId.Keyboard_Custom2, (1,22) }, - { LedId.Keyboard_Custom24, (1,23) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - { LedId.Keyboard_Num7, (2,18) }, - { LedId.Keyboard_Num8, (2,19) }, - { LedId.Keyboard_Num9, (2,20) }, - { LedId.Keyboard_NumPlus, (2,21) }, - { LedId.Keyboard_Custom3, (2,22) }, - { LedId.Keyboard_Custom25, (2,23) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_Enter, (3,14) }, - { LedId.Keyboard_Num4, (3,18) }, - { LedId.Keyboard_Num5, (3,19) }, - { LedId.Keyboard_Num6, (3,20) }, - { LedId.Keyboard_Custom4, (3,22) }, - { LedId.Keyboard_Custom26, (3,23) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - { LedId.Keyboard_Num1, (4,18) }, - { LedId.Keyboard_Num2, (4,19) }, - { LedId.Keyboard_Num3, (4,20) }, - { LedId.Keyboard_NumEnter, (4,21) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,20) }, - - { LedId.Keyboard_Custom5, (6,0) }, - { LedId.Keyboard_Custom6, (6,1) }, - { LedId.Keyboard_Custom7, (6,2) }, - { LedId.Keyboard_Custom8, (6,3) }, - { LedId.Keyboard_Custom9, (6,4) }, - { LedId.Keyboard_Custom10, (6,5) }, - { LedId.Keyboard_Custom11, (6,6) }, - { LedId.Keyboard_Custom12, (6,7) }, - { LedId.Keyboard_Custom13, (6,8) }, - { LedId.Keyboard_Custom14, (6,9) }, - { LedId.Keyboard_Custom15, (6,10) }, - { LedId.Keyboard_Custom16, (6,11) }, - { LedId.Keyboard_Custom17, (6,12) }, - { LedId.Keyboard_Custom18, (6,13) }, - { LedId.Keyboard_Custom19, (6,14) }, - { LedId.Keyboard_Custom20, (6,15) }, - { LedId.Keyboard_Custom21, (6,16) }, - { LedId.Keyboard_Custom22, (6,17) }, - }; - - private static readonly Dictionary MasterKeysMK750_EU = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - { LedId.Keyboard_Programmable1, (0,18) }, - { LedId.Keyboard_Programmable2, (0,19) }, - { LedId.Keyboard_Programmable3, (0,20) }, - { LedId.Keyboard_Programmable4, (0,21) }, - { LedId.Keyboard_Custom1, (0,22) }, - { LedId.Keyboard_Custom23, (0,23) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - { LedId.Keyboard_NumLock, (1,18) }, - { LedId.Keyboard_NumSlash, (1,19) }, - { LedId.Keyboard_NumAsterisk, (1,20) }, - { LedId.Keyboard_NumMinus, (1,21) }, - { LedId.Keyboard_Custom2, (1,22) }, - { LedId.Keyboard_Custom24, (1,23) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Enter, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - { LedId.Keyboard_Num7, (2,18) }, - { LedId.Keyboard_Num8, (2,19) }, - { LedId.Keyboard_Num9, (2,20) }, - { LedId.Keyboard_NumPlus, (2,21) }, - { LedId.Keyboard_Custom3, (2,22) }, - { LedId.Keyboard_Custom25, (2,23) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_NonUsTilde, (3,12) }, - { LedId.Keyboard_Num4, (3,18) }, - { LedId.Keyboard_Num5, (3,19) }, - { LedId.Keyboard_Num6, (3,20) }, - { LedId.Keyboard_Custom4, (3,22) }, - { LedId.Keyboard_Custom26, (3,23) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_NonUsBackslash, (4,1) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - { LedId.Keyboard_Num1, (4,18) }, - { LedId.Keyboard_Num2, (4,19) }, - { LedId.Keyboard_Num3, (4,20) }, - { LedId.Keyboard_NumEnter, (4,21) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,20) }, - - { LedId.Keyboard_Custom5, (6,0) }, - { LedId.Keyboard_Custom6, (6,1) }, - { LedId.Keyboard_Custom7, (6,2) }, - { LedId.Keyboard_Custom8, (6,3) }, - { LedId.Keyboard_Custom9, (6,4) }, - { LedId.Keyboard_Custom10, (6,5) }, - { LedId.Keyboard_Custom11, (6,6) }, - { LedId.Keyboard_Custom12, (6,7) }, - { LedId.Keyboard_Custom13, (6,8) }, - { LedId.Keyboard_Custom14, (6,9) }, - { LedId.Keyboard_Custom15, (6,10) }, - { LedId.Keyboard_Custom16, (6,11) }, - { LedId.Keyboard_Custom17, (6,12) }, - { LedId.Keyboard_Custom18, (6,13) }, - { LedId.Keyboard_Custom19, (6,14) }, - { LedId.Keyboard_Custom20, (6,15) }, - { LedId.Keyboard_Custom21, (6,16) }, - { LedId.Keyboard_Custom22, (6,17) } - }; - - private static readonly Dictionary MasterKeysMK750_JP = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - { LedId.Keyboard_Programmable1, (0,18) }, - { LedId.Keyboard_Programmable2, (0,19) }, - { LedId.Keyboard_Programmable3, (0,20) }, - { LedId.Keyboard_Programmable4, (0,21) }, - { LedId.Keyboard_Custom1, (0,22) }, - { LedId.Keyboard_Custom23, (0,23) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_International1, (1,13) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - { LedId.Keyboard_NumLock, (1,18) }, - { LedId.Keyboard_NumSlash, (1,19) }, - { LedId.Keyboard_NumAsterisk, (1,20) }, - { LedId.Keyboard_NumMinus, (1,21) }, - { LedId.Keyboard_Custom2, (1,22) }, - { LedId.Keyboard_Custom24, (1,23) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Enter, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - { LedId.Keyboard_Num7, (2,18) }, - { LedId.Keyboard_Num8, (2,19) }, - { LedId.Keyboard_Num9, (2,20) }, - { LedId.Keyboard_NumPlus, (2,21) }, - { LedId.Keyboard_Custom3, (2,22) }, - { LedId.Keyboard_Custom25, (2,23) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_Backslash, (3,14) }, - { LedId.Keyboard_Num4, (3,18) }, - { LedId.Keyboard_Num5, (3,19) }, - { LedId.Keyboard_Num6, (3,20) }, - { LedId.Keyboard_Custom4, (3,22) }, - { LedId.Keyboard_Custom26, (3,23) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_International2, (4,12) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - { LedId.Keyboard_Num1, (4,18) }, - { LedId.Keyboard_Num2, (4,19) }, - { LedId.Keyboard_Num3, (4,20) }, - { LedId.Keyboard_NumEnter, (4,21) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_International3, (5,4) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_International4, (5,8) }, - { LedId.Keyboard_International5, (5,9) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,20) }, - - { LedId.Keyboard_Custom5, (6,0) }, - { LedId.Keyboard_Custom6, (6,1) }, - { LedId.Keyboard_Custom7, (6,2) }, - { LedId.Keyboard_Custom8, (6,3) }, - { LedId.Keyboard_Custom9, (6,4) }, - { LedId.Keyboard_Custom10, (6,5) }, - { LedId.Keyboard_Custom11, (6,6) }, - { LedId.Keyboard_Custom12, (6,7) }, - { LedId.Keyboard_Custom13, (6,8) }, - { LedId.Keyboard_Custom14, (6,9) }, - { LedId.Keyboard_Custom15, (6,10) }, - { LedId.Keyboard_Custom16, (6,11) }, - { LedId.Keyboard_Custom17, (6,12) }, - { LedId.Keyboard_Custom18, (6,13) }, - { LedId.Keyboard_Custom19, (6,14) }, - { LedId.Keyboard_Custom20, (6,15) }, - { LedId.Keyboard_Custom21, (6,16) }, - { LedId.Keyboard_Custom22, (6,17) }, - }; - - #endregion - - #region CKxxx - - private static readonly Dictionary CKxxx_US = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - { LedId.Keyboard_NumLock, (1,18) }, - { LedId.Keyboard_NumSlash, (1,19) }, - { LedId.Keyboard_NumAsterisk, (1,20) }, - { LedId.Keyboard_NumMinus, (1,21) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - { LedId.Keyboard_Num7, (2,18) }, - { LedId.Keyboard_Num8, (2,19) }, - { LedId.Keyboard_Num9, (2,20) }, - { LedId.Keyboard_NumPlus, (2,21) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_Enter, (3,14) }, - { LedId.Keyboard_Num4, (3,18) }, - { LedId.Keyboard_Num5, (3,19) }, - { LedId.Keyboard_Num6, (3,20) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - { LedId.Keyboard_Num1, (4,18) }, - { LedId.Keyboard_Num2, (4,19) }, - { LedId.Keyboard_Num3, (4,20) }, - { LedId.Keyboard_NumEnter, (4,21) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,20) } - }; - - private static readonly Dictionary CKxxx_EU = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - { LedId.Keyboard_NumLock, (1,18) }, - { LedId.Keyboard_NumSlash, (1,19) }, - { LedId.Keyboard_NumAsterisk, (1,20) }, - { LedId.Keyboard_NumMinus, (1,21) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Enter, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - { LedId.Keyboard_Num7, (2,18) }, - { LedId.Keyboard_Num8, (2,19) }, - { LedId.Keyboard_Num9, (2,20) }, - { LedId.Keyboard_NumPlus, (2,21) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_NonUsTilde, (3,12) }, - { LedId.Keyboard_Num4, (3,18) }, - { LedId.Keyboard_Num5, (3,19) }, - { LedId.Keyboard_Num6, (3,20) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_NonUsBackslash, (4,1) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - { LedId.Keyboard_Num1, (4,18) }, - { LedId.Keyboard_Num2, (4,19) }, - { LedId.Keyboard_Num3, (4,20) }, - { LedId.Keyboard_NumEnter, (4,21) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,20) } - }; - - private static readonly Dictionary CKxxx_JP = new Dictionary + public static readonly Dictionary>> Mapping = + new() { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,1) }, - { LedId.Keyboard_F2, (0,2) }, - { LedId.Keyboard_F3, (0,3) }, - { LedId.Keyboard_F4, (0,4) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,11) }, - { LedId.Keyboard_F10, (0,12) }, - { LedId.Keyboard_F11, (0,13) }, - { LedId.Keyboard_F12, (0,14) }, - { LedId.Keyboard_PrintScreen, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_PauseBreak, (0,17) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_International1, (1,13) }, - { LedId.Keyboard_Backspace, (1,14) }, - { LedId.Keyboard_Insert, (1,15) }, - { LedId.Keyboard_Home, (1,16) }, - { LedId.Keyboard_PageUp, (1,17) }, - { LedId.Keyboard_NumLock, (1,18) }, - { LedId.Keyboard_NumSlash, (1,19) }, - { LedId.Keyboard_NumAsterisk, (1,20) }, - { LedId.Keyboard_NumMinus, (1,21) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Enter, (2,14) }, - { LedId.Keyboard_Delete, (2,15) }, - { LedId.Keyboard_End, (2,16) }, - { LedId.Keyboard_PageDown, (2,17) }, - { LedId.Keyboard_Num7, (2,18) }, - { LedId.Keyboard_Num8, (2,19) }, - { LedId.Keyboard_Num9, (2,20) }, - { LedId.Keyboard_NumPlus, (2,21) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_Backslash, (3,14) }, - { LedId.Keyboard_Num4, (3,18) }, - { LedId.Keyboard_Num5, (3,19) }, - { LedId.Keyboard_Num6, (3,20) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_International2, (4,12) }, - { LedId.Keyboard_RightShift, (4,14) }, - { LedId.Keyboard_ArrowUp, (4,16) }, - { LedId.Keyboard_Num1, (4,18) }, - { LedId.Keyboard_Num2, (4,19) }, - { LedId.Keyboard_Num3, (4,20) }, - { LedId.Keyboard_NumEnter, (4,21) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_International3, (5,4) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_International4, (5,8) }, - { LedId.Keyboard_International5, (5,9) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,14) }, - { LedId.Keyboard_ArrowLeft, (5,15) }, - { LedId.Keyboard_ArrowDown, (5,16) }, - { LedId.Keyboard_ArrowRight, (5,17) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,20) } + { CoolerMasterDevicesIndexes.MasterKeys_L, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysL_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysL_EU } + } + }, + + { CoolerMasterDevicesIndexes.MasterKeys_M, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysM_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysM_EU } + } + }, + + { CoolerMasterDevicesIndexes.MasterKeys_S, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysS_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysS_EU } + } + }, + + { CoolerMasterDevicesIndexes.MasterKeys_L_White, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysL_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysL_EU } + } + }, + + { CoolerMasterDevicesIndexes.MasterKeys_M_White, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysM_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysM_EU } + } + }, + + { CoolerMasterDevicesIndexes.MasterKeys_S_White, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysS_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysS_EU } + } + }, + + { CoolerMasterDevicesIndexes.MasterKeys_MK750, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysMK750_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysMK750_EU }, + { CoolerMasterPhysicalKeyboardLayout.JP, MasterKeysMK750_JP } + } + }, + + { CoolerMasterDevicesIndexes.CK372, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, CKxxx_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, CKxxx_EU }, + { CoolerMasterPhysicalKeyboardLayout.JP, CKxxx_JP } + } + }, + + { CoolerMasterDevicesIndexes.CK550, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, CKxxx_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, CKxxx_EU }, + { CoolerMasterPhysicalKeyboardLayout.JP, CKxxx_JP } + } + }, + + { CoolerMasterDevicesIndexes.CK551, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, CKxxx_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, CKxxx_EU }, + { CoolerMasterPhysicalKeyboardLayout.JP, CKxxx_JP } + } + }, + + { CoolerMasterDevicesIndexes.CK530, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, CK530_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, CK530_EU }, + { CoolerMasterPhysicalKeyboardLayout.JP, CK530_JP } + } + }, + + { CoolerMasterDevicesIndexes.MK850, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysMK850_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysMK850_EU } + } + }, + + { CoolerMasterDevicesIndexes.SK630, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, SK630_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, SK630_EU }, + { CoolerMasterPhysicalKeyboardLayout.JP, SK630_JP } + } + }, + + { CoolerMasterDevicesIndexes.SK650, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, SK650_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, SK650_EU }, + { CoolerMasterPhysicalKeyboardLayout.JP, SK650_JP } + } + }, + + { CoolerMasterDevicesIndexes.SK621, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, SK621_US }, + { CoolerMasterPhysicalKeyboardLayout.EU, SK621_EU } + } + }, + + { CoolerMasterDevicesIndexes.MK730, new Dictionary> + { + { CoolerMasterPhysicalKeyboardLayout.US, MK730_US}, + { CoolerMasterPhysicalKeyboardLayout.EU, MK730_EU }, + { CoolerMasterPhysicalKeyboardLayout.JP, MK730_JP } + } + }, }; - #endregion - - /// - /// Contains all the hardware-id mappings for CoolerMaster devices. - /// - public static readonly Dictionary>> Mapping = - new Dictionary>> - { - { CoolerMasterDevicesIndexes.MasterKeys_L, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysL_US }, - { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysL_EU } - } - }, - - { CoolerMasterDevicesIndexes.MasterKeys_M, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysM_US }, - { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysM_EU } - } - }, - - { CoolerMasterDevicesIndexes.MasterKeys_S, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysS_US }, - { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysS_EU } - } - }, - - { CoolerMasterDevicesIndexes.MasterKeys_L_White, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysL_US }, - { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysL_EU } - } - }, - - { CoolerMasterDevicesIndexes.MasterKeys_M_White, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysM_US }, - { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysM_EU } - } - }, - - { CoolerMasterDevicesIndexes.MasterKeys_S_White, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysS_US }, - { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysS_EU } - } - }, - - { CoolerMasterDevicesIndexes.MasterKeys_MK750, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, MasterKeysMK750_US}, - { CoolerMasterPhysicalKeyboardLayout.EU, MasterKeysMK750_EU }, - { CoolerMasterPhysicalKeyboardLayout.JP, MasterKeysMK750_JP } - } - }, - - { CoolerMasterDevicesIndexes.CK372, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, CKxxx_US}, - { CoolerMasterPhysicalKeyboardLayout.EU, CKxxx_EU }, - { CoolerMasterPhysicalKeyboardLayout.JP, CKxxx_JP } - } - }, - - { CoolerMasterDevicesIndexes.CK550, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, CKxxx_US}, - { CoolerMasterPhysicalKeyboardLayout.EU, CKxxx_EU }, - { CoolerMasterPhysicalKeyboardLayout.JP, CKxxx_JP } - } - }, - - { CoolerMasterDevicesIndexes.CK551, new Dictionary> - { - { CoolerMasterPhysicalKeyboardLayout.US, CKxxx_US}, - { CoolerMasterPhysicalKeyboardLayout.EU, CKxxx_EU }, - { CoolerMasterPhysicalKeyboardLayout.JP, CKxxx_JP } - } - }, - }; - - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs index 8a8c17a8..29b1e3c1 100644 --- a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDevice.cs @@ -1,48 +1,51 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// +/// Represents a CoolerMaster keyboard. +/// +public class CoolerMasterKeyboardRGBDevice : CoolerMasterRGBDevice, IKeyboard { - /// + #region Properties & Fields + + IKeyboardDeviceInfo IKeyboard.DeviceInfo => DeviceInfo; + + #endregion + + #region Constructors + + /// /// - /// Represents a CoolerMaster keyboard. + /// Initializes a new instance of the class. /// - public class CoolerMasterKeyboardRGBDevice : CoolerMasterRGBDevice, IKeyboard + /// The specific information provided by CoolerMaster for the keyboard + /// The update trigger used to update this device. + internal CoolerMasterKeyboardRGBDevice(CoolerMasterKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CoolerMaster for the keyboard - internal CoolerMasterKeyboardRGBDevice(CoolerMasterKeyboardRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - if (!CoolerMasterKeyboardLedMappings.Mapping.TryGetValue(DeviceInfo.DeviceIndex, out Dictionary> deviceMappings)) - throw new RGBDeviceException($"Failed to find a CoolerMasterKeyboardLedMapping for device index {DeviceInfo.DeviceIndex}"); - if (!deviceMappings.TryGetValue(DeviceInfo.PhysicalLayout, out Dictionary mapping)) - throw new RGBDeviceException($"Failed to find a CoolerMasterKeyboardLedMapping for device index {DeviceInfo.DeviceIndex} with physical layout {DeviceInfo.PhysicalLayout}"); - - foreach (KeyValuePair led in mapping) - InitializeLed(led.Key, new Rectangle(led.Value.column * 19, led.Value.row * 19, 19, 19)); - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\CoolerMaster\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), - DeviceInfo.LogicalLayout.ToString()); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => CoolerMasterKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId]; - - #endregion + InitializeLayout(); } -} + + #endregion + + #region Methods + + private void InitializeLayout() + { + if (!CoolerMasterKeyboardLedMappings.Mapping.TryGetValue(DeviceInfo.DeviceIndex, out Dictionary>? deviceMappings)) + throw new RGBDeviceException($"Failed to find a CoolerMasterKeyboardLedMapping for device index {DeviceInfo.DeviceIndex}"); + if (!deviceMappings.TryGetValue(DeviceInfo.PhysicalLayout, out Dictionary? mapping)) + throw new RGBDeviceException($"Failed to find a CoolerMasterKeyboardLedMapping for device index {DeviceInfo.DeviceIndex} with physical layout {DeviceInfo.PhysicalLayout}"); + + foreach ((LedId ledId, (int row, int column)) in mapping) + AddLed(ledId, new Point(column * 19, row * 19), new Size(19, 19)); + } + + /// + protected override object GetLedCustomData(LedId ledId) => CoolerMasterKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId]; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDeviceInfo.cs index c13e4cc4..df9fec99 100644 --- a/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.CoolerMaster/Keyboard/CoolerMasterKeyboardRGBDeviceInfo.cs @@ -1,56 +1,45 @@ -using System.Globalization; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// Represents a generic information for a . +/// +public class CoolerMasterKeyboardRGBDeviceInfo : CoolerMasterRGBDeviceInfo, IKeyboardDeviceInfo { + #region Properties & Fields + /// + public KeyboardLayoutType Layout { get; } + /// - /// Represents a generic information for a . + /// Gets the of the . /// - public class CoolerMasterKeyboardRGBDeviceInfo : CoolerMasterRGBDeviceInfo - { - #region Properties & Fields - - /// - /// Gets the of the . - /// - public CoolerMasterPhysicalKeyboardLayout PhysicalLayout { get; } - - /// - /// Gets the of the . - /// - public CoolerMasterLogicalKeyboardLayout LogicalLayout { get; private set; } - - #endregion - - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The index of the . - /// The of the . - /// The of the layout this keyboard is using - internal CoolerMasterKeyboardRGBDeviceInfo(CoolerMasterDevicesIndexes deviceIndex, CoolerMasterPhysicalKeyboardLayout physicalKeyboardLayout, CultureInfo culture) - : base(RGBDeviceType.Keyboard, deviceIndex) - { - this.PhysicalLayout = physicalKeyboardLayout; + public CoolerMasterPhysicalKeyboardLayout PhysicalLayout { get; } + + #endregion - SetLayouts(culture.KeyboardLayoutId); - } + #region Constructors - private void SetLayouts(int keyboardLayoutId) + /// + /// + /// Internal constructor of managed . + /// + /// The index of the . + /// The of the . + internal CoolerMasterKeyboardRGBDeviceInfo(CoolerMasterDevicesIndexes deviceIndex, CoolerMasterPhysicalKeyboardLayout physicalKeyboardLayout) + : base(RGBDeviceType.Keyboard, deviceIndex) + { + this.PhysicalLayout = physicalKeyboardLayout; + this.Layout = physicalKeyboardLayout switch { - switch (keyboardLayoutId) - { - //TODO DarthAffe 02.04.2017: Check all available keyboards and there layout-ids - default: - LogicalLayout = CoolerMasterLogicalKeyboardLayout.DE; - break; - } - } - - #endregion + CoolerMasterPhysicalKeyboardLayout.UNINIT => KeyboardLayoutType.Unknown, + CoolerMasterPhysicalKeyboardLayout.US => KeyboardLayoutType.ANSI, + CoolerMasterPhysicalKeyboardLayout.EU => KeyboardLayoutType.ISO, + CoolerMasterPhysicalKeyboardLayout.JP => KeyboardLayoutType.JIS, + _ => KeyboardLayoutType.Unknown + }; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs index 61bee7d2..0548ace2 100644 --- a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs +++ b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseLedMappings.cs @@ -1,55 +1,69 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// Contains all the hardware-id mappings for CoolerMaster devices. +/// +internal static class CoolerMasterMouseLedMappings { + #region Properties & Fields + /// /// Contains all the hardware-id mappings for CoolerMaster devices. /// - internal static class CoolerMasterMouseLedMappings - { - #region Properties & Fields - - /// - /// Contains all the hardware-id mappings for CoolerMaster devices. - /// - // ReSharper disable once InconsistentNaming - public static readonly Dictionary> Mapping = - new Dictionary> - { - { CoolerMasterDevicesIndexes.MasterMouse_L, new Dictionary - { - { LedId.Mouse1, (0,0) }, - { LedId.Mouse2, (0,1) }, - { LedId.Mouse3, (0,2) }, - { LedId.Mouse4, (0,3) } - } - }, - - { CoolerMasterDevicesIndexes.MasterMouse_S, new Dictionary - { - { LedId.Mouse1, (0,0) }, - { LedId.Mouse2, (0,1) } - } - }, - - { CoolerMasterDevicesIndexes.MM530, new Dictionary - { - { LedId.Mouse1, (0,0) }, - { LedId.Mouse2, (0,1) }, - { LedId.Mouse3, (0,2) } - } - }, - - { CoolerMasterDevicesIndexes.MM520, new Dictionary - { - { LedId.Mouse1, (0,0) }, - { LedId.Mouse2, (0,1) }, - { LedId.Mouse3, (0,2) } - } - }, - }; - - #endregion - } -} + // ReSharper disable once InconsistentNaming + public static readonly Dictionary> Mapping = + new() + { + { CoolerMasterDevicesIndexes.MasterMouse_L, new Dictionary + { + { LedId.Mouse1, (0,0) }, + { LedId.Mouse2, (0,1) }, + { LedId.Mouse3, (0,2) }, + { LedId.Mouse4, (0,3) } + } + }, + + { CoolerMasterDevicesIndexes.MasterMouse_S, new Dictionary + { + { LedId.Mouse1, (0,0) }, + { LedId.Mouse2, (0,1) } + } + }, + + { CoolerMasterDevicesIndexes.MM530, new Dictionary + { + { LedId.Mouse1, (0,0) }, + { LedId.Mouse2, (0,1) }, + { LedId.Mouse3, (0,2) } + } + }, + + { CoolerMasterDevicesIndexes.MM520, new Dictionary + { + { LedId.Mouse1, (0,0) }, + { LedId.Mouse2, (0,1) }, + { LedId.Mouse3, (0,2) } + } + }, + + { CoolerMasterDevicesIndexes.MM830, new Dictionary + { + { LedId.Mouse1, (0,0) }, + { LedId.Mouse2, (0,1) }, + { LedId.Mouse3, (0,2) }, + { LedId.Mouse4, (0,3) }, + { LedId.Mouse5, (0,4) }, + { LedId.Mouse6, (0,5) }, + { LedId.Mouse7, (0,6) }, + { LedId.Mouse8, (0,7) }, + { LedId.Mouse9, (0,8) }, + { LedId.Mouse10, (0,9) }, + } + }, + }; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs index a59b1ce0..16ba91c5 100644 --- a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs +++ b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDevice.cs @@ -1,44 +1,42 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// +/// Represents a CoolerMaster mouse. +/// +public class CoolerMasterMouseRGBDevice : CoolerMasterRGBDevice, IMouse { - /// + #region Constructors + + /// /// - /// Represents a CoolerMaster mouse. + /// Initializes a new instance of the class. /// - public class CoolerMasterMouseRGBDevice : CoolerMasterRGBDevice, IMouse + /// The specific information provided by CoolerMaster for the mouse + /// The update trigger used to update this device. + internal CoolerMasterMouseRGBDevice(CoolerMasterMouseRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CoolerMaster for the mouse - internal CoolerMasterMouseRGBDevice(CoolerMasterMouseRGBDeviceInfo info) - : base(info) - { } - - #endregion + InitializeLayout(); + } - #region Methods + #endregion - /// - protected override void InitializeLayout() - { - Dictionary mapping = CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex]; + #region Methods - foreach (KeyValuePair led in mapping) - InitializeLed(led.Key, new Rectangle(led.Value.column * 19, led.Value.row * 19, 19, 19)); + private void InitializeLayout() + { + Dictionary mapping = CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex]; - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\CoolerMaster\Mice", $"{model}.xml"), null); - } + foreach (KeyValuePair led in mapping) + AddLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19, 19)); + } - /// - protected override object CreateLedCustomData(LedId ledId) => CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex][ledId]; + /// + protected override object GetLedCustomData(LedId ledId) => CoolerMasterMouseLedMappings.Mapping[DeviceInfo.DeviceIndex][ledId]; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDeviceInfo.cs b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDeviceInfo.cs index 6d78415e..14f6b0eb 100644 --- a/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDeviceInfo.cs +++ b/RGB.NET.Devices.CoolerMaster/Mouse/CoolerMasterMouseRGBDeviceInfo.cs @@ -1,24 +1,23 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster +namespace RGB.NET.Devices.CoolerMaster; + +/// +/// +/// Represents a generic information for a . +/// +public class CoolerMasterMouseRGBDeviceInfo : CoolerMasterRGBDeviceInfo { + #region Constructors + /// /// - /// Represents a generic information for a . + /// Internal constructor of managed . /// - public class CoolerMasterMouseRGBDeviceInfo : CoolerMasterRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The index of the . - internal CoolerMasterMouseRGBDeviceInfo(CoolerMasterDevicesIndexes deviceIndex) - : base(RGBDeviceType.Mouse, deviceIndex) - { } + /// The index of the . + internal CoolerMasterMouseRGBDeviceInfo(CoolerMasterDevicesIndexes deviceIndex) + : base(RGBDeviceType.Mouse, deviceIndex) + { } - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterColorMatrix.cs b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterColorMatrix.cs index c3d1312a..10ac5932 100644 --- a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterColorMatrix.cs +++ b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterColorMatrix.cs @@ -1,26 +1,25 @@ using System.Runtime.InteropServices; -namespace RGB.NET.Devices.CoolerMaster.Native +namespace RGB.NET.Devices.CoolerMaster.Native; + +// ReSharper disable once InconsistentNaming +internal struct _CoolerMasterColorMatrix { - // ReSharper disable once InconsistentNaming - internal struct _CoolerMasterColorMatrix - { - #region Constants + #region Constants - // ReSharper disable MemberCanBePrivate.Global + // ReSharper disable MemberCanBePrivate.Global - internal const int ROWS = 7; - internal const int COLUMNS = 24; + internal const int ROWS = 8; + internal const int COLUMNS = 24; - // ReSharper restore MemberCanBePrivate.Global + // ReSharper restore MemberCanBePrivate.Global - #endregion + #endregion - #region Properties & Fields + #region Properties & Fields - [MarshalAs(UnmanagedType.ByValArray, SizeConst = ROWS * COLUMNS)] - public _CoolerMasterKeyColor[,] KeyColor; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = ROWS * COLUMNS)] + public _CoolerMasterKeyColor[,] KeyColor; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterKeyColor.cs b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterKeyColor.cs index b8e26eb3..1640361e 100644 --- a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterKeyColor.cs +++ b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterKeyColor.cs @@ -3,28 +3,27 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable NotAccessedField.Global -namespace RGB.NET.Devices.CoolerMaster.Native -{ - // ReSharper disable once InconsistentNaming - internal struct _CoolerMasterKeyColor - { - #region Properties & Fields +namespace RGB.NET.Devices.CoolerMaster.Native; - public byte R; - public byte G; - public byte B; +// ReSharper disable once InconsistentNaming +internal struct _CoolerMasterKeyColor +{ + #region Properties & Fields - #endregion + public byte R; + public byte G; + public byte B; - #region Constructors + #endregion - internal _CoolerMasterKeyColor(byte r, byte g, byte b) - { - this.R = r; - this.G = g; - this.B = b; - } + #region Constructors - #endregion + internal _CoolerMasterKeyColor(byte r, byte g, byte b) + { + this.R = r; + this.G = g; + this.B = b; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs index ac235874..6b51c39a 100644 --- a/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs +++ b/RGB.NET.Devices.CoolerMaster/Native/_CoolerMasterSDK.cs @@ -1,4 +1,5 @@ -// ReSharper disable UnusedMethodReturnValue.Global +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable UnusedMethodReturnValue.Global // ReSharper disable UnusedMember.Global using System; @@ -8,169 +9,180 @@ using System.Runtime.InteropServices; using RGB.NET.Core; -namespace RGB.NET.Devices.CoolerMaster.Native -{ - // ReSharper disable once InconsistentNaming - internal static class _CoolerMasterSDK - { - #region Libary Management +namespace RGB.NET.Devices.CoolerMaster.Native; - private static IntPtr _dllHandle = IntPtr.Zero; +// ReSharper disable once InconsistentNaming +internal static class _CoolerMasterSDK +{ + #region Libary Management - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } + private static IntPtr _handle = IntPtr.Zero; - /// - /// Reloads the SDK. - /// - internal static void Reload() - { - UnloadCMSDK(); - LoadCMSDK(); - } - - private static void LoadCMSDK() + /// + /// Reloads the SDK. + /// + internal static void Reload() + { + if (_handle != IntPtr.Zero) { - if (_dllHandle != IntPtr.Zero) return; - - // HACK: Load library at runtime to support both, x86 and x64 with one managed dll - List possiblePathList = Environment.Is64BitProcess ? CoolerMasterDeviceProvider.PossibleX64NativePaths : CoolerMasterDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); - if (dllPath == null) throw new RGBDeviceException($"Can't find the CoolerMaster-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - - _dllHandle = LoadLibrary(dllPath); - - _getSDKVersionPointer = (GetSDKVersionPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetCM_SDK_DllVer"), typeof(GetSDKVersionPointer)); - _setControlDevicenPointer = (SetControlDevicePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetControlDevice"), typeof(SetControlDevicePointer)); - _isDevicePlugPointer = (IsDevicePlugPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "IsDevicePlug"), typeof(IsDevicePlugPointer)); - _getDeviceLayoutPointer = (GetDeviceLayoutPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "GetDeviceLayout"), typeof(GetDeviceLayoutPointer)); - _enableLedControlPointer = (EnableLedControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "EnableLedControl"), typeof(EnableLedControlPointer)); - _refreshLedPointer = (RefreshLedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "RefreshLed"), typeof(RefreshLedPointer)); - _setLedColorPointer = (SetLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetLedColor"), typeof(SetLedColorPointer)); - _setAllLedColorPointer = (SetAllLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetAllLedColor"), typeof(SetAllLedColorPointer)); + foreach (CoolerMasterDevicesIndexes index in Enum.GetValues(typeof(CoolerMasterDevicesIndexes))) + EnableLedControl(false, index); } + else + LoadCMSDK(); + } - internal static void UnloadCMSDK() - { - if (_dllHandle == IntPtr.Zero) return; - - // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 20.02.2016: We might need to reduce the internal reference counter more than once to set the library free - while (FreeLibrary(_dllHandle)) ; - _dllHandle = IntPtr.Zero; - } + private static void LoadCMSDK() + { + if (_handle != IntPtr.Zero) return; + + // HACK: Load library at runtime to support both, x86 and x64 with one managed dll + List possiblePathList = (Environment.Is64BitProcess ? CoolerMasterDeviceProvider.PossibleX64NativePaths : CoolerMasterDeviceProvider.PossibleX86NativePaths) + .Select(Environment.ExpandEnvironmentVariables) + .ToList(); + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); + if (dllPath == null) throw new RGBDeviceException($"Can't find the CoolerMaster-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); + + _handle = LoadLibrary(dllPath); +#if NET6_0 + if (_handle == IntPtr.Zero) throw new RGBDeviceException($"CoolerMaster LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}"); +#else + if (_handle == IntPtr.Zero) throw new RGBDeviceException($"CoolerMaster LoadLibrary failed with error code {Marshal.GetLastWin32Error()}"); +#endif + + _getSDKVersionPointer = (GetSDKVersionPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "GetCM_SDK_DllVer"), typeof(GetSDKVersionPointer)); + _setControlDevicenPointer = (SetControlDevicePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "SetControlDevice"), typeof(SetControlDevicePointer)); + _isDevicePlugPointer = (IsDevicePlugPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "IsDevicePlug"), typeof(IsDevicePlugPointer)); + _getDeviceLayoutPointer = (GetDeviceLayoutPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "GetDeviceLayout"), typeof(GetDeviceLayoutPointer)); + _enableLedControlPointer = (EnableLedControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "EnableLedControl"), typeof(EnableLedControlPointer)); + _refreshLedPointer = (RefreshLedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "RefreshLed"), typeof(RefreshLedPointer)); + _setLedColorPointer = (SetLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "SetLedColor"), typeof(SetLedColorPointer)); + _setAllLedColorPointer = (SetAllLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_handle, "SetAllLedColor"), typeof(SetAllLedColorPointer)); + } - [DllImport("kernel32.dll")] - private static extern IntPtr LoadLibrary(string dllToLoad); + internal static void UnloadCMSDK() + { + if (_handle == IntPtr.Zero) return; + + _getSDKVersionPointer = null; + _setControlDevicenPointer = null; + _isDevicePlugPointer = null; + _getDeviceLayoutPointer = null; + _enableLedControlPointer = null; + _refreshLedPointer = null; + _setLedColorPointer = null; + _setAllLedColorPointer = null; + + NativeLibrary.Free(_handle); + _handle = IntPtr.Zero; + } - [DllImport("kernel32.dll")] - private static extern bool FreeLibrary(IntPtr dllHandle); + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + private static extern IntPtr LoadLibrary(string dllToLoad); - [DllImport("kernel32.dll")] - private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); + [DllImport("kernel32.dll", CharSet = CharSet.Ansi)] + private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); - #endregion + #endregion - #region SDK-METHODS + #region SDK-METHODS - #region Pointers + #region Pointers - private static GetSDKVersionPointer _getSDKVersionPointer; - private static SetControlDevicePointer _setControlDevicenPointer; - private static IsDevicePlugPointer _isDevicePlugPointer; - private static GetDeviceLayoutPointer _getDeviceLayoutPointer; - private static EnableLedControlPointer _enableLedControlPointer; - private static RefreshLedPointer _refreshLedPointer; - private static SetLedColorPointer _setLedColorPointer; - private static SetAllLedColorPointer _setAllLedColorPointer; + private static GetSDKVersionPointer? _getSDKVersionPointer; + private static SetControlDevicePointer? _setControlDevicenPointer; + private static IsDevicePlugPointer? _isDevicePlugPointer; + private static GetDeviceLayoutPointer? _getDeviceLayoutPointer; + private static EnableLedControlPointer? _enableLedControlPointer; + private static RefreshLedPointer? _refreshLedPointer; + private static SetLedColorPointer? _setLedColorPointer; + private static SetAllLedColorPointer? _setAllLedColorPointer; - #endregion + #endregion - #region Delegates + #region Delegates - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetSDKVersionPointer(); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetSDKVersionPointer(); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void SetControlDevicePointer(CoolerMasterDevicesIndexes devicesIndexes); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate void SetControlDevicePointer(CoolerMasterDevicesIndexes devicesIndexes); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.I1)] - private delegate bool IsDevicePlugPointer(CoolerMasterDevicesIndexes devIndex); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + private delegate bool IsDevicePlugPointer(CoolerMasterDevicesIndexes devIndex); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate CoolerMasterPhysicalKeyboardLayout GetDeviceLayoutPointer(CoolerMasterDevicesIndexes devIndex); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate CoolerMasterPhysicalKeyboardLayout GetDeviceLayoutPointer(CoolerMasterDevicesIndexes devIndex); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.I1)] - private delegate bool EnableLedControlPointer(bool value, CoolerMasterDevicesIndexes devIndex); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + private delegate bool EnableLedControlPointer(bool value, CoolerMasterDevicesIndexes devIndex); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.I1)] - private delegate bool RefreshLedPointer(bool autoRefresh, CoolerMasterDevicesIndexes devIndex); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + private delegate bool RefreshLedPointer(bool autoRefresh, CoolerMasterDevicesIndexes devIndex); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.I1)] - private delegate bool SetLedColorPointer(int row, int column, byte r, byte g, byte b, CoolerMasterDevicesIndexes devIndex); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + private delegate bool SetLedColorPointer(int row, int column, byte r, byte g, byte b, CoolerMasterDevicesIndexes devIndex); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - [return: MarshalAs(UnmanagedType.I1)] - private delegate bool SetAllLedColorPointer(_CoolerMasterColorMatrix colorMatrix, CoolerMasterDevicesIndexes devIndex); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + [return: MarshalAs(UnmanagedType.I1)] + private delegate bool SetAllLedColorPointer(_CoolerMasterColorMatrix colorMatrix, CoolerMasterDevicesIndexes devIndex); - #endregion + #endregion - // ReSharper disable EventExceptionNotDocumented + // ReSharper disable EventExceptionNotDocumented - /// - /// CM-SDK: Get SDK Dll's Version. - /// - internal static int GetSDKVersion() => _getSDKVersionPointer(); + /// + /// CM-SDK: Get SDK Dll's Version. + /// + internal static int GetSDKVersion() => (_getSDKVersionPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(); - /// - /// CM-SDK: set operating device - /// - internal static void SetControlDevice(CoolerMasterDevicesIndexes devicesIndexes) - => _setControlDevicenPointer(devicesIndexes); + /// + /// CM-SDK: set operating device + /// + internal static void SetControlDevice(CoolerMasterDevicesIndexes devicesIndexes) + => (_setControlDevicenPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(devicesIndexes); - /// - /// CM-SDK: verify if the deviced is plugged in - /// - internal static bool IsDevicePlugged(CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _isDevicePlugPointer(devIndex); + /// + /// CM-SDK: verify if the deviced is plugged in + /// + internal static bool IsDevicePlugged(CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) + => (_isDevicePlugPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(devIndex); - /// - /// CM-SDK: Obtain current device layout - /// - internal static CoolerMasterPhysicalKeyboardLayout GetDeviceLayout(CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _getDeviceLayoutPointer(devIndex); + /// + /// CM-SDK: Obtain current device layout + /// + internal static CoolerMasterPhysicalKeyboardLayout GetDeviceLayout(CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) + => (_getDeviceLayoutPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(devIndex); - /// - /// CM-SDK: set control over device’s LED - /// - internal static bool EnableLedControl(bool value, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _enableLedControlPointer(value, devIndex); + /// + /// CM-SDK: set control over device’s LED + /// + internal static bool EnableLedControl(bool value, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) + => (_enableLedControlPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(value, devIndex); - /// - /// CM-SDK: Print out the lights setting from Buffer to LED - /// - internal static bool RefreshLed(bool autoRefresh, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _refreshLedPointer(autoRefresh, devIndex); + /// + /// CM-SDK: Print out the lights setting from Buffer to LED + /// + internal static bool RefreshLed(bool autoRefresh, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) + => (_refreshLedPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(autoRefresh, devIndex); - /// - /// CM-SDK: Set single Key LED color - /// - internal static bool SetLedColor(int row, int column, byte r, byte g, byte b, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _setLedColorPointer(row, column, r, g, b, devIndex); + /// + /// CM-SDK: Set single Key LED color + /// + internal static bool SetLedColor(int row, int column, byte r, byte g, byte b, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) + => (_setLedColorPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(row, column, r, g, b, devIndex); - /// - /// CM-SDK: Set Keyboard "every LED" color - /// - internal static bool SetAllLedColor(_CoolerMasterColorMatrix colorMatrix, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) - => _setAllLedColorPointer(colorMatrix, devIndex); + /// + /// CM-SDK: Set Keyboard "every LED" color + /// + internal static bool SetAllLedColor(_CoolerMasterColorMatrix colorMatrix, CoolerMasterDevicesIndexes devIndex = CoolerMasterDevicesIndexes.Default) + => (_setAllLedColorPointer ?? throw new RGBDeviceException("The CoolerMaster-SDK is not initialized.")).Invoke(colorMatrix, devIndex); - // ReSharper restore EventExceptionNotDocumented + // ReSharper restore EventExceptionNotDocumented - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/README.md b/RGB.NET.Devices.CoolerMaster/README.md new file mode 100644 index 00000000..850fc72c --- /dev/null +++ b/RGB.NET.Devices.CoolerMaster/README.md @@ -0,0 +1,24 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for Cooler Master-Devices. + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(CoolerMasterDeviceProvider.Instance); +``` + +# Required SDK +This providers requires native SDK-dlls. +You can get them directly from Cooler Master at [https://templates.coolermaster.com/](https://templates.coolermaster.com/) (Direct Link: [https://templates.coolermaster.com/assets/sdk/coolermaster-sdk.zip](https://templates.coolermaster.com/assets/sdk/coolermaster-sdk.zip)) + +Since the SDK-dlls are native it's important to use the correct architecture you're building your application for. (If in doubt you can always include both.) + +### x64 +`Src\SDK\x64\SDKDLL.dll` from the SDK-zip needs to be distributed as `\x64\CMSDK.dll` + +You can use other, custom paths by adding them to `CoolerMasterDeviceProvider.PossibleX64NativePaths`. + +### x86 +`Src\SDK\x86\SDKDLL.dll` from the SDK-zip needs to be distributed as `\x86\CMSDK.dll` + +You can use other, custom paths by adding them to `CoolerMasterDeviceProvider.PossibleX86NativePaths`. diff --git a/RGB.NET.Devices.CoolerMaster/RGB.NET.Devices.CoolerMaster.csproj b/RGB.NET.Devices.CoolerMaster/RGB.NET.Devices.CoolerMaster.csproj index aa5d87f9..d4812ed2 100644 --- a/RGB.NET.Devices.CoolerMaster/RGB.NET.Devices.CoolerMaster.csproj +++ b/RGB.NET.Devices.CoolerMaster/RGB.NET.Devices.CoolerMaster.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.CoolerMaster Cooler Master-Device-Implementations of RGB.NET Cooler Master-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,36 +35,28 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + - - + + \ No newline at end of file diff --git a/RGB.NET.Devices.CoolerMaster/RGB.NET.Devices.CoolerMaster.csproj.DotSettings b/RGB.NET.Devices.CoolerMaster/RGB.NET.Devices.CoolerMaster.csproj.DotSettings index 44309b11..1590a7c0 100644 --- a/RGB.NET.Devices.CoolerMaster/RGB.NET.Devices.CoolerMaster.csproj.DotSettings +++ b/RGB.NET.Devices.CoolerMaster/RGB.NET.Devices.CoolerMaster.csproj.DotSettings @@ -3,4 +3,5 @@ True True True - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs index 74ac4ec0..7acd75e4 100644 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs +++ b/RGB.NET.Devices.Corsair/CorsairDeviceProvider.cs @@ -3,303 +3,213 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; +using System.Linq; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a device provider responsible for corsair (CUE) devices. +/// +public class CorsairDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static CorsairDeviceProvider? _instance; /// - /// Represents a device provider responsible for corsair (CUE) devices. + /// Gets the singleton instance. /// - public class CorsairDeviceProvider : IRGBDeviceProvider - { - #region Properties & Fields - - private static CorsairDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static CorsairDeviceProvider Instance => _instance ?? new CorsairDeviceProvider(); - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. - /// The first match will be used. - /// - public static List PossibleX86NativePaths { get; } = new List { "x86/CUESDK.dll", "x86/CUESDK_2015.dll", "x86/CUESDK_2013.dll" }; - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. - /// The first match will be used. - /// - public static List PossibleX64NativePaths { get; } = new List { "x64/CUESDK.dll", "x64/CUESDK_2015.dll", "x64/CUESDK_2013.dll" }; - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _CUESDK.LoadedArchitecture; - - /// - /// Gets the protocol details for the current SDK-connection. - /// - public CorsairProtocolDetails ProtocolDetails { get; private set; } - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } - - /// - /// Gets the last error documented by CUE. - /// - public CorsairError LastError => _CUESDK.CorsairGetLastError(); - - /// - public IEnumerable Devices { get; private set; } - - /// - /// The used to trigger the updates for corsair devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public CorsairDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(CorsairDeviceProvider)}"); - _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); - } - - #endregion - - #region Methods - - /// - /// Thrown if the SDK is already initialized or if the SDK is not compatible to CUE. - /// Thrown if the CUE-SDK provides an error. - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - IsInitialized = false; - - try - { - UpdateTrigger?.Stop(); + public static CorsairDeviceProvider Instance => _instance ?? new CorsairDeviceProvider(); - _CUESDK.Reload(); - - ProtocolDetails = new CorsairProtocolDetails(_CUESDK.CorsairPerformProtocolHandshake()); + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. + /// The first match will be used. + /// + public static List PossibleX86NativePaths { get; } = new() { "x86/CUESDK.dll", "x86/CUESDK_2019.dll", "x86/CUESDK_2017.dll", "x86/CUESDK_2015.dll", "x86/CUESDK_2013.dll" }; - CorsairError error = LastError; - if (error != CorsairError.Success) - throw new CUEException(error); + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. + /// The first match will be used. + /// + public static List PossibleX64NativePaths { get; } = new() { "x64/CUESDK.dll", "x64/CUESDK.x64_2019.dll", "x64/CUESDK.x64_2017.dll", "x64/CUESDK_2019.dll", "x64/CUESDK_2017.dll", "x64/CUESDK_2015.dll", "x64/CUESDK_2013.dll" }; - if (ProtocolDetails.BreakingChanges) - throw new RGBDeviceException("The SDK currently used isn't compatible with the installed version of CUE.\r\n" - + $"CUE-Version: {ProtocolDetails.ServerVersion} (Protocol {ProtocolDetails.ServerProtocolVersion})\r\n" - + $"SDK-Version: {ProtocolDetails.SdkVersion} (Protocol {ProtocolDetails.SdkProtocolVersion})"); + /// + /// Gets the protocol details for the current SDK-connection. + /// + public CorsairProtocolDetails? ProtocolDetails { get; private set; } - if (exclusiveAccessIfPossible) - { - if (!_CUESDK.CorsairRequestControl(CorsairAccessMode.ExclusiveLightingControl)) - throw new CUEException(LastError); + /// + /// Gets the last error documented by CUE. + /// + public static CorsairError LastError => _CUESDK.CorsairGetLastError(); - HasExclusiveAccess = true; - } - else - HasExclusiveAccess = false; + #endregion - // DarthAffe 07.07.2018: 127 is CUE, we want to directly compete with it as in older versions. - if (!_CUESDK.CorsairSetLayerPriority(127)) - throw new CUEException(LastError); + #region Constructors - Dictionary modelCounter = new Dictionary(); - IList devices = new List(); - int deviceCount = _CUESDK.CorsairGetDeviceCount(); - for (int i = 0; i < deviceCount; i++) - { - try - { - _CorsairDeviceInfo nativeDeviceInfo = (_CorsairDeviceInfo)Marshal.PtrToStructure(_CUESDK.CorsairGetDeviceInfo(i), typeof(_CorsairDeviceInfo)); - CorsairRGBDeviceInfo info = new CorsairRGBDeviceInfo(i, RGBDeviceType.Unknown, nativeDeviceInfo, modelCounter); - if (!info.CapsMask.HasFlag(CorsairDeviceCaps.Lighting)) - continue; // Everything that doesn't support lighting control is useless + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public CorsairDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(CorsairDeviceProvider)}"); + _instance = this; + } - CorsairDeviceUpdateQueue deviceUpdateQueue = null; - foreach (ICorsairRGBDevice device in GetRGBDevice(info, i, nativeDeviceInfo, modelCounter)) - { - if ((device == null) || !loadFilter.HasFlag(device.DeviceInfo.DeviceType)) continue; + #endregion - if (deviceUpdateQueue == null) - deviceUpdateQueue = new CorsairDeviceUpdateQueue(UpdateTrigger, info.CorsairDeviceIndex); + #region Methods - device.Initialize(deviceUpdateQueue); - AddSpecialParts(device); + /// + protected override void InitializeSDK() + { + _CUESDK.Reload(); - error = LastError; - if (error != CorsairError.Success) - throw new CUEException(error); + ProtocolDetails = new CorsairProtocolDetails(_CUESDK.CorsairPerformProtocolHandshake()); - devices.Add(device); - } - } - catch { if (throwExceptions) throw; } - } + CorsairError error = LastError; + if (error != CorsairError.Success) + Throw(new CUEException(error), true); - UpdateTrigger?.Start(); + if (ProtocolDetails.BreakingChanges) + Throw(new RGBDeviceException("The SDK currently used isn't compatible with the installed version of CUE.\r\n" + + $"CUE-Version: {ProtocolDetails.ServerVersion} (Protocol {ProtocolDetails.ServerProtocolVersion})\r\n" + + $"SDK-Version: {ProtocolDetails.SdkVersion} (Protocol {ProtocolDetails.SdkProtocolVersion})"), true); - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - Reset(); - if (throwExceptions) throw; - return false; - } + // DarthAffe 02.02.2021: 127 is iCUE + if (!_CUESDK.CorsairSetLayerPriority(128)) + Throw(new CUEException(LastError)); + } - return true; + /// + protected override IEnumerable LoadDevices() + { + foreach (ICorsairRGBDevice corsairDevice in LoadCorsairDevices()) + { + corsairDevice.Initialize(); + yield return corsairDevice; } + } - private static IEnumerable GetRGBDevice(CorsairRGBDeviceInfo info, int i, _CorsairDeviceInfo nativeDeviceInfo, Dictionary modelCounter) + private IEnumerable LoadCorsairDevices() + { + int deviceCount = _CUESDK.CorsairGetDeviceCount(); + for (int i = 0; i < deviceCount; i++) { - switch (info.CorsairDeviceType) + _CorsairDeviceInfo nativeDeviceInfo = (_CorsairDeviceInfo)Marshal.PtrToStructure(_CUESDK.CorsairGetDeviceInfo(i), typeof(_CorsairDeviceInfo))!; + if (!((CorsairDeviceCaps)nativeDeviceInfo.capsMask).HasFlag(CorsairDeviceCaps.Lighting)) + continue; // Everything that doesn't support lighting control is useless + + CorsairDeviceUpdateQueue updateQueue = new(GetUpdateTrigger(), i); + switch (nativeDeviceInfo.type) { case CorsairDeviceType.Keyboard: - yield return new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); + yield return new CorsairKeyboardRGBDevice(new CorsairKeyboardRGBDeviceInfo(i, nativeDeviceInfo), updateQueue); break; case CorsairDeviceType.Mouse: - yield return new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); + yield return new CorsairMouseRGBDevice(new CorsairMouseRGBDeviceInfo(i, nativeDeviceInfo), updateQueue); break; case CorsairDeviceType.Headset: - yield return new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); + yield return new CorsairHeadsetRGBDevice(new CorsairHeadsetRGBDeviceInfo(i, nativeDeviceInfo), updateQueue); break; case CorsairDeviceType.Mousepad: - yield return new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); + yield return new CorsairMousepadRGBDevice(new CorsairMousepadRGBDeviceInfo(i, nativeDeviceInfo), updateQueue); break; case CorsairDeviceType.HeadsetStand: - yield return new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); + yield return new CorsairHeadsetStandRGBDevice(new CorsairHeadsetStandRGBDeviceInfo(i, nativeDeviceInfo), updateQueue); break; case CorsairDeviceType.MemoryModule: - yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(i, nativeDeviceInfo, modelCounter)); + yield return new CorsairMemoryRGBDevice(new CorsairMemoryRGBDeviceInfo(i, nativeDeviceInfo), updateQueue); break; - case CorsairDeviceType.Cooler: - case CorsairDeviceType.CommanderPro: - case CorsairDeviceType.LightningNodePro: - _CorsairChannelsInfo channelsInfo = nativeDeviceInfo.channels; - if (channelsInfo != null) - { - IntPtr channelInfoPtr = channelsInfo.channels; + case CorsairDeviceType.Mainboard: + yield return new CorsairMainboardRGBDevice(new CorsairMainboardRGBDeviceInfo(i, nativeDeviceInfo), updateQueue); + break; - for (int channel = 0; channel < channelsInfo.channelsCount; channel++) - { - CorsairLedId referenceLed = GetChannelReferenceId(info.CorsairDeviceType, channel); - if (referenceLed == CorsairLedId.Invalid) continue; + case CorsairDeviceType.GraphicsCard: + yield return new CorsairGraphicsCardRGBDevice(new CorsairGraphicsCardRGBDeviceInfo(i, nativeDeviceInfo), updateQueue); + break; - _CorsairChannelInfo channelInfo = (_CorsairChannelInfo)Marshal.PtrToStructure(channelInfoPtr, typeof(_CorsairChannelInfo)); + case CorsairDeviceType.Touchbar: + yield return new CorsairTouchbarRGBDevice(new CorsairTouchbarRGBDeviceInfo(i, nativeDeviceInfo), updateQueue); + break; - int channelDeviceInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelDeviceInfo)); - IntPtr channelDeviceInfoPtr = channelInfo.devices; + case CorsairDeviceType.Cooler: + case CorsairDeviceType.CommanderPro: + case CorsairDeviceType.LightningNodePro: + List<_CorsairChannelInfo> channels = GetChannels(nativeDeviceInfo).ToList(); + int channelsLedCount = channels.Sum(x => x.totalLedsCount); + int deviceLedCount = nativeDeviceInfo.ledsCount - channelsLedCount; - for (int device = 0; device < channelInfo.devicesCount; device++) - { - _CorsairChannelDeviceInfo channelDeviceInfo = (_CorsairChannelDeviceInfo)Marshal.PtrToStructure(channelDeviceInfoPtr, typeof(_CorsairChannelDeviceInfo)); + if (deviceLedCount > 0) + yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(i, nativeDeviceInfo, deviceLedCount), updateQueue); - yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(info, nativeDeviceInfo, channelDeviceInfo, referenceLed, modelCounter)); - referenceLed += channelDeviceInfo.deviceLedCount; + int ledOffset = deviceLedCount; + foreach (_CorsairChannelInfo channelInfo in channels) + { + int channelDeviceInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelDeviceInfo)); + IntPtr channelDeviceInfoPtr = channelInfo.devices; + for (int device = 0; (device < channelInfo.devicesCount) && (ledOffset < nativeDeviceInfo.ledsCount); device++) + { + _CorsairChannelDeviceInfo channelDeviceInfo = (_CorsairChannelDeviceInfo)Marshal.PtrToStructure(channelDeviceInfoPtr, typeof(_CorsairChannelDeviceInfo))!; - channelDeviceInfoPtr = new IntPtr(channelDeviceInfoPtr.ToInt64() + channelDeviceInfoStructSize); - } + yield return new CorsairCustomRGBDevice(new CorsairCustomRGBDeviceInfo(i, nativeDeviceInfo, channelDeviceInfo, ledOffset), updateQueue); - int channelInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelInfo)); - channelInfoPtr = new IntPtr(channelInfoPtr.ToInt64() + channelInfoStructSize); + ledOffset += channelDeviceInfo.deviceLedCount; + channelDeviceInfoPtr = new IntPtr(channelDeviceInfoPtr.ToInt64() + channelDeviceInfoStructSize); } } - break; - - // ReSharper disable once RedundantCaseLabel - case CorsairDeviceType.Unknown: default: - throw new RGBDeviceException("Unknown Device-Type"); + Throw(new RGBDeviceException("Unknown Device-Type")); + break; } } + } - private static CorsairLedId GetChannelReferenceId(CorsairDeviceType deviceType, int channel) - { - if (deviceType == CorsairDeviceType.Cooler) - return CorsairLedId.CustomLiquidCoolerChannel1Led1; - else - { - switch (channel) - { - case 0: return CorsairLedId.CustomDeviceChannel1Led1; - case 1: return CorsairLedId.CustomDeviceChannel2Led1; - case 2: return CorsairLedId.CustomDeviceChannel3Led1; - } - } - - return CorsairLedId.Invalid; - } + private static IEnumerable<_CorsairChannelInfo> GetChannels(_CorsairDeviceInfo deviceInfo) + { + _CorsairChannelsInfo? channelsInfo = deviceInfo.channels; + if (channelsInfo == null) yield break; - private void AddSpecialParts(ICorsairRGBDevice device) + IntPtr channelInfoPtr = channelsInfo.channels; + for (int channel = 0; channel < channelsInfo.channelsCount; channel++) { - if (device.DeviceInfo.Model.Equals("K95 RGB Platinum", StringComparison.OrdinalIgnoreCase)) - device.AddSpecialDevicePart(new LightbarSpecialPart(device)); - } + yield return (_CorsairChannelInfo)Marshal.PtrToStructure(channelInfoPtr, typeof(_CorsairChannelInfo))!; - /// - public void ResetDevices() - { - if (IsInitialized) - try - { - _CUESDK.Reload(); - } - catch {/* shit happens */} + int channelInfoStructSize = Marshal.SizeOf(typeof(_CorsairChannelInfo)); + channelInfoPtr = new IntPtr(channelInfoPtr.ToInt64() + channelInfoStructSize); } + } - private void Reset() - { - ProtocolDetails = null; - HasExclusiveAccess = false; - Devices = null; - IsInitialized = false; - } + /// + protected override void Reset() + { + ProtocolDetails = null; - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } + base.Reset(); + } - try { _CUESDK.UnloadCUESDK(); } - catch { /* at least we tried */ } - } + /// + public override void Dispose() + { + base.Dispose(); - #endregion + try { _CUESDK.UnloadCUESDK(); } + catch { /* at least we tried */ } + + GC.SuppressFinalize(this); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/CorsairDeviceProviderLoader.cs b/RGB.NET.Devices.Corsair/CorsairDeviceProviderLoader.cs deleted file mode 100644 index 4a1aa545..00000000 --- a/RGB.NET.Devices.Corsair/CorsairDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - /// - /// Represents a device provider loaded used to dynamically load corsair devices into an application. - /// - public class CorsairDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => CorsairDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs index 58546238..1bc3b6e8 100644 --- a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDevice.cs @@ -1,75 +1,74 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System.Collections.Generic; +using System; +using System.Runtime.InteropServices; using RGB.NET.Core; +using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair custom. +/// +public class CorsairCustomRGBDevice : CorsairRGBDevice, IUnknownDevice { - /// + #region Constructors + + /// /// - /// Represents a corsair custom. + /// Initializes a new instance of the class. /// - public class CorsairCustomRGBDevice : CorsairRGBDevice, IUnknownDevice - { - #region Properties & Fields - - private readonly Dictionary _idMapping = new Dictionary(); + /// The specific information provided by CUE for the custom-device. + /// The queue used to update this device. + internal CorsairCustomRGBDevice(CorsairCustomRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, new LedMapping(), updateQueue) + { } - #endregion + #endregion - #region Constructors + #region Methods - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the custom-device. - internal CorsairCustomRGBDevice(CorsairCustomRGBDeviceInfo info) - : base(info) - { } + /// + protected override void InitializeLayout() + { + Mapping.Clear(); - #endregion + _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + if (nativeLedPositions == null) return; - #region Methods + int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); + IntPtr ptr = new(nativeLedPositions.pLedPosition.ToInt64() + (structSize * DeviceInfo.LedOffset)); - /// - protected override void InitializeLayout() + LedId referenceLedId = GetReferenceLed(DeviceInfo.DeviceType); + for (int i = 0; i < DeviceInfo.LedCount; i++) { - LedId referenceId = GetReferenceLed(DeviceInfo.DeviceType); - - for (int i = 0; i < DeviceInfo.LedCount; i++) + LedId ledId = referenceLedId + i; + _CorsairLedPosition? ledPosition = (_CorsairLedPosition?)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); + if (ledPosition == null) { - LedId ledId = referenceId + i; - _idMapping.Add(ledId, DeviceInfo.ReferenceCorsairLed + i); - InitializeLed(ledId, new Rectangle(i * 10, 0, 10, 10)); + ptr = new IntPtr(ptr.ToInt64() + structSize); + continue; } - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Customs", $"{model}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => _idMapping.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; + Mapping.Add(ledId, ledPosition.LedId); - protected virtual LedId GetReferenceLed(RGBDeviceType deviceType) - { - switch (deviceType) - { - case RGBDeviceType.LedStripe: - return LedId.LedStripe1; - - case RGBDeviceType.Fan: - return LedId.Fan1; - - case RGBDeviceType.Cooler: - return LedId.Cooler1; + Rectangle rectangle = ledPosition.ToRectangle(); + AddLed(ledId, rectangle.Location, rectangle.Size); - default: - return LedId.Custom1; - } + ptr = new IntPtr(ptr.ToInt64() + structSize); } - - #endregion } -} + + private static LedId GetReferenceLed(RGBDeviceType deviceType) + => deviceType switch + { + RGBDeviceType.LedStripe => LedId.LedStripe1, + RGBDeviceType.Fan => LedId.Fan1, + RGBDeviceType.Cooler => LedId.Cooler1, + _ => LedId.Custom1 + }; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDeviceInfo.cs index 72485be7..5d0858a8 100644 --- a/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Custom/CorsairCustomRGBDeviceInfo.cs @@ -2,126 +2,154 @@ // ReSharper disable UnusedMember.Global using System; -using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text.RegularExpressions; using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a . +/// +public class CorsairCustomRGBDeviceInfo : CorsairRGBDeviceInfo { + #region Properties & Fields + + /// + /// Gets the amount of LEDs this device contains. + /// + public int LedCount { get; } + + /// + /// Gets the offset used to access the LEDs of this device. + /// + internal int LedOffset { get; } + + #endregion + + #region Constructors + /// /// - /// Represents a generic information for a . + /// Internal constructor of managed . /// - public class CorsairCustomRGBDeviceInfo : CorsairRGBDeviceInfo + /// The index of the . + /// The native -struct + /// The native representing this device. + /// The offset used to find the LEDs of this device. + internal CorsairCustomRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo, _CorsairChannelDeviceInfo channelDeviceInfo, int ledOffset) + : base(deviceIndex, GetDeviceType(channelDeviceInfo.type), nativeInfo, + GetModelName(nativeInfo.model == IntPtr.Zero ? string.Empty : Regex.Replace(Marshal.PtrToStringAnsi(nativeInfo.model) ?? string.Empty, " ?DEMO", string.Empty, RegexOptions.IgnoreCase), channelDeviceInfo)) { - #region Properties & Fields - - public CorsairLedId ReferenceCorsairLed { get; } - public int LedCount { get; } - - #endregion - - #region Constructors - - //TODO DarthAffe 07.07.2018: DAP is a fan right now, that's most likely wrong - /// - /// - /// Internal constructor of managed . - /// - /// The info describing the the . - /// The native -struct - /// The native representing this device. - /// The id of the first led of this device. - /// A dictionary containing counters to create unique names for equal devices models. - internal CorsairCustomRGBDeviceInfo(CorsairRGBDeviceInfo info, _CorsairDeviceInfo nativeInfo, - _CorsairChannelDeviceInfo channelDeviceInfo, - CorsairLedId referenceCorsairLed, Dictionary modelCounter) - : base(info.CorsairDeviceIndex, GetDeviceType(channelDeviceInfo.type), nativeInfo, - GetModelName(info, channelDeviceInfo), modelCounter) - { - this.ReferenceCorsairLed = referenceCorsairLed; + this.LedOffset = ledOffset; - LedCount = channelDeviceInfo.deviceLedCount; - } + LedCount = channelDeviceInfo.deviceLedCount; + } + + internal CorsairCustomRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo, int ledCount) + : base(deviceIndex, GetDeviceType(nativeInfo.type), nativeInfo) + { + this.LedCount = ledCount; - #endregion + LedOffset = 0; + } - #region Methods + #endregion - private static RGBDeviceType GetDeviceType(CorsairChannelDeviceType deviceType) - { - switch (deviceType) - { - case CorsairChannelDeviceType.Invalid: - return RGBDeviceType.Unknown; - - case CorsairChannelDeviceType.FanHD: - case CorsairChannelDeviceType.FanSP: - case CorsairChannelDeviceType.FanLL: - case CorsairChannelDeviceType.FanML: - case CorsairChannelDeviceType.DAP: - case CorsairChannelDeviceType.FanQL: - return RGBDeviceType.Fan; - - case CorsairChannelDeviceType.Strip: - return RGBDeviceType.LedStripe; - - case CorsairChannelDeviceType.Pump: - return RGBDeviceType.Cooler; - - default: - throw new ArgumentOutOfRangeException(nameof(deviceType), deviceType, null); - } - } + #region Methods - private static string GetModelName(IRGBDeviceInfo info, _CorsairChannelDeviceInfo channelDeviceInfo) + private static RGBDeviceType GetDeviceType(CorsairChannelDeviceType deviceType) + => deviceType switch { - switch (channelDeviceInfo.type) - { - case CorsairChannelDeviceType.Invalid: - return "Invalid"; - - case CorsairChannelDeviceType.FanHD: - return "HD Fan"; - - case CorsairChannelDeviceType.FanSP: - return "SP Fan"; - - case CorsairChannelDeviceType.FanLL: - return "LL Fan"; - - case CorsairChannelDeviceType.FanML: - return "ML Fan"; - - case CorsairChannelDeviceType.Strip: - // LS100 Led Strips are reported as one big strip if configured in monitor mode in iCUE, 138 LEDs for dual monitor, 84 for single - if ((info.Model == "LS100 Starter Kit") && (channelDeviceInfo.deviceLedCount == 138)) - return "LS100 LED Strip (dual monitor)"; - else if ((info.Model == "LS100 Starter Kit") && (channelDeviceInfo.deviceLedCount == 84)) - return "LS100 LED Strip (single monitor)"; - // Any other value means an "External LED Strip" in iCUE, these are reported per-strip, 15 for short strips, 27 for long - else if ((info.Model == "LS100 Starter Kit") && (channelDeviceInfo.deviceLedCount == 15)) - return "LS100 LED Strip (short)"; - else if ((info.Model == "LS100 Starter Kit") && (channelDeviceInfo.deviceLedCount == 27)) - return "LS100 LED Strip (long)"; - // Device model is "Commander Pro" for regular LED strips - else - return "LED Strip"; - - case CorsairChannelDeviceType.DAP: - return "DAP Fan"; - - case CorsairChannelDeviceType.Pump: - return "Pump"; - - case CorsairChannelDeviceType.FanQL: - return "QL Fan"; - - default: - throw new ArgumentOutOfRangeException(nameof(channelDeviceInfo.type), channelDeviceInfo.type, null); - } + CorsairChannelDeviceType.Invalid => RGBDeviceType.Unknown, + CorsairChannelDeviceType.FanHD => RGBDeviceType.Fan, + CorsairChannelDeviceType.FanSP => RGBDeviceType.Fan, + CorsairChannelDeviceType.FanLL => RGBDeviceType.Fan, + CorsairChannelDeviceType.FanML => RGBDeviceType.Fan, + CorsairChannelDeviceType.DAP => RGBDeviceType.Fan, + CorsairChannelDeviceType.FanQL => RGBDeviceType.Fan, + CorsairChannelDeviceType.EightLedSeriesFan => RGBDeviceType.Fan, + CorsairChannelDeviceType.Strip => RGBDeviceType.LedStripe, + CorsairChannelDeviceType.Pump => RGBDeviceType.Cooler, + CorsairChannelDeviceType.WaterBlock => RGBDeviceType.Cooler, + _ => throw new ArgumentOutOfRangeException(nameof(deviceType), deviceType, null) + }; + + private static RGBDeviceType GetDeviceType(CorsairDeviceType deviceType) + => deviceType switch + { + CorsairDeviceType.Unknown => RGBDeviceType.Unknown, + CorsairDeviceType.Mouse => RGBDeviceType.Mouse, + CorsairDeviceType.Keyboard => RGBDeviceType.Keyboard, + CorsairDeviceType.Headset => RGBDeviceType.Headset, + CorsairDeviceType.Mousepad => RGBDeviceType.Mousepad, + CorsairDeviceType.HeadsetStand => RGBDeviceType.HeadsetStand, + CorsairDeviceType.CommanderPro => RGBDeviceType.LedController, + CorsairDeviceType.LightningNodePro => RGBDeviceType.LedController, + CorsairDeviceType.MemoryModule => RGBDeviceType.DRAM, + CorsairDeviceType.Cooler => RGBDeviceType.Cooler, + CorsairDeviceType.Mainboard => RGBDeviceType.Mainboard, + CorsairDeviceType.GraphicsCard => RGBDeviceType.GraphicsCard, + _ => throw new ArgumentOutOfRangeException(nameof(deviceType), deviceType, null) + }; + + private static string GetModelName(string model, _CorsairChannelDeviceInfo channelDeviceInfo) + { + switch (channelDeviceInfo.type) + { + case CorsairChannelDeviceType.Invalid: + return model; + + case CorsairChannelDeviceType.FanHD: + return "HD Fan"; + + case CorsairChannelDeviceType.FanSP: + return "SP Fan"; + + case CorsairChannelDeviceType.FanLL: + return "LL Fan"; + + case CorsairChannelDeviceType.FanML: + return "ML Fan"; + + case CorsairChannelDeviceType.FanQL: + return "QL Fan"; + + case CorsairChannelDeviceType.EightLedSeriesFan: + return "8-Led-Series Fan Fan"; + + case CorsairChannelDeviceType.Strip: + // LS100 Led Strips are reported as one big strip if configured in monitor mode in iCUE, 138 LEDs for dual monitor, 84 for single + if ((model == "LS100 Starter Kit") && (channelDeviceInfo.deviceLedCount == 138)) + return "LS100 LED Strip (dual monitor)"; + else if ((model == "LS100 Starter Kit") && (channelDeviceInfo.deviceLedCount == 84)) + return "LS100 LED Strip (single monitor)"; + // Any other value means an "External LED Strip" in iCUE, these are reported per-strip, 15 for short strips, 27 for long + else if ((model == "LS100 Starter Kit") && (channelDeviceInfo.deviceLedCount == 15)) + return "LS100 LED Strip (short)"; + else if ((model == "LS100 Starter Kit") && (channelDeviceInfo.deviceLedCount == 27)) + return "LS100 LED Strip (long)"; + // Device model is "Commander Pro" for regular LED strips + else + return "LED Strip"; + + case CorsairChannelDeviceType.DAP: + return "DAP Fan"; + + case CorsairChannelDeviceType.WaterBlock: + return "Water Block"; + + case CorsairChannelDeviceType.Pump: + return "Pump"; + + default: +#pragma warning disable CA2208 // Instantiate argument exceptions correctly + throw new ArgumentOutOfRangeException($"{nameof(channelDeviceInfo)}.{nameof(channelDeviceInfo.type)}", channelDeviceInfo.type, null); +#pragma warning restore CA2208 // Instantiate argument exceptions correctly } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairAccessMode.cs b/RGB.NET.Devices.Corsair/Enum/CorsairAccessMode.cs index af8a87c2..1ecdda4b 100644 --- a/RGB.NET.Devices.Corsair/Enum/CorsairAccessMode.cs +++ b/RGB.NET.Devices.Corsair/Enum/CorsairAccessMode.cs @@ -3,13 +3,12 @@ #pragma warning disable 1591 // Missing XML comment for publicly visible type or member -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Represents an SDK access mode. +/// +public enum CorsairAccessMode { - /// - /// Contains list of available SDK access modes. - /// - public enum CorsairAccessMode - { - ExclusiveLightingControl = 0 - }; -} + ExclusiveLightingControl = 0 +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairChannelDeviceType.cs b/RGB.NET.Devices.Corsair/Enum/CorsairChannelDeviceType.cs index f57e5b2f..8c89470c 100644 --- a/RGB.NET.Devices.Corsair/Enum/CorsairChannelDeviceType.cs +++ b/RGB.NET.Devices.Corsair/Enum/CorsairChannelDeviceType.cs @@ -4,21 +4,22 @@ #pragma warning disable 1591 // Missing XML comment for publicly visible type or member -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Contains a list of available corsair channel device types. +/// +public enum CorsairChannelDeviceType { - /// - /// Contains list of available corsair channel device types. - /// - public enum CorsairChannelDeviceType - { - Invalid = 0, - FanHD = 1, - FanSP = 2, - FanLL = 3, - FanML = 4, - Strip = 5, - DAP = 6, - Pump = 7, - FanQL = 8 - }; -} + Invalid = 0, + FanHD = 1, + FanSP = 2, + FanLL = 3, + FanML = 4, + Strip = 5, + DAP = 6, + Pump = 7, + FanQL = 8, + WaterBlock = 9, + EightLedSeriesFan = 10 // Previously called FanSPPRO +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairDeviceCaps.cs b/RGB.NET.Devices.Corsair/Enum/CorsairDeviceCaps.cs index 4d496266..c92807bd 100644 --- a/RGB.NET.Devices.Corsair/Enum/CorsairDeviceCaps.cs +++ b/RGB.NET.Devices.Corsair/Enum/CorsairDeviceCaps.cs @@ -3,27 +3,26 @@ using System; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Contains a list of corsair device capabilities. +/// +[Flags] +public enum CorsairDeviceCaps { /// - /// Contains list of corsair device capabilities. + /// For devices that do not support any SDK functions. /// - [Flags] - public enum CorsairDeviceCaps - { - /// - /// For devices that do not support any SDK functions. - /// - None = 0, + None = 0, - /// - /// For devices that has controlled lighting. - /// - Lighting = 1, + /// + /// For devices that has controlled lighting. + /// + Lighting = 1, - /// - /// For devices that provide current state through set of properties. - /// - PropertyLookup = 2 - }; -} + /// + /// For devices that provide current state through set of properties. + /// + PropertyLookup = 2 +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairDeviceType.cs b/RGB.NET.Devices.Corsair/Enum/CorsairDeviceType.cs index 52bb8511..a409c5d5 100644 --- a/RGB.NET.Devices.Corsair/Enum/CorsairDeviceType.cs +++ b/RGB.NET.Devices.Corsair/Enum/CorsairDeviceType.cs @@ -4,24 +4,24 @@ #pragma warning disable 1591 // Missing XML comment for publicly visible type or member -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Contains a list of available corsair device types. +/// +public enum CorsairDeviceType { - /// - /// Contains list of available corsair device types. - /// - public enum CorsairDeviceType - { - Unknown = 0, - Mouse = 1, - Keyboard = 2, - Headset = 3, - Mousepad = 4, - HeadsetStand = 5, - CommanderPro = 6, - LightningNodePro = 7, - MemoryModule = 8, - Cooler = 9, - Mainboard = 10, - GraphicsCard = 11 - }; -} + Unknown = 0, + Mouse = 1, + Keyboard = 2, + Headset = 3, + Mousepad = 4, + HeadsetStand = 5, + CommanderPro = 6, + LightningNodePro = 7, + MemoryModule = 8, + Cooler = 9, + Mainboard = 10, + GraphicsCard = 11, + Touchbar = 12 +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairError.cs b/RGB.NET.Devices.Corsair/Enum/CorsairError.cs index e0ae1c98..977c2cf5 100644 --- a/RGB.NET.Devices.Corsair/Enum/CorsairError.cs +++ b/RGB.NET.Devices.Corsair/Enum/CorsairError.cs @@ -1,42 +1,41 @@ // ReSharper disable InconsistentNaming // ReSharper disable UnusedMember.Global -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Shared list of all errors which could happen during calling of Corsair* functions. +/// +public enum CorsairError { /// - /// Shared list of all errors which could happen during calling of Corsair* functions. + /// If previously called function completed successfully. /// - public enum CorsairError - { - /// - /// If previously called function completed successfully. - /// - Success, + Success, - /// - /// CUE is not running or was shut down or third-party control is disabled in CUE settings. (runtime error) - /// - ServerNotFound, + /// + /// CUE is not running or was shut down or third-party control is disabled in CUE settings. (runtime error) + /// + ServerNotFound, - /// - /// If some other client has or took over exclusive control. (runtime error) - /// - NoControl, + /// + /// If some other client has or took over exclusive control. (runtime error) + /// + NoControl, - /// - /// If developer did not perform protocol handshake. (developer error) - /// - ProtocolHandshakeMissing, + /// + /// If developer did not perform protocol handshake. (developer error) + /// + ProtocolHandshakeMissing, - /// - /// If developer is calling the function that is not supported by the server (either because protocol has broken by server or client or because the function is new and server is too old. - /// Check CorsairProtocolDetails for details). (developer error) - /// - IncompatibleProtocol, + /// + /// If developer is calling the function that is not supported by the server (either because protocol has broken by server or client or because the function is new and server is too old. + /// Check CorsairProtocolDetails for details). (developer error) + /// + IncompatibleProtocol, - /// - /// If developer supplied invalid arguments to the function (for specifics look at function descriptions). (developer error) - /// - InvalidArguments - }; -} + /// + /// If developer supplied invalid arguments to the function (for specifics look at function descriptions). (developer error) + /// + InvalidArguments +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairLedId.cs b/RGB.NET.Devices.Corsair/Enum/CorsairLedId.cs index acbca2f4..a0cfeab9 100644 --- a/RGB.NET.Devices.Corsair/Enum/CorsairLedId.cs +++ b/RGB.NET.Devices.Corsair/Enum/CorsairLedId.cs @@ -1,1576 +1,1742 @@ // ReSharper disable InconsistentNaming +// ReSharper disable UnusedMember.Global +#pragma warning disable 1591 -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member +namespace RGB.NET.Devices.Corsair; -namespace RGB.NET.Devices.Corsair +/// +/// Contains a list of all LEDs available for all corsair devices. +/// +public enum CorsairLedId { - /// - /// Contains list of all LEDs available for all corsair devices. - /// - public enum CorsairLedId - { - Invalid = 0, - Escape = 1, - F1 = 2, - F2 = 3, - F3 = 4, - F4 = 5, - F5 = 6, - F6 = 7, - F7 = 8, - F8 = 9, - F9 = 10, - F10 = 11, - F11 = 12, - GraveAccentAndTilde = 13, - D1 = 14, - D2 = 15, - D3 = 16, - D4 = 17, - D5 = 18, - D6 = 19, - D7 = 20, - D8 = 21, - D9 = 22, - D0 = 23, - MinusAndUnderscore = 24, - Tab = 25, - Q = 26, - W = 27, - E = 28, - R = 29, - T = 30, - Y = 31, - U = 32, - I = 33, - O = 34, - P = 35, - BracketLeft = 36, - CapsLock = 37, - A = 38, - S = 39, - D = 40, - F = 41, - G = 42, - H = 43, - J = 44, - K = 45, - L = 46, - SemicolonAndColon = 47, - ApostropheAndDoubleQuote = 48, - LeftShift = 49, - NonUsBackslash = 50, - Z = 51, - X = 52, - C = 53, - V = 54, - B = 55, - N = 56, - M = 57, - CommaAndLessThan = 58, - PeriodAndBiggerThan = 59, - SlashAndQuestionMark = 60, - LeftCtrl = 61, - LeftGui = 62, - LeftAlt = 63, - Lang2 = 64, - Space = 65, - Lang1 = 66, - International2 = 67, - RightAlt = 68, - RightGui = 69, - Application = 70, - LedProgramming = 71, - Brightness = 72, - F12 = 73, - PrintScreen = 74, - ScrollLock = 75, - PauseBreak = 76, - Insert = 77, - Home = 78, - PageUp = 79, - BracketRight = 80, - Backslash = 81, - NonUsTilde = 82, - Enter = 83, - International1 = 84, - EqualsAndPlus = 85, - International3 = 86, - Backspace = 87, - Delete = 88, - End = 89, - PageDown = 90, - RightShift = 91, - RightCtrl = 92, - UpArrow = 93, - LeftArrow = 94, - DownArrow = 95, - RightArrow = 96, - WinLock = 97, - Mute = 98, - Stop = 99, - ScanPreviousTrack = 100, - PlayPause = 101, - ScanNextTrack = 102, - NumLock = 103, - KeypadSlash = 104, - KeypadAsterisk = 105, - KeypadMinus = 106, - KeypadPlus = 107, - KeypadEnter = 108, - Keypad7 = 109, - Keypad8 = 110, - Keypad9 = 111, - KeypadComma = 112, - Keypad4 = 113, - Keypad5 = 114, - Keypad6 = 115, - Keypad1 = 116, - Keypad2 = 117, - Keypad3 = 118, - Keypad0 = 119, - KeypadPeriodAndDelete = 120, - G1 = 121, - G2 = 122, - G3 = 123, - G4 = 124, - G5 = 125, - G6 = 126, - G7 = 127, - G8 = 128, - G9 = 129, - G10 = 130, - VolumeUp = 131, - VolumeDown = 132, - MR = 133, - M1 = 134, - M2 = 135, - M3 = 136, - G11 = 137, - G12 = 138, - G13 = 139, - G14 = 140, - G15 = 141, - G16 = 142, - G17 = 143, - G18 = 144, - International5 = 145, - International4 = 146, - Fn = 147, + Invalid = 0, + Escape = 1, + F1 = 2, + F2 = 3, + F3 = 4, + F4 = 5, + F5 = 6, + F6 = 7, + F7 = 8, + F8 = 9, + F9 = 10, + F10 = 11, + F11 = 12, + GraveAccentAndTilde = 13, + D1 = 14, + D2 = 15, + D3 = 16, + D4 = 17, + D5 = 18, + D6 = 19, + D7 = 20, + D8 = 21, + D9 = 22, + D0 = 23, + MinusAndUnderscore = 24, + Tab = 25, + Q = 26, + W = 27, + E = 28, + R = 29, + T = 30, + Y = 31, + U = 32, + I = 33, + O = 34, + P = 35, + BracketLeft = 36, + CapsLock = 37, + A = 38, + S = 39, + D = 40, + F = 41, + G = 42, + H = 43, + J = 44, + K = 45, + L = 46, + SemicolonAndColon = 47, + ApostropheAndDoubleQuote = 48, + LeftShift = 49, + NonUsBackslash = 50, + Z = 51, + X = 52, + C = 53, + V = 54, + B = 55, + N = 56, + M = 57, + CommaAndLessThan = 58, + PeriodAndBiggerThan = 59, + SlashAndQuestionMark = 60, + LeftCtrl = 61, + LeftGui = 62, + LeftAlt = 63, + Lang2 = 64, + Space = 65, + Lang1 = 66, + International2 = 67, + RightAlt = 68, + RightGui = 69, + Application = 70, + LedProgramming = 71, + Brightness = 72, + F12 = 73, + PrintScreen = 74, + ScrollLock = 75, + PauseBreak = 76, + Insert = 77, + Home = 78, + PageUp = 79, + BracketRight = 80, + Backslash = 81, + NonUsTilde = 82, + Enter = 83, + International1 = 84, + EqualsAndPlus = 85, + International3 = 86, + Backspace = 87, + Delete = 88, + End = 89, + PageDown = 90, + RightShift = 91, + RightCtrl = 92, + UpArrow = 93, + LeftArrow = 94, + DownArrow = 95, + RightArrow = 96, + WinLock = 97, + Mute = 98, + Stop = 99, + ScanPreviousTrack = 100, + PlayPause = 101, + ScanNextTrack = 102, + NumLock = 103, + KeypadSlash = 104, + KeypadAsterisk = 105, + KeypadMinus = 106, + KeypadPlus = 107, + KeypadEnter = 108, + Keypad7 = 109, + Keypad8 = 110, + Keypad9 = 111, + KeypadComma = 112, + Keypad4 = 113, + Keypad5 = 114, + Keypad6 = 115, + Keypad1 = 116, + Keypad2 = 117, + Keypad3 = 118, + Keypad0 = 119, + KeypadPeriodAndDelete = 120, + G1 = 121, + G2 = 122, + G3 = 123, + G4 = 124, + G5 = 125, + G6 = 126, + G7 = 127, + G8 = 128, + G9 = 129, + G10 = 130, + VolumeUp = 131, + VolumeDown = 132, + MR = 133, + M1 = 134, + M2 = 135, + M3 = 136, + G11 = 137, + G12 = 138, + G13 = 139, + G14 = 140, + G15 = 141, + G16 = 142, + G17 = 143, + G18 = 144, + International5 = 145, + International4 = 146, + Fn = 147, - B1 = 148, - B2 = 149, - B3 = 150, - B4 = 151, - B5 = 189, - B6 = 190, + B1 = 148, + B2 = 149, + B3 = 150, + B4 = 151, - LeftLogo = 152, - RightLogo = 153, + LeftLogo = 152, + RightLogo = 153, - Logo = 154, + Logo = 154, - Zone1 = 155, - Zone2 = 156, - Zone3 = 157, - Zone4 = 158, - Zone5 = 159, - Zone6 = 160, - Zone7 = 161, - Zone8 = 162, - Zone9 = 163, - Zone10 = 164, - Zone11 = 165, - Zone12 = 166, - Zone13 = 167, - Zone14 = 168, - Zone15 = 169, + Zone1 = 155, + Zone2 = 156, + Zone3 = 157, + Zone4 = 158, + Zone5 = 159, + Zone6 = 160, + Zone7 = 161, + Zone8 = 162, + Zone9 = 163, + Zone10 = 164, + Zone11 = 165, + Zone12 = 166, + Zone13 = 167, + Zone14 = 168, + Zone15 = 169, - Lightbar1 = 170, - Lightbar2 = 171, - Lightbar3 = 172, - Lightbar4 = 173, - Lightbar5 = 174, - Lightbar6 = 175, - Lightbar7 = 176, - Lightbar8 = 177, - Lightbar9 = 178, - Lightbar10 = 179, - Lightbar11 = 180, - Lightbar12 = 181, - Lightbar13 = 182, - Lightbar14 = 183, - Lightbar15 = 184, - Lightbar16 = 185, - Lightbar17 = 186, - Lightbar18 = 187, - Lightbar19 = 188, + Lightbar1 = 170, + Lightbar2 = 171, + Lightbar3 = 172, + Lightbar4 = 173, + Lightbar5 = 174, + Lightbar6 = 175, + Lightbar7 = 176, + Lightbar8 = 177, + Lightbar9 = 178, + Lightbar10 = 179, + Lightbar11 = 180, + Lightbar12 = 181, + Lightbar13 = 182, + Lightbar14 = 183, + Lightbar15 = 184, + Lightbar16 = 185, + Lightbar17 = 186, + Lightbar18 = 187, + Lightbar19 = 188, - HeadsetStandZone1 = 191, - HeadsetStandZone2 = 192, - HeadsetStandZone3 = 193, - HeadsetStandZone4 = 194, - HeadsetStandZone5 = 195, - HeadsetStandZone6 = 196, - HeadsetStandZone7 = 197, - HeadsetStandZone8 = 198, - HeadsetStandZone9 = 199, + B5 = 189, + B6 = 190, - CustomDeviceChannel1Led1 = 200, - CustomDeviceChannel1Led2 = 201, - CustomDeviceChannel1Led3 = 202, - CustomDeviceChannel1Led4 = 203, - CustomDeviceChannel1Led5 = 204, - CustomDeviceChannel1Led6 = 205, - CustomDeviceChannel1Led7 = 206, - CustomDeviceChannel1Led8 = 207, - CustomDeviceChannel1Led9 = 208, - CustomDeviceChannel1Led10 = 209, - CustomDeviceChannel1Led11 = 210, - CustomDeviceChannel1Led12 = 211, - CustomDeviceChannel1Led13 = 212, - CustomDeviceChannel1Led14 = 213, - CustomDeviceChannel1Led15 = 214, - CustomDeviceChannel1Led16 = 215, - CustomDeviceChannel1Led17 = 216, - CustomDeviceChannel1Led18 = 217, - CustomDeviceChannel1Led19 = 218, - CustomDeviceChannel1Led20 = 219, - CustomDeviceChannel1Led21 = 220, - CustomDeviceChannel1Led22 = 221, - CustomDeviceChannel1Led23 = 222, - CustomDeviceChannel1Led24 = 223, - CustomDeviceChannel1Led25 = 224, - CustomDeviceChannel1Led26 = 225, - CustomDeviceChannel1Led27 = 226, - CustomDeviceChannel1Led28 = 227, - CustomDeviceChannel1Led29 = 228, - CustomDeviceChannel1Led30 = 229, - CustomDeviceChannel1Led31 = 230, - CustomDeviceChannel1Led32 = 231, - CustomDeviceChannel1Led33 = 232, - CustomDeviceChannel1Led34 = 233, - CustomDeviceChannel1Led35 = 234, - CustomDeviceChannel1Led36 = 235, - CustomDeviceChannel1Led37 = 236, - CustomDeviceChannel1Led38 = 237, - CustomDeviceChannel1Led39 = 238, - CustomDeviceChannel1Led40 = 239, - CustomDeviceChannel1Led41 = 240, - CustomDeviceChannel1Led42 = 241, - CustomDeviceChannel1Led43 = 242, - CustomDeviceChannel1Led44 = 243, - CustomDeviceChannel1Led45 = 244, - CustomDeviceChannel1Led46 = 245, - CustomDeviceChannel1Led47 = 246, - CustomDeviceChannel1Led48 = 247, - CustomDeviceChannel1Led49 = 248, - CustomDeviceChannel1Led50 = 249, - CustomDeviceChannel1Led51 = 250, - CustomDeviceChannel1Led52 = 251, - CustomDeviceChannel1Led53 = 252, - CustomDeviceChannel1Led54 = 253, - CustomDeviceChannel1Led55 = 254, - CustomDeviceChannel1Led56 = 255, - CustomDeviceChannel1Led57 = 256, - CustomDeviceChannel1Led58 = 257, - CustomDeviceChannel1Led59 = 258, - CustomDeviceChannel1Led60 = 259, - CustomDeviceChannel1Led61 = 260, - CustomDeviceChannel1Led62 = 261, - CustomDeviceChannel1Led63 = 262, - CustomDeviceChannel1Led64 = 263, - CustomDeviceChannel1Led65 = 264, - CustomDeviceChannel1Led66 = 265, - CustomDeviceChannel1Led67 = 266, - CustomDeviceChannel1Led68 = 267, - CustomDeviceChannel1Led69 = 268, - CustomDeviceChannel1Led70 = 269, - CustomDeviceChannel1Led71 = 270, - CustomDeviceChannel1Led72 = 271, - CustomDeviceChannel1Led73 = 272, - CustomDeviceChannel1Led74 = 273, - CustomDeviceChannel1Led75 = 274, - CustomDeviceChannel1Led76 = 275, - CustomDeviceChannel1Led77 = 276, - CustomDeviceChannel1Led78 = 277, - CustomDeviceChannel1Led79 = 278, - CustomDeviceChannel1Led80 = 279, - CustomDeviceChannel1Led81 = 280, - CustomDeviceChannel1Led82 = 281, - CustomDeviceChannel1Led83 = 282, - CustomDeviceChannel1Led84 = 283, - CustomDeviceChannel1Led85 = 284, - CustomDeviceChannel1Led86 = 285, - CustomDeviceChannel1Led87 = 286, - CustomDeviceChannel1Led88 = 287, - CustomDeviceChannel1Led89 = 288, - CustomDeviceChannel1Led90 = 289, - CustomDeviceChannel1Led91 = 290, - CustomDeviceChannel1Led92 = 291, - CustomDeviceChannel1Led93 = 292, - CustomDeviceChannel1Led94 = 293, - CustomDeviceChannel1Led95 = 294, - CustomDeviceChannel1Led96 = 295, - CustomDeviceChannel1Led97 = 296, - CustomDeviceChannel1Led98 = 297, - CustomDeviceChannel1Led99 = 298, - CustomDeviceChannel1Led100 = 299, - CustomDeviceChannel1Led101 = 300, - CustomDeviceChannel1Led102 = 301, - CustomDeviceChannel1Led103 = 302, - CustomDeviceChannel1Led104 = 303, - CustomDeviceChannel1Led105 = 304, - CustomDeviceChannel1Led106 = 305, - CustomDeviceChannel1Led107 = 306, - CustomDeviceChannel1Led108 = 307, - CustomDeviceChannel1Led109 = 308, - CustomDeviceChannel1Led110 = 309, - CustomDeviceChannel1Led111 = 310, - CustomDeviceChannel1Led112 = 311, - CustomDeviceChannel1Led113 = 312, - CustomDeviceChannel1Led114 = 313, - CustomDeviceChannel1Led115 = 314, - CustomDeviceChannel1Led116 = 315, - CustomDeviceChannel1Led117 = 316, - CustomDeviceChannel1Led118 = 317, - CustomDeviceChannel1Led119 = 318, - CustomDeviceChannel1Led120 = 319, - CustomDeviceChannel1Led121 = 320, - CustomDeviceChannel1Led122 = 321, - CustomDeviceChannel1Led123 = 322, - CustomDeviceChannel1Led124 = 323, - CustomDeviceChannel1Led125 = 324, - CustomDeviceChannel1Led126 = 325, - CustomDeviceChannel1Led127 = 326, - CustomDeviceChannel1Led128 = 327, - CustomDeviceChannel1Led129 = 328, - CustomDeviceChannel1Led130 = 329, - CustomDeviceChannel1Led131 = 330, - CustomDeviceChannel1Led132 = 331, - CustomDeviceChannel1Led133 = 332, - CustomDeviceChannel1Led134 = 333, - CustomDeviceChannel1Led135 = 334, - CustomDeviceChannel1Led136 = 335, - CustomDeviceChannel1Led137 = 336, - CustomDeviceChannel1Led138 = 337, - CustomDeviceChannel1Led139 = 338, - CustomDeviceChannel1Led140 = 339, - CustomDeviceChannel1Led141 = 340, - CustomDeviceChannel1Led142 = 341, - CustomDeviceChannel1Led143 = 342, - CustomDeviceChannel1Led144 = 343, - CustomDeviceChannel1Led145 = 344, - CustomDeviceChannel1Led146 = 345, - CustomDeviceChannel1Led147 = 346, - CustomDeviceChannel1Led148 = 347, - CustomDeviceChannel1Led149 = 348, - CustomDeviceChannel1Led150 = 349, + HeadsetStandZone1 = 191, + HeadsetStandZone2 = 192, + HeadsetStandZone3 = 193, + HeadsetStandZone4 = 194, + HeadsetStandZone5 = 195, + HeadsetStandZone6 = 196, + HeadsetStandZone7 = 197, + HeadsetStandZone8 = 198, + HeadsetStandZone9 = 199, - CustomDeviceChannel2Led1 = 350, - CustomDeviceChannel2Led2 = 351, - CustomDeviceChannel2Led3 = 352, - CustomDeviceChannel2Led4 = 353, - CustomDeviceChannel2Led5 = 354, - CustomDeviceChannel2Led6 = 355, - CustomDeviceChannel2Led7 = 356, - CustomDeviceChannel2Led8 = 357, - CustomDeviceChannel2Led9 = 358, - CustomDeviceChannel2Led10 = 359, - CustomDeviceChannel2Led11 = 360, - CustomDeviceChannel2Led12 = 361, - CustomDeviceChannel2Led13 = 362, - CustomDeviceChannel2Led14 = 363, - CustomDeviceChannel2Led15 = 364, - CustomDeviceChannel2Led16 = 365, - CustomDeviceChannel2Led17 = 366, - CustomDeviceChannel2Led18 = 367, - CustomDeviceChannel2Led19 = 368, - CustomDeviceChannel2Led20 = 369, - CustomDeviceChannel2Led21 = 370, - CustomDeviceChannel2Led22 = 371, - CustomDeviceChannel2Led23 = 372, - CustomDeviceChannel2Led24 = 373, - CustomDeviceChannel2Led25 = 374, - CustomDeviceChannel2Led26 = 375, - CustomDeviceChannel2Led27 = 376, - CustomDeviceChannel2Led28 = 377, - CustomDeviceChannel2Led29 = 378, - CustomDeviceChannel2Led30 = 379, - CustomDeviceChannel2Led31 = 380, - CustomDeviceChannel2Led32 = 381, - CustomDeviceChannel2Led33 = 382, - CustomDeviceChannel2Led34 = 383, - CustomDeviceChannel2Led35 = 384, - CustomDeviceChannel2Led36 = 385, - CustomDeviceChannel2Led37 = 386, - CustomDeviceChannel2Led38 = 387, - CustomDeviceChannel2Led39 = 388, - CustomDeviceChannel2Led40 = 389, - CustomDeviceChannel2Led41 = 390, - CustomDeviceChannel2Led42 = 391, - CustomDeviceChannel2Led43 = 392, - CustomDeviceChannel2Led44 = 393, - CustomDeviceChannel2Led45 = 394, - CustomDeviceChannel2Led46 = 395, - CustomDeviceChannel2Led47 = 396, - CustomDeviceChannel2Led48 = 397, - CustomDeviceChannel2Led49 = 398, - CustomDeviceChannel2Led50 = 399, - CustomDeviceChannel2Led51 = 400, - CustomDeviceChannel2Led52 = 401, - CustomDeviceChannel2Led53 = 402, - CustomDeviceChannel2Led54 = 403, - CustomDeviceChannel2Led55 = 404, - CustomDeviceChannel2Led56 = 405, - CustomDeviceChannel2Led57 = 406, - CustomDeviceChannel2Led58 = 407, - CustomDeviceChannel2Led59 = 408, - CustomDeviceChannel2Led60 = 409, - CustomDeviceChannel2Led61 = 410, - CustomDeviceChannel2Led62 = 411, - CustomDeviceChannel2Led63 = 412, - CustomDeviceChannel2Led64 = 413, - CustomDeviceChannel2Led65 = 414, - CustomDeviceChannel2Led66 = 415, - CustomDeviceChannel2Led67 = 416, - CustomDeviceChannel2Led68 = 417, - CustomDeviceChannel2Led69 = 418, - CustomDeviceChannel2Led70 = 419, - CustomDeviceChannel2Led71 = 420, - CustomDeviceChannel2Led72 = 421, - CustomDeviceChannel2Led73 = 422, - CustomDeviceChannel2Led74 = 423, - CustomDeviceChannel2Led75 = 424, - CustomDeviceChannel2Led76 = 425, - CustomDeviceChannel2Led77 = 426, - CustomDeviceChannel2Led78 = 427, - CustomDeviceChannel2Led79 = 428, - CustomDeviceChannel2Led80 = 429, - CustomDeviceChannel2Led81 = 430, - CustomDeviceChannel2Led82 = 431, - CustomDeviceChannel2Led83 = 432, - CustomDeviceChannel2Led84 = 433, - CustomDeviceChannel2Led85 = 434, - CustomDeviceChannel2Led86 = 435, - CustomDeviceChannel2Led87 = 436, - CustomDeviceChannel2Led88 = 437, - CustomDeviceChannel2Led89 = 438, - CustomDeviceChannel2Led90 = 439, - CustomDeviceChannel2Led91 = 440, - CustomDeviceChannel2Led92 = 441, - CustomDeviceChannel2Led93 = 442, - CustomDeviceChannel2Led94 = 443, - CustomDeviceChannel2Led95 = 444, - CustomDeviceChannel2Led96 = 445, - CustomDeviceChannel2Led97 = 446, - CustomDeviceChannel2Led98 = 447, - CustomDeviceChannel2Led99 = 448, - CustomDeviceChannel2Led100 = 449, - CustomDeviceChannel2Led101 = 450, - CustomDeviceChannel2Led102 = 451, - CustomDeviceChannel2Led103 = 452, - CustomDeviceChannel2Led104 = 453, - CustomDeviceChannel2Led105 = 454, - CustomDeviceChannel2Led106 = 455, - CustomDeviceChannel2Led107 = 456, - CustomDeviceChannel2Led108 = 457, - CustomDeviceChannel2Led109 = 458, - CustomDeviceChannel2Led110 = 459, - CustomDeviceChannel2Led111 = 460, - CustomDeviceChannel2Led112 = 461, - CustomDeviceChannel2Led113 = 462, - CustomDeviceChannel2Led114 = 463, - CustomDeviceChannel2Led115 = 464, - CustomDeviceChannel2Led116 = 465, - CustomDeviceChannel2Led117 = 466, - CustomDeviceChannel2Led118 = 467, - CustomDeviceChannel2Led119 = 468, - CustomDeviceChannel2Led120 = 469, - CustomDeviceChannel2Led121 = 470, - CustomDeviceChannel2Led122 = 471, - CustomDeviceChannel2Led123 = 472, - CustomDeviceChannel2Led124 = 473, - CustomDeviceChannel2Led125 = 474, - CustomDeviceChannel2Led126 = 475, - CustomDeviceChannel2Led127 = 476, - CustomDeviceChannel2Led128 = 477, - CustomDeviceChannel2Led129 = 478, - CustomDeviceChannel2Led130 = 479, - CustomDeviceChannel2Led131 = 480, - CustomDeviceChannel2Led132 = 481, - CustomDeviceChannel2Led133 = 482, - CustomDeviceChannel2Led134 = 483, - CustomDeviceChannel2Led135 = 484, - CustomDeviceChannel2Led136 = 485, - CustomDeviceChannel2Led137 = 486, - CustomDeviceChannel2Led138 = 487, - CustomDeviceChannel2Led139 = 488, - CustomDeviceChannel2Led140 = 489, - CustomDeviceChannel2Led141 = 490, - CustomDeviceChannel2Led142 = 491, - CustomDeviceChannel2Led143 = 492, - CustomDeviceChannel2Led144 = 493, - CustomDeviceChannel2Led145 = 494, - CustomDeviceChannel2Led146 = 495, - CustomDeviceChannel2Led147 = 496, - CustomDeviceChannel2Led148 = 497, - CustomDeviceChannel2Led149 = 498, - CustomDeviceChannel2Led150 = 499, + CustomDeviceChannel1Led1 = 200, + CustomDeviceChannel1Led2 = 201, + CustomDeviceChannel1Led3 = 202, + CustomDeviceChannel1Led4 = 203, + CustomDeviceChannel1Led5 = 204, + CustomDeviceChannel1Led6 = 205, + CustomDeviceChannel1Led7 = 206, + CustomDeviceChannel1Led8 = 207, + CustomDeviceChannel1Led9 = 208, + CustomDeviceChannel1Led10 = 209, + CustomDeviceChannel1Led11 = 210, + CustomDeviceChannel1Led12 = 211, + CustomDeviceChannel1Led13 = 212, + CustomDeviceChannel1Led14 = 213, + CustomDeviceChannel1Led15 = 214, + CustomDeviceChannel1Led16 = 215, + CustomDeviceChannel1Led17 = 216, + CustomDeviceChannel1Led18 = 217, + CustomDeviceChannel1Led19 = 218, + CustomDeviceChannel1Led20 = 219, + CustomDeviceChannel1Led21 = 220, + CustomDeviceChannel1Led22 = 221, + CustomDeviceChannel1Led23 = 222, + CustomDeviceChannel1Led24 = 223, + CustomDeviceChannel1Led25 = 224, + CustomDeviceChannel1Led26 = 225, + CustomDeviceChannel1Led27 = 226, + CustomDeviceChannel1Led28 = 227, + CustomDeviceChannel1Led29 = 228, + CustomDeviceChannel1Led30 = 229, + CustomDeviceChannel1Led31 = 230, + CustomDeviceChannel1Led32 = 231, + CustomDeviceChannel1Led33 = 232, + CustomDeviceChannel1Led34 = 233, + CustomDeviceChannel1Led35 = 234, + CustomDeviceChannel1Led36 = 235, + CustomDeviceChannel1Led37 = 236, + CustomDeviceChannel1Led38 = 237, + CustomDeviceChannel1Led39 = 238, + CustomDeviceChannel1Led40 = 239, + CustomDeviceChannel1Led41 = 240, + CustomDeviceChannel1Led42 = 241, + CustomDeviceChannel1Led43 = 242, + CustomDeviceChannel1Led44 = 243, + CustomDeviceChannel1Led45 = 244, + CustomDeviceChannel1Led46 = 245, + CustomDeviceChannel1Led47 = 246, + CustomDeviceChannel1Led48 = 247, + CustomDeviceChannel1Led49 = 248, + CustomDeviceChannel1Led50 = 249, + CustomDeviceChannel1Led51 = 250, + CustomDeviceChannel1Led52 = 251, + CustomDeviceChannel1Led53 = 252, + CustomDeviceChannel1Led54 = 253, + CustomDeviceChannel1Led55 = 254, + CustomDeviceChannel1Led56 = 255, + CustomDeviceChannel1Led57 = 256, + CustomDeviceChannel1Led58 = 257, + CustomDeviceChannel1Led59 = 258, + CustomDeviceChannel1Led60 = 259, + CustomDeviceChannel1Led61 = 260, + CustomDeviceChannel1Led62 = 261, + CustomDeviceChannel1Led63 = 262, + CustomDeviceChannel1Led64 = 263, + CustomDeviceChannel1Led65 = 264, + CustomDeviceChannel1Led66 = 265, + CustomDeviceChannel1Led67 = 266, + CustomDeviceChannel1Led68 = 267, + CustomDeviceChannel1Led69 = 268, + CustomDeviceChannel1Led70 = 269, + CustomDeviceChannel1Led71 = 270, + CustomDeviceChannel1Led72 = 271, + CustomDeviceChannel1Led73 = 272, + CustomDeviceChannel1Led74 = 273, + CustomDeviceChannel1Led75 = 274, + CustomDeviceChannel1Led76 = 275, + CustomDeviceChannel1Led77 = 276, + CustomDeviceChannel1Led78 = 277, + CustomDeviceChannel1Led79 = 278, + CustomDeviceChannel1Led80 = 279, + CustomDeviceChannel1Led81 = 280, + CustomDeviceChannel1Led82 = 281, + CustomDeviceChannel1Led83 = 282, + CustomDeviceChannel1Led84 = 283, + CustomDeviceChannel1Led85 = 284, + CustomDeviceChannel1Led86 = 285, + CustomDeviceChannel1Led87 = 286, + CustomDeviceChannel1Led88 = 287, + CustomDeviceChannel1Led89 = 288, + CustomDeviceChannel1Led90 = 289, + CustomDeviceChannel1Led91 = 290, + CustomDeviceChannel1Led92 = 291, + CustomDeviceChannel1Led93 = 292, + CustomDeviceChannel1Led94 = 293, + CustomDeviceChannel1Led95 = 294, + CustomDeviceChannel1Led96 = 295, + CustomDeviceChannel1Led97 = 296, + CustomDeviceChannel1Led98 = 297, + CustomDeviceChannel1Led99 = 298, + CustomDeviceChannel1Led100 = 299, + CustomDeviceChannel1Led101 = 300, + CustomDeviceChannel1Led102 = 301, + CustomDeviceChannel1Led103 = 302, + CustomDeviceChannel1Led104 = 303, + CustomDeviceChannel1Led105 = 304, + CustomDeviceChannel1Led106 = 305, + CustomDeviceChannel1Led107 = 306, + CustomDeviceChannel1Led108 = 307, + CustomDeviceChannel1Led109 = 308, + CustomDeviceChannel1Led110 = 309, + CustomDeviceChannel1Led111 = 310, + CustomDeviceChannel1Led112 = 311, + CustomDeviceChannel1Led113 = 312, + CustomDeviceChannel1Led114 = 313, + CustomDeviceChannel1Led115 = 314, + CustomDeviceChannel1Led116 = 315, + CustomDeviceChannel1Led117 = 316, + CustomDeviceChannel1Led118 = 317, + CustomDeviceChannel1Led119 = 318, + CustomDeviceChannel1Led120 = 319, + CustomDeviceChannel1Led121 = 320, + CustomDeviceChannel1Led122 = 321, + CustomDeviceChannel1Led123 = 322, + CustomDeviceChannel1Led124 = 323, + CustomDeviceChannel1Led125 = 324, + CustomDeviceChannel1Led126 = 325, + CustomDeviceChannel1Led127 = 326, + CustomDeviceChannel1Led128 = 327, + CustomDeviceChannel1Led129 = 328, + CustomDeviceChannel1Led130 = 329, + CustomDeviceChannel1Led131 = 330, + CustomDeviceChannel1Led132 = 331, + CustomDeviceChannel1Led133 = 332, + CustomDeviceChannel1Led134 = 333, + CustomDeviceChannel1Led135 = 334, + CustomDeviceChannel1Led136 = 335, + CustomDeviceChannel1Led137 = 336, + CustomDeviceChannel1Led138 = 337, + CustomDeviceChannel1Led139 = 338, + CustomDeviceChannel1Led140 = 339, + CustomDeviceChannel1Led141 = 340, + CustomDeviceChannel1Led142 = 341, + CustomDeviceChannel1Led143 = 342, + CustomDeviceChannel1Led144 = 343, + CustomDeviceChannel1Led145 = 344, + CustomDeviceChannel1Led146 = 345, + CustomDeviceChannel1Led147 = 346, + CustomDeviceChannel1Led148 = 347, + CustomDeviceChannel1Led149 = 348, + CustomDeviceChannel1Led150 = 349, - OemLed1 = 500, - OemLed2 = 501, - OemLed3 = 502, - OemLed4 = 503, - OemLed5 = 504, - OemLed6 = 505, - OemLed7 = 506, - OemLed8 = 507, - OemLed9 = 508, - OemLed10 = 509, - OemLed11 = 510, - OemLed12 = 511, - OemLed13 = 512, - OemLed14 = 513, - OemLed15 = 514, - OemLed16 = 515, - OemLed17 = 516, - OemLed18 = 517, - OemLed19 = 518, - OemLed20 = 519, - OemLed21 = 520, - OemLed22 = 521, - OemLed23 = 522, - OemLed24 = 523, - OemLed25 = 524, - OemLed26 = 525, - OemLed27 = 526, - OemLed28 = 527, - OemLed29 = 528, - OemLed30 = 529, - OemLed31 = 530, - OemLed32 = 531, - OemLed33 = 532, - OemLed34 = 533, - OemLed35 = 534, - OemLed36 = 535, - OemLed37 = 536, - OemLed38 = 537, - OemLed39 = 538, - OemLed40 = 539, - OemLed41 = 540, - OemLed42 = 541, - OemLed43 = 542, - OemLed44 = 543, - OemLed45 = 544, - OemLed46 = 545, - OemLed47 = 546, - OemLed48 = 547, - OemLed49 = 548, - OemLed50 = 549, - OemLed51 = 550, - OemLed52 = 551, - OemLed53 = 552, - OemLed54 = 553, - OemLed55 = 554, - OemLed56 = 555, - OemLed57 = 556, - OemLed58 = 557, - OemLed59 = 558, - OemLed60 = 559, - OemLed61 = 560, - OemLed62 = 561, - OemLed63 = 562, - OemLed64 = 563, - OemLed65 = 564, - OemLed66 = 565, - OemLed67 = 566, - OemLed68 = 567, - OemLed69 = 568, - OemLed70 = 569, - OemLed71 = 570, - OemLed72 = 571, - OemLed73 = 572, - OemLed74 = 573, - OemLed75 = 574, - OemLed76 = 575, - OemLed77 = 576, - OemLed78 = 577, - OemLed79 = 578, - OemLed80 = 579, - OemLed81 = 580, - OemLed82 = 581, - OemLed83 = 582, - OemLed84 = 583, - OemLed85 = 584, - OemLed86 = 585, - OemLed87 = 586, - OemLed88 = 587, - OemLed89 = 588, - OemLed90 = 589, - OemLed91 = 590, - OemLed92 = 591, - OemLed93 = 592, - OemLed94 = 593, - OemLed95 = 594, - OemLed96 = 595, - OemLed97 = 596, - OemLed98 = 597, - OemLed99 = 598, - OemLed100 = 599, + CustomDeviceChannel2Led1 = 350, + CustomDeviceChannel2Led2 = 351, + CustomDeviceChannel2Led3 = 352, + CustomDeviceChannel2Led4 = 353, + CustomDeviceChannel2Led5 = 354, + CustomDeviceChannel2Led6 = 355, + CustomDeviceChannel2Led7 = 356, + CustomDeviceChannel2Led8 = 357, + CustomDeviceChannel2Led9 = 358, + CustomDeviceChannel2Led10 = 359, + CustomDeviceChannel2Led11 = 360, + CustomDeviceChannel2Led12 = 361, + CustomDeviceChannel2Led13 = 362, + CustomDeviceChannel2Led14 = 363, + CustomDeviceChannel2Led15 = 364, + CustomDeviceChannel2Led16 = 365, + CustomDeviceChannel2Led17 = 366, + CustomDeviceChannel2Led18 = 367, + CustomDeviceChannel2Led19 = 368, + CustomDeviceChannel2Led20 = 369, + CustomDeviceChannel2Led21 = 370, + CustomDeviceChannel2Led22 = 371, + CustomDeviceChannel2Led23 = 372, + CustomDeviceChannel2Led24 = 373, + CustomDeviceChannel2Led25 = 374, + CustomDeviceChannel2Led26 = 375, + CustomDeviceChannel2Led27 = 376, + CustomDeviceChannel2Led28 = 377, + CustomDeviceChannel2Led29 = 378, + CustomDeviceChannel2Led30 = 379, + CustomDeviceChannel2Led31 = 380, + CustomDeviceChannel2Led32 = 381, + CustomDeviceChannel2Led33 = 382, + CustomDeviceChannel2Led34 = 383, + CustomDeviceChannel2Led35 = 384, + CustomDeviceChannel2Led36 = 385, + CustomDeviceChannel2Led37 = 386, + CustomDeviceChannel2Led38 = 387, + CustomDeviceChannel2Led39 = 388, + CustomDeviceChannel2Led40 = 389, + CustomDeviceChannel2Led41 = 390, + CustomDeviceChannel2Led42 = 391, + CustomDeviceChannel2Led43 = 392, + CustomDeviceChannel2Led44 = 393, + CustomDeviceChannel2Led45 = 394, + CustomDeviceChannel2Led46 = 395, + CustomDeviceChannel2Led47 = 396, + CustomDeviceChannel2Led48 = 397, + CustomDeviceChannel2Led49 = 398, + CustomDeviceChannel2Led50 = 399, + CustomDeviceChannel2Led51 = 400, + CustomDeviceChannel2Led52 = 401, + CustomDeviceChannel2Led53 = 402, + CustomDeviceChannel2Led54 = 403, + CustomDeviceChannel2Led55 = 404, + CustomDeviceChannel2Led56 = 405, + CustomDeviceChannel2Led57 = 406, + CustomDeviceChannel2Led58 = 407, + CustomDeviceChannel2Led59 = 408, + CustomDeviceChannel2Led60 = 409, + CustomDeviceChannel2Led61 = 410, + CustomDeviceChannel2Led62 = 411, + CustomDeviceChannel2Led63 = 412, + CustomDeviceChannel2Led64 = 413, + CustomDeviceChannel2Led65 = 414, + CustomDeviceChannel2Led66 = 415, + CustomDeviceChannel2Led67 = 416, + CustomDeviceChannel2Led68 = 417, + CustomDeviceChannel2Led69 = 418, + CustomDeviceChannel2Led70 = 419, + CustomDeviceChannel2Led71 = 420, + CustomDeviceChannel2Led72 = 421, + CustomDeviceChannel2Led73 = 422, + CustomDeviceChannel2Led74 = 423, + CustomDeviceChannel2Led75 = 424, + CustomDeviceChannel2Led76 = 425, + CustomDeviceChannel2Led77 = 426, + CustomDeviceChannel2Led78 = 427, + CustomDeviceChannel2Led79 = 428, + CustomDeviceChannel2Led80 = 429, + CustomDeviceChannel2Led81 = 430, + CustomDeviceChannel2Led82 = 431, + CustomDeviceChannel2Led83 = 432, + CustomDeviceChannel2Led84 = 433, + CustomDeviceChannel2Led85 = 434, + CustomDeviceChannel2Led86 = 435, + CustomDeviceChannel2Led87 = 436, + CustomDeviceChannel2Led88 = 437, + CustomDeviceChannel2Led89 = 438, + CustomDeviceChannel2Led90 = 439, + CustomDeviceChannel2Led91 = 440, + CustomDeviceChannel2Led92 = 441, + CustomDeviceChannel2Led93 = 442, + CustomDeviceChannel2Led94 = 443, + CustomDeviceChannel2Led95 = 444, + CustomDeviceChannel2Led96 = 445, + CustomDeviceChannel2Led97 = 446, + CustomDeviceChannel2Led98 = 447, + CustomDeviceChannel2Led99 = 448, + CustomDeviceChannel2Led100 = 449, + CustomDeviceChannel2Led101 = 450, + CustomDeviceChannel2Led102 = 451, + CustomDeviceChannel2Led103 = 452, + CustomDeviceChannel2Led104 = 453, + CustomDeviceChannel2Led105 = 454, + CustomDeviceChannel2Led106 = 455, + CustomDeviceChannel2Led107 = 456, + CustomDeviceChannel2Led108 = 457, + CustomDeviceChannel2Led109 = 458, + CustomDeviceChannel2Led110 = 459, + CustomDeviceChannel2Led111 = 460, + CustomDeviceChannel2Led112 = 461, + CustomDeviceChannel2Led113 = 462, + CustomDeviceChannel2Led114 = 463, + CustomDeviceChannel2Led115 = 464, + CustomDeviceChannel2Led116 = 465, + CustomDeviceChannel2Led117 = 466, + CustomDeviceChannel2Led118 = 467, + CustomDeviceChannel2Led119 = 468, + CustomDeviceChannel2Led120 = 469, + CustomDeviceChannel2Led121 = 470, + CustomDeviceChannel2Led122 = 471, + CustomDeviceChannel2Led123 = 472, + CustomDeviceChannel2Led124 = 473, + CustomDeviceChannel2Led125 = 474, + CustomDeviceChannel2Led126 = 475, + CustomDeviceChannel2Led127 = 476, + CustomDeviceChannel2Led128 = 477, + CustomDeviceChannel2Led129 = 478, + CustomDeviceChannel2Led130 = 479, + CustomDeviceChannel2Led131 = 480, + CustomDeviceChannel2Led132 = 481, + CustomDeviceChannel2Led133 = 482, + CustomDeviceChannel2Led134 = 483, + CustomDeviceChannel2Led135 = 484, + CustomDeviceChannel2Led136 = 485, + CustomDeviceChannel2Led137 = 486, + CustomDeviceChannel2Led138 = 487, + CustomDeviceChannel2Led139 = 488, + CustomDeviceChannel2Led140 = 489, + CustomDeviceChannel2Led141 = 490, + CustomDeviceChannel2Led142 = 491, + CustomDeviceChannel2Led143 = 492, + CustomDeviceChannel2Led144 = 493, + CustomDeviceChannel2Led145 = 494, + CustomDeviceChannel2Led146 = 495, + CustomDeviceChannel2Led147 = 496, + CustomDeviceChannel2Led148 = 497, + CustomDeviceChannel2Led149 = 498, + CustomDeviceChannel2Led150 = 499, - DRAM1 = 600, - DRAM2 = 601, - DRAM3 = 602, - DRAM4 = 603, - DRAM5 = 604, - DRAM6 = 605, - DRAM7 = 606, - DRAM8 = 607, - DRAM9 = 608, - DRAM10 = 609, - DRAM11 = 610, - DRAM12 = 611, + OemLed1 = 500, + OemLed2 = 501, + OemLed3 = 502, + OemLed4 = 503, + OemLed5 = 504, + OemLed6 = 505, + OemLed7 = 506, + OemLed8 = 507, + OemLed9 = 508, + OemLed10 = 509, + OemLed11 = 510, + OemLed12 = 511, + OemLed13 = 512, + OemLed14 = 513, + OemLed15 = 514, + OemLed16 = 515, + OemLed17 = 516, + OemLed18 = 517, + OemLed19 = 518, + OemLed20 = 519, + OemLed21 = 520, + OemLed22 = 521, + OemLed23 = 522, + OemLed24 = 523, + OemLed25 = 524, + OemLed26 = 525, + OemLed27 = 526, + OemLed28 = 527, + OemLed29 = 528, + OemLed30 = 529, + OemLed31 = 530, + OemLed32 = 531, + OemLed33 = 532, + OemLed34 = 533, + OemLed35 = 534, + OemLed36 = 535, + OemLed37 = 536, + OemLed38 = 537, + OemLed39 = 538, + OemLed40 = 539, + OemLed41 = 540, + OemLed42 = 541, + OemLed43 = 542, + OemLed44 = 543, + OemLed45 = 544, + OemLed46 = 545, + OemLed47 = 546, + OemLed48 = 547, + OemLed49 = 548, + OemLed50 = 549, + OemLed51 = 550, + OemLed52 = 551, + OemLed53 = 552, + OemLed54 = 553, + OemLed55 = 554, + OemLed56 = 555, + OemLed57 = 556, + OemLed58 = 557, + OemLed59 = 558, + OemLed60 = 559, + OemLed61 = 560, + OemLed62 = 561, + OemLed63 = 562, + OemLed64 = 563, + OemLed65 = 564, + OemLed66 = 565, + OemLed67 = 566, + OemLed68 = 567, + OemLed69 = 568, + OemLed70 = 569, + OemLed71 = 570, + OemLed72 = 571, + OemLed73 = 572, + OemLed74 = 573, + OemLed75 = 574, + OemLed76 = 575, + OemLed77 = 576, + OemLed78 = 577, + OemLed79 = 578, + OemLed80 = 579, + OemLed81 = 580, + OemLed82 = 581, + OemLed83 = 582, + OemLed84 = 583, + OemLed85 = 584, + OemLed86 = 585, + OemLed87 = 586, + OemLed88 = 587, + OemLed89 = 588, + OemLed90 = 589, + OemLed91 = 590, + OemLed92 = 591, + OemLed93 = 592, + OemLed94 = 593, + OemLed95 = 594, + OemLed96 = 595, + OemLed97 = 596, + OemLed98 = 597, + OemLed99 = 598, + OemLed100 = 599, - CustomDeviceChannel3Led1 = 612, - CustomDeviceChannel3Led2 = 613, - CustomDeviceChannel3Led3 = 614, - CustomDeviceChannel3Led4 = 615, - CustomDeviceChannel3Led5 = 616, - CustomDeviceChannel3Led6 = 617, - CustomDeviceChannel3Led7 = 618, - CustomDeviceChannel3Led8 = 619, - CustomDeviceChannel3Led9 = 620, - CustomDeviceChannel3Led10 = 621, - CustomDeviceChannel3Led11 = 622, - CustomDeviceChannel3Led12 = 623, - CustomDeviceChannel3Led13 = 624, - CustomDeviceChannel3Led14 = 625, - CustomDeviceChannel3Led15 = 626, - CustomDeviceChannel3Led16 = 627, - CustomDeviceChannel3Led17 = 628, - CustomDeviceChannel3Led18 = 629, - CustomDeviceChannel3Led19 = 630, - CustomDeviceChannel3Led20 = 631, - CustomDeviceChannel3Led21 = 632, - CustomDeviceChannel3Led22 = 633, - CustomDeviceChannel3Led23 = 634, - CustomDeviceChannel3Led24 = 635, - CustomDeviceChannel3Led25 = 636, - CustomDeviceChannel3Led26 = 637, - CustomDeviceChannel3Led27 = 638, - CustomDeviceChannel3Led28 = 639, - CustomDeviceChannel3Led29 = 640, - CustomDeviceChannel3Led30 = 641, - CustomDeviceChannel3Led31 = 642, - CustomDeviceChannel3Led32 = 643, - CustomDeviceChannel3Led33 = 644, - CustomDeviceChannel3Led34 = 645, - CustomDeviceChannel3Led35 = 646, - CustomDeviceChannel3Led36 = 647, - CustomDeviceChannel3Led37 = 648, - CustomDeviceChannel3Led38 = 649, - CustomDeviceChannel3Led39 = 650, - CustomDeviceChannel3Led40 = 651, - CustomDeviceChannel3Led41 = 652, - CustomDeviceChannel3Led42 = 653, - CustomDeviceChannel3Led43 = 654, - CustomDeviceChannel3Led44 = 655, - CustomDeviceChannel3Led45 = 656, - CustomDeviceChannel3Led46 = 657, - CustomDeviceChannel3Led47 = 658, - CustomDeviceChannel3Led48 = 659, - CustomDeviceChannel3Led49 = 660, - CustomDeviceChannel3Led50 = 661, - CustomDeviceChannel3Led51 = 662, - CustomDeviceChannel3Led52 = 663, - CustomDeviceChannel3Led53 = 664, - CustomDeviceChannel3Led54 = 665, - CustomDeviceChannel3Led55 = 666, - CustomDeviceChannel3Led56 = 667, - CustomDeviceChannel3Led57 = 668, - CustomDeviceChannel3Led58 = 669, - CustomDeviceChannel3Led59 = 670, - CustomDeviceChannel3Led60 = 671, - CustomDeviceChannel3Led61 = 672, - CustomDeviceChannel3Led62 = 673, - CustomDeviceChannel3Led63 = 674, - CustomDeviceChannel3Led64 = 675, - CustomDeviceChannel3Led65 = 676, - CustomDeviceChannel3Led66 = 677, - CustomDeviceChannel3Led67 = 678, - CustomDeviceChannel3Led68 = 679, - CustomDeviceChannel3Led69 = 680, - CustomDeviceChannel3Led70 = 681, - CustomDeviceChannel3Led71 = 682, - CustomDeviceChannel3Led72 = 683, - CustomDeviceChannel3Led73 = 684, - CustomDeviceChannel3Led74 = 685, - CustomDeviceChannel3Led75 = 686, - CustomDeviceChannel3Led76 = 687, - CustomDeviceChannel3Led77 = 688, - CustomDeviceChannel3Led78 = 689, - CustomDeviceChannel3Led79 = 690, - CustomDeviceChannel3Led80 = 691, - CustomDeviceChannel3Led81 = 692, - CustomDeviceChannel3Led82 = 693, - CustomDeviceChannel3Led83 = 694, - CustomDeviceChannel3Led84 = 695, - CustomDeviceChannel3Led85 = 696, - CustomDeviceChannel3Led86 = 697, - CustomDeviceChannel3Led87 = 698, - CustomDeviceChannel3Led88 = 699, - CustomDeviceChannel3Led89 = 700, - CustomDeviceChannel3Led90 = 701, - CustomDeviceChannel3Led91 = 702, - CustomDeviceChannel3Led92 = 703, - CustomDeviceChannel3Led93 = 704, - CustomDeviceChannel3Led94 = 705, - CustomDeviceChannel3Led95 = 706, - CustomDeviceChannel3Led96 = 707, - CustomDeviceChannel3Led97 = 708, - CustomDeviceChannel3Led98 = 709, - CustomDeviceChannel3Led99 = 710, - CustomDeviceChannel3Led100 = 711, - CustomDeviceChannel3Led101 = 712, - CustomDeviceChannel3Led102 = 713, - CustomDeviceChannel3Led103 = 714, - CustomDeviceChannel3Led104 = 715, - CustomDeviceChannel3Led105 = 716, - CustomDeviceChannel3Led106 = 717, - CustomDeviceChannel3Led107 = 718, - CustomDeviceChannel3Led108 = 719, - CustomDeviceChannel3Led109 = 720, - CustomDeviceChannel3Led110 = 721, - CustomDeviceChannel3Led111 = 722, - CustomDeviceChannel3Led112 = 723, - CustomDeviceChannel3Led113 = 724, - CustomDeviceChannel3Led114 = 725, - CustomDeviceChannel3Led115 = 726, - CustomDeviceChannel3Led116 = 727, - CustomDeviceChannel3Led117 = 728, - CustomDeviceChannel3Led118 = 729, - CustomDeviceChannel3Led119 = 730, - CustomDeviceChannel3Led120 = 731, - CustomDeviceChannel3Led121 = 732, - CustomDeviceChannel3Led122 = 733, - CustomDeviceChannel3Led123 = 734, - CustomDeviceChannel3Led124 = 735, - CustomDeviceChannel3Led125 = 736, - CustomDeviceChannel3Led126 = 737, - CustomDeviceChannel3Led127 = 738, - CustomDeviceChannel3Led128 = 739, - CustomDeviceChannel3Led129 = 740, - CustomDeviceChannel3Led130 = 741, - CustomDeviceChannel3Led131 = 742, - CustomDeviceChannel3Led132 = 743, - CustomDeviceChannel3Led133 = 744, - CustomDeviceChannel3Led134 = 745, - CustomDeviceChannel3Led135 = 746, - CustomDeviceChannel3Led136 = 747, - CustomDeviceChannel3Led137 = 748, - CustomDeviceChannel3Led138 = 749, - CustomDeviceChannel3Led139 = 750, - CustomDeviceChannel3Led140 = 751, - CustomDeviceChannel3Led141 = 752, - CustomDeviceChannel3Led142 = 753, - CustomDeviceChannel3Led143 = 754, - CustomDeviceChannel3Led144 = 755, - CustomDeviceChannel3Led145 = 756, - CustomDeviceChannel3Led146 = 757, - CustomDeviceChannel3Led147 = 758, - CustomDeviceChannel3Led148 = 759, - CustomDeviceChannel3Led149 = 760, - CustomDeviceChannel3Led150 = 761, + DRAM1 = 600, + DRAM2 = 601, + DRAM3 = 602, + DRAM4 = 603, + DRAM5 = 604, + DRAM6 = 605, + DRAM7 = 606, + DRAM8 = 607, + DRAM9 = 608, + DRAM10 = 609, + DRAM11 = 610, + DRAM12 = 611, - CustomLiquidCoolerChannel1Led1 = 762, - CustomLiquidCoolerChannel1Led2 = 763, - CustomLiquidCoolerChannel1Led3 = 764, - CustomLiquidCoolerChannel1Led4 = 765, - CustomLiquidCoolerChannel1Led5 = 766, - CustomLiquidCoolerChannel1Led6 = 767, - CustomLiquidCoolerChannel1Led7 = 768, - CustomLiquidCoolerChannel1Led8 = 769, - CustomLiquidCoolerChannel1Led9 = 770, - CustomLiquidCoolerChannel1Led10 = 771, - CustomLiquidCoolerChannel1Led11 = 772, - CustomLiquidCoolerChannel1Led12 = 773, - CustomLiquidCoolerChannel1Led13 = 774, - CustomLiquidCoolerChannel1Led14 = 775, - CustomLiquidCoolerChannel1Led15 = 776, - CustomLiquidCoolerChannel1Led16 = 777, - CustomLiquidCoolerChannel1Led17 = 778, - CustomLiquidCoolerChannel1Led18 = 779, - CustomLiquidCoolerChannel1Led19 = 780, - CustomLiquidCoolerChannel1Led20 = 781, - CustomLiquidCoolerChannel1Led21 = 782, - CustomLiquidCoolerChannel1Led22 = 783, - CustomLiquidCoolerChannel1Led23 = 784, - CustomLiquidCoolerChannel1Led24 = 785, - CustomLiquidCoolerChannel1Led25 = 786, - CustomLiquidCoolerChannel1Led26 = 787, - CustomLiquidCoolerChannel1Led27 = 788, - CustomLiquidCoolerChannel1Led28 = 789, - CustomLiquidCoolerChannel1Led29 = 790, - CustomLiquidCoolerChannel1Led30 = 791, - CustomLiquidCoolerChannel1Led31 = 792, - CustomLiquidCoolerChannel1Led32 = 793, - CustomLiquidCoolerChannel1Led33 = 794, - CustomLiquidCoolerChannel1Led34 = 795, - CustomLiquidCoolerChannel1Led35 = 796, - CustomLiquidCoolerChannel1Led36 = 797, - CustomLiquidCoolerChannel1Led37 = 798, - CustomLiquidCoolerChannel1Led38 = 799, - CustomLiquidCoolerChannel1Led39 = 800, - CustomLiquidCoolerChannel1Led40 = 801, - CustomLiquidCoolerChannel1Led41 = 802, - CustomLiquidCoolerChannel1Led42 = 803, - CustomLiquidCoolerChannel1Led43 = 804, - CustomLiquidCoolerChannel1Led44 = 805, - CustomLiquidCoolerChannel1Led45 = 806, - CustomLiquidCoolerChannel1Led46 = 807, - CustomLiquidCoolerChannel1Led47 = 808, - CustomLiquidCoolerChannel1Led48 = 809, - CustomLiquidCoolerChannel1Led49 = 810, - CustomLiquidCoolerChannel1Led50 = 811, - CustomLiquidCoolerChannel1Led51 = 812, - CustomLiquidCoolerChannel1Led52 = 813, - CustomLiquidCoolerChannel1Led53 = 814, - CustomLiquidCoolerChannel1Led54 = 815, - CustomLiquidCoolerChannel1Led55 = 816, - CustomLiquidCoolerChannel1Led56 = 817, - CustomLiquidCoolerChannel1Led57 = 818, - CustomLiquidCoolerChannel1Led58 = 819, - CustomLiquidCoolerChannel1Led59 = 820, - CustomLiquidCoolerChannel1Led60 = 821, - CustomLiquidCoolerChannel1Led61 = 822, - CustomLiquidCoolerChannel1Led62 = 823, - CustomLiquidCoolerChannel1Led63 = 824, - CustomLiquidCoolerChannel1Led64 = 825, - CustomLiquidCoolerChannel1Led65 = 826, - CustomLiquidCoolerChannel1Led66 = 827, - CustomLiquidCoolerChannel1Led67 = 828, - CustomLiquidCoolerChannel1Led68 = 829, - CustomLiquidCoolerChannel1Led69 = 830, - CustomLiquidCoolerChannel1Led70 = 831, - CustomLiquidCoolerChannel1Led71 = 832, - CustomLiquidCoolerChannel1Led72 = 833, - CustomLiquidCoolerChannel1Led73 = 834, - CustomLiquidCoolerChannel1Led74 = 835, - CustomLiquidCoolerChannel1Led75 = 836, - CustomLiquidCoolerChannel1Led76 = 837, - CustomLiquidCoolerChannel1Led77 = 838, - CustomLiquidCoolerChannel1Led78 = 839, - CustomLiquidCoolerChannel1Led79 = 840, - CustomLiquidCoolerChannel1Led80 = 841, - CustomLiquidCoolerChannel1Led81 = 842, - CustomLiquidCoolerChannel1Led82 = 843, - CustomLiquidCoolerChannel1Led83 = 844, - CustomLiquidCoolerChannel1Led84 = 845, - CustomLiquidCoolerChannel1Led85 = 846, - CustomLiquidCoolerChannel1Led86 = 847, - CustomLiquidCoolerChannel1Led87 = 848, - CustomLiquidCoolerChannel1Led88 = 849, - CustomLiquidCoolerChannel1Led89 = 850, - CustomLiquidCoolerChannel1Led90 = 851, - CustomLiquidCoolerChannel1Led91 = 852, - CustomLiquidCoolerChannel1Led92 = 853, - CustomLiquidCoolerChannel1Led93 = 854, - CustomLiquidCoolerChannel1Led94 = 855, - CustomLiquidCoolerChannel1Led95 = 856, - CustomLiquidCoolerChannel1Led96 = 857, - CustomLiquidCoolerChannel1Led97 = 858, - CustomLiquidCoolerChannel1Led98 = 859, - CustomLiquidCoolerChannel1Led99 = 860, - CustomLiquidCoolerChannel1Led100 = 861, - CustomLiquidCoolerChannel1Led101 = 862, - CustomLiquidCoolerChannel1Led102 = 863, - CustomLiquidCoolerChannel1Led103 = 864, - CustomLiquidCoolerChannel1Led104 = 865, - CustomLiquidCoolerChannel1Led105 = 866, - CustomLiquidCoolerChannel1Led106 = 867, - CustomLiquidCoolerChannel1Led107 = 868, - CustomLiquidCoolerChannel1Led108 = 869, - CustomLiquidCoolerChannel1Led109 = 870, - CustomLiquidCoolerChannel1Led110 = 871, - CustomLiquidCoolerChannel1Led111 = 872, - CustomLiquidCoolerChannel1Led112 = 873, - CustomLiquidCoolerChannel1Led113 = 874, - CustomLiquidCoolerChannel1Led114 = 875, - CustomLiquidCoolerChannel1Led115 = 876, - CustomLiquidCoolerChannel1Led116 = 877, - CustomLiquidCoolerChannel1Led117 = 878, - CustomLiquidCoolerChannel1Led118 = 879, - CustomLiquidCoolerChannel1Led119 = 880, - CustomLiquidCoolerChannel1Led120 = 881, - CustomLiquidCoolerChannel1Led121 = 882, - CustomLiquidCoolerChannel1Led122 = 883, - CustomLiquidCoolerChannel1Led123 = 884, - CustomLiquidCoolerChannel1Led124 = 885, - CustomLiquidCoolerChannel1Led125 = 886, - CustomLiquidCoolerChannel1Led126 = 887, - CustomLiquidCoolerChannel1Led127 = 888, - CustomLiquidCoolerChannel1Led128 = 889, - CustomLiquidCoolerChannel1Led129 = 890, - CustomLiquidCoolerChannel1Led130 = 891, - CustomLiquidCoolerChannel1Led131 = 892, - CustomLiquidCoolerChannel1Led132 = 893, - CustomLiquidCoolerChannel1Led133 = 894, - CustomLiquidCoolerChannel1Led134 = 895, - CustomLiquidCoolerChannel1Led135 = 896, - CustomLiquidCoolerChannel1Led136 = 897, - CustomLiquidCoolerChannel1Led137 = 898, - CustomLiquidCoolerChannel1Led138 = 899, - CustomLiquidCoolerChannel1Led139 = 900, - CustomLiquidCoolerChannel1Led140 = 901, - CustomLiquidCoolerChannel1Led141 = 902, - CustomLiquidCoolerChannel1Led142 = 903, - CustomLiquidCoolerChannel1Led143 = 904, - CustomLiquidCoolerChannel1Led144 = 905, - CustomLiquidCoolerChannel1Led145 = 906, - CustomLiquidCoolerChannel1Led146 = 907, - CustomLiquidCoolerChannel1Led147 = 908, - CustomLiquidCoolerChannel1Led148 = 909, - CustomLiquidCoolerChannel1Led149 = 910, - CustomLiquidCoolerChannel1Led150 = 911, + CustomDeviceChannel3Led1 = 612, + CustomDeviceChannel3Led2 = 613, + CustomDeviceChannel3Led3 = 614, + CustomDeviceChannel3Led4 = 615, + CustomDeviceChannel3Led5 = 616, + CustomDeviceChannel3Led6 = 617, + CustomDeviceChannel3Led7 = 618, + CustomDeviceChannel3Led8 = 619, + CustomDeviceChannel3Led9 = 620, + CustomDeviceChannel3Led10 = 621, + CustomDeviceChannel3Led11 = 622, + CustomDeviceChannel3Led12 = 623, + CustomDeviceChannel3Led13 = 624, + CustomDeviceChannel3Led14 = 625, + CustomDeviceChannel3Led15 = 626, + CustomDeviceChannel3Led16 = 627, + CustomDeviceChannel3Led17 = 628, + CustomDeviceChannel3Led18 = 629, + CustomDeviceChannel3Led19 = 630, + CustomDeviceChannel3Led20 = 631, + CustomDeviceChannel3Led21 = 632, + CustomDeviceChannel3Led22 = 633, + CustomDeviceChannel3Led23 = 634, + CustomDeviceChannel3Led24 = 635, + CustomDeviceChannel3Led25 = 636, + CustomDeviceChannel3Led26 = 637, + CustomDeviceChannel3Led27 = 638, + CustomDeviceChannel3Led28 = 639, + CustomDeviceChannel3Led29 = 640, + CustomDeviceChannel3Led30 = 641, + CustomDeviceChannel3Led31 = 642, + CustomDeviceChannel3Led32 = 643, + CustomDeviceChannel3Led33 = 644, + CustomDeviceChannel3Led34 = 645, + CustomDeviceChannel3Led35 = 646, + CustomDeviceChannel3Led36 = 647, + CustomDeviceChannel3Led37 = 648, + CustomDeviceChannel3Led38 = 649, + CustomDeviceChannel3Led39 = 650, + CustomDeviceChannel3Led40 = 651, + CustomDeviceChannel3Led41 = 652, + CustomDeviceChannel3Led42 = 653, + CustomDeviceChannel3Led43 = 654, + CustomDeviceChannel3Led44 = 655, + CustomDeviceChannel3Led45 = 656, + CustomDeviceChannel3Led46 = 657, + CustomDeviceChannel3Led47 = 658, + CustomDeviceChannel3Led48 = 659, + CustomDeviceChannel3Led49 = 660, + CustomDeviceChannel3Led50 = 661, + CustomDeviceChannel3Led51 = 662, + CustomDeviceChannel3Led52 = 663, + CustomDeviceChannel3Led53 = 664, + CustomDeviceChannel3Led54 = 665, + CustomDeviceChannel3Led55 = 666, + CustomDeviceChannel3Led56 = 667, + CustomDeviceChannel3Led57 = 668, + CustomDeviceChannel3Led58 = 669, + CustomDeviceChannel3Led59 = 670, + CustomDeviceChannel3Led60 = 671, + CustomDeviceChannel3Led61 = 672, + CustomDeviceChannel3Led62 = 673, + CustomDeviceChannel3Led63 = 674, + CustomDeviceChannel3Led64 = 675, + CustomDeviceChannel3Led65 = 676, + CustomDeviceChannel3Led66 = 677, + CustomDeviceChannel3Led67 = 678, + CustomDeviceChannel3Led68 = 679, + CustomDeviceChannel3Led69 = 680, + CustomDeviceChannel3Led70 = 681, + CustomDeviceChannel3Led71 = 682, + CustomDeviceChannel3Led72 = 683, + CustomDeviceChannel3Led73 = 684, + CustomDeviceChannel3Led74 = 685, + CustomDeviceChannel3Led75 = 686, + CustomDeviceChannel3Led76 = 687, + CustomDeviceChannel3Led77 = 688, + CustomDeviceChannel3Led78 = 689, + CustomDeviceChannel3Led79 = 690, + CustomDeviceChannel3Led80 = 691, + CustomDeviceChannel3Led81 = 692, + CustomDeviceChannel3Led82 = 693, + CustomDeviceChannel3Led83 = 694, + CustomDeviceChannel3Led84 = 695, + CustomDeviceChannel3Led85 = 696, + CustomDeviceChannel3Led86 = 697, + CustomDeviceChannel3Led87 = 698, + CustomDeviceChannel3Led88 = 699, + CustomDeviceChannel3Led89 = 700, + CustomDeviceChannel3Led90 = 701, + CustomDeviceChannel3Led91 = 702, + CustomDeviceChannel3Led92 = 703, + CustomDeviceChannel3Led93 = 704, + CustomDeviceChannel3Led94 = 705, + CustomDeviceChannel3Led95 = 706, + CustomDeviceChannel3Led96 = 707, + CustomDeviceChannel3Led97 = 708, + CustomDeviceChannel3Led98 = 709, + CustomDeviceChannel3Led99 = 710, + CustomDeviceChannel3Led100 = 711, + CustomDeviceChannel3Led101 = 712, + CustomDeviceChannel3Led102 = 713, + CustomDeviceChannel3Led103 = 714, + CustomDeviceChannel3Led104 = 715, + CustomDeviceChannel3Led105 = 716, + CustomDeviceChannel3Led106 = 717, + CustomDeviceChannel3Led107 = 718, + CustomDeviceChannel3Led108 = 719, + CustomDeviceChannel3Led109 = 720, + CustomDeviceChannel3Led110 = 721, + CustomDeviceChannel3Led111 = 722, + CustomDeviceChannel3Led112 = 723, + CustomDeviceChannel3Led113 = 724, + CustomDeviceChannel3Led114 = 725, + CustomDeviceChannel3Led115 = 726, + CustomDeviceChannel3Led116 = 727, + CustomDeviceChannel3Led117 = 728, + CustomDeviceChannel3Led118 = 729, + CustomDeviceChannel3Led119 = 730, + CustomDeviceChannel3Led120 = 731, + CustomDeviceChannel3Led121 = 732, + CustomDeviceChannel3Led122 = 733, + CustomDeviceChannel3Led123 = 734, + CustomDeviceChannel3Led124 = 735, + CustomDeviceChannel3Led125 = 736, + CustomDeviceChannel3Led126 = 737, + CustomDeviceChannel3Led127 = 738, + CustomDeviceChannel3Led128 = 739, + CustomDeviceChannel3Led129 = 740, + CustomDeviceChannel3Led130 = 741, + CustomDeviceChannel3Led131 = 742, + CustomDeviceChannel3Led132 = 743, + CustomDeviceChannel3Led133 = 744, + CustomDeviceChannel3Led134 = 745, + CustomDeviceChannel3Led135 = 746, + CustomDeviceChannel3Led136 = 747, + CustomDeviceChannel3Led137 = 748, + CustomDeviceChannel3Led138 = 749, + CustomDeviceChannel3Led139 = 750, + CustomDeviceChannel3Led140 = 751, + CustomDeviceChannel3Led141 = 752, + CustomDeviceChannel3Led142 = 753, + CustomDeviceChannel3Led143 = 754, + CustomDeviceChannel3Led144 = 755, + CustomDeviceChannel3Led145 = 756, + CustomDeviceChannel3Led146 = 757, + CustomDeviceChannel3Led147 = 758, + CustomDeviceChannel3Led148 = 759, + CustomDeviceChannel3Led149 = 760, + CustomDeviceChannel3Led150 = 761, - CustomDeviceChannel1Led151 = 912, - CustomDeviceChannel1Led152 = 913, - CustomDeviceChannel1Led153 = 914, - CustomDeviceChannel1Led154 = 915, - CustomDeviceChannel1Led155 = 916, - CustomDeviceChannel1Led156 = 917, - CustomDeviceChannel1Led157 = 918, - CustomDeviceChannel1Led158 = 919, - CustomDeviceChannel1Led159 = 920, - CustomDeviceChannel1Led160 = 921, - CustomDeviceChannel1Led161 = 922, - CustomDeviceChannel1Led162 = 923, - CustomDeviceChannel1Led163 = 924, - CustomDeviceChannel1Led164 = 925, - CustomDeviceChannel1Led165 = 926, - CustomDeviceChannel1Led166 = 927, - CustomDeviceChannel1Led167 = 928, - CustomDeviceChannel1Led168 = 929, - CustomDeviceChannel1Led169 = 930, - CustomDeviceChannel1Led170 = 931, - CustomDeviceChannel1Led171 = 932, - CustomDeviceChannel1Led172 = 933, - CustomDeviceChannel1Led173 = 934, - CustomDeviceChannel1Led174 = 935, - CustomDeviceChannel1Led175 = 936, - CustomDeviceChannel1Led176 = 937, - CustomDeviceChannel1Led177 = 938, - CustomDeviceChannel1Led178 = 939, - CustomDeviceChannel1Led179 = 940, - CustomDeviceChannel1Led180 = 941, - CustomDeviceChannel1Led181 = 942, - CustomDeviceChannel1Led182 = 943, - CustomDeviceChannel1Led183 = 944, - CustomDeviceChannel1Led184 = 945, - CustomDeviceChannel1Led185 = 946, - CustomDeviceChannel1Led186 = 947, - CustomDeviceChannel1Led187 = 948, - CustomDeviceChannel1Led188 = 949, - CustomDeviceChannel1Led189 = 950, - CustomDeviceChannel1Led190 = 951, - CustomDeviceChannel1Led191 = 952, - CustomDeviceChannel1Led192 = 953, - CustomDeviceChannel1Led193 = 954, - CustomDeviceChannel1Led194 = 955, - CustomDeviceChannel1Led195 = 956, - CustomDeviceChannel1Led196 = 957, - CustomDeviceChannel1Led197 = 958, - CustomDeviceChannel1Led198 = 959, - CustomDeviceChannel1Led199 = 960, - CustomDeviceChannel1Led200 = 961, - CustomDeviceChannel1Led201 = 962, - CustomDeviceChannel1Led202 = 963, - CustomDeviceChannel1Led203 = 964, - CustomDeviceChannel1Led204 = 965, - CustomDeviceChannel1Led205 = 966, - CustomDeviceChannel1Led206 = 967, - CustomDeviceChannel1Led207 = 968, - CustomDeviceChannel1Led208 = 969, - CustomDeviceChannel1Led209 = 970, - CustomDeviceChannel1Led210 = 971, - CustomDeviceChannel1Led211 = 972, - CustomDeviceChannel1Led212 = 973, - CustomDeviceChannel1Led213 = 974, - CustomDeviceChannel1Led214 = 975, - CustomDeviceChannel1Led215 = 976, - CustomDeviceChannel1Led216 = 977, - CustomDeviceChannel1Led217 = 978, - CustomDeviceChannel1Led218 = 979, - CustomDeviceChannel1Led219 = 980, - CustomDeviceChannel1Led220 = 981, - CustomDeviceChannel1Led221 = 982, - CustomDeviceChannel1Led222 = 983, - CustomDeviceChannel1Led223 = 984, - CustomDeviceChannel1Led224 = 985, - CustomDeviceChannel1Led225 = 986, - CustomDeviceChannel1Led226 = 987, - CustomDeviceChannel1Led227 = 988, - CustomDeviceChannel1Led228 = 989, - CustomDeviceChannel1Led229 = 990, - CustomDeviceChannel1Led230 = 991, - CustomDeviceChannel1Led231 = 992, - CustomDeviceChannel1Led232 = 993, - CustomDeviceChannel1Led233 = 994, - CustomDeviceChannel1Led234 = 995, - CustomDeviceChannel1Led235 = 996, - CustomDeviceChannel1Led236 = 997, - CustomDeviceChannel1Led237 = 998, - CustomDeviceChannel1Led238 = 999, - CustomDeviceChannel1Led239 = 1000, - CustomDeviceChannel1Led240 = 1001, - CustomDeviceChannel1Led241 = 1002, - CustomDeviceChannel1Led242 = 1003, - CustomDeviceChannel1Led243 = 1004, - CustomDeviceChannel1Led244 = 1005, - CustomDeviceChannel1Led245 = 1006, - CustomDeviceChannel1Led246 = 1007, - CustomDeviceChannel1Led247 = 1008, - CustomDeviceChannel1Led248 = 1009, - CustomDeviceChannel1Led249 = 1010, - CustomDeviceChannel1Led250 = 1011, - CustomDeviceChannel1Led251 = 1012, - CustomDeviceChannel1Led252 = 1013, - CustomDeviceChannel1Led253 = 1014, - CustomDeviceChannel1Led254 = 1015, - CustomDeviceChannel1Led255 = 1016, - CustomDeviceChannel1Led256 = 1017, - CustomDeviceChannel1Led257 = 1018, - CustomDeviceChannel1Led258 = 1019, - CustomDeviceChannel1Led259 = 1020, - CustomDeviceChannel1Led260 = 1021, - CustomDeviceChannel1Led261 = 1022, - CustomDeviceChannel1Led262 = 1023, - CustomDeviceChannel1Led263 = 1024, - CustomDeviceChannel1Led264 = 1025, - CustomDeviceChannel1Led265 = 1026, - CustomDeviceChannel1Led266 = 1027, - CustomDeviceChannel1Led267 = 1028, - CustomDeviceChannel1Led268 = 1029, - CustomDeviceChannel1Led269 = 1030, - CustomDeviceChannel1Led270 = 1031, - CustomDeviceChannel1Led271 = 1032, - CustomDeviceChannel1Led272 = 1033, - CustomDeviceChannel1Led273 = 1034, - CustomDeviceChannel1Led274 = 1035, - CustomDeviceChannel1Led275 = 1036, - CustomDeviceChannel1Led276 = 1037, - CustomDeviceChannel1Led277 = 1038, - CustomDeviceChannel1Led278 = 1039, - CustomDeviceChannel1Led279 = 1040, - CustomDeviceChannel1Led280 = 1041, - CustomDeviceChannel1Led281 = 1042, - CustomDeviceChannel1Led282 = 1043, - CustomDeviceChannel1Led283 = 1044, - CustomDeviceChannel1Led284 = 1045, - CustomDeviceChannel1Led285 = 1046, - CustomDeviceChannel1Led286 = 1047, - CustomDeviceChannel1Led287 = 1048, - CustomDeviceChannel1Led288 = 1049, - CustomDeviceChannel1Led289 = 1050, - CustomDeviceChannel1Led290 = 1051, - CustomDeviceChannel1Led291 = 1052, - CustomDeviceChannel1Led292 = 1053, - CustomDeviceChannel1Led293 = 1054, - CustomDeviceChannel1Led294 = 1055, - CustomDeviceChannel1Led295 = 1056, - CustomDeviceChannel1Led296 = 1057, - CustomDeviceChannel1Led297 = 1058, - CustomDeviceChannel1Led298 = 1059, - CustomDeviceChannel1Led299 = 1060, - CustomDeviceChannel1Led300 = 1061, + CustomLiquidCoolerChannel1Led1 = 762, + CustomLiquidCoolerChannel1Led2 = 763, + CustomLiquidCoolerChannel1Led3 = 764, + CustomLiquidCoolerChannel1Led4 = 765, + CustomLiquidCoolerChannel1Led5 = 766, + CustomLiquidCoolerChannel1Led6 = 767, + CustomLiquidCoolerChannel1Led7 = 768, + CustomLiquidCoolerChannel1Led8 = 769, + CustomLiquidCoolerChannel1Led9 = 770, + CustomLiquidCoolerChannel1Led10 = 771, + CustomLiquidCoolerChannel1Led11 = 772, + CustomLiquidCoolerChannel1Led12 = 773, + CustomLiquidCoolerChannel1Led13 = 774, + CustomLiquidCoolerChannel1Led14 = 775, + CustomLiquidCoolerChannel1Led15 = 776, + CustomLiquidCoolerChannel1Led16 = 777, + CustomLiquidCoolerChannel1Led17 = 778, + CustomLiquidCoolerChannel1Led18 = 779, + CustomLiquidCoolerChannel1Led19 = 780, + CustomLiquidCoolerChannel1Led20 = 781, + CustomLiquidCoolerChannel1Led21 = 782, + CustomLiquidCoolerChannel1Led22 = 783, + CustomLiquidCoolerChannel1Led23 = 784, + CustomLiquidCoolerChannel1Led24 = 785, + CustomLiquidCoolerChannel1Led25 = 786, + CustomLiquidCoolerChannel1Led26 = 787, + CustomLiquidCoolerChannel1Led27 = 788, + CustomLiquidCoolerChannel1Led28 = 789, + CustomLiquidCoolerChannel1Led29 = 790, + CustomLiquidCoolerChannel1Led30 = 791, + CustomLiquidCoolerChannel1Led31 = 792, + CustomLiquidCoolerChannel1Led32 = 793, + CustomLiquidCoolerChannel1Led33 = 794, + CustomLiquidCoolerChannel1Led34 = 795, + CustomLiquidCoolerChannel1Led35 = 796, + CustomLiquidCoolerChannel1Led36 = 797, + CustomLiquidCoolerChannel1Led37 = 798, + CustomLiquidCoolerChannel1Led38 = 799, + CustomLiquidCoolerChannel1Led39 = 800, + CustomLiquidCoolerChannel1Led40 = 801, + CustomLiquidCoolerChannel1Led41 = 802, + CustomLiquidCoolerChannel1Led42 = 803, + CustomLiquidCoolerChannel1Led43 = 804, + CustomLiquidCoolerChannel1Led44 = 805, + CustomLiquidCoolerChannel1Led45 = 806, + CustomLiquidCoolerChannel1Led46 = 807, + CustomLiquidCoolerChannel1Led47 = 808, + CustomLiquidCoolerChannel1Led48 = 809, + CustomLiquidCoolerChannel1Led49 = 810, + CustomLiquidCoolerChannel1Led50 = 811, + CustomLiquidCoolerChannel1Led51 = 812, + CustomLiquidCoolerChannel1Led52 = 813, + CustomLiquidCoolerChannel1Led53 = 814, + CustomLiquidCoolerChannel1Led54 = 815, + CustomLiquidCoolerChannel1Led55 = 816, + CustomLiquidCoolerChannel1Led56 = 817, + CustomLiquidCoolerChannel1Led57 = 818, + CustomLiquidCoolerChannel1Led58 = 819, + CustomLiquidCoolerChannel1Led59 = 820, + CustomLiquidCoolerChannel1Led60 = 821, + CustomLiquidCoolerChannel1Led61 = 822, + CustomLiquidCoolerChannel1Led62 = 823, + CustomLiquidCoolerChannel1Led63 = 824, + CustomLiquidCoolerChannel1Led64 = 825, + CustomLiquidCoolerChannel1Led65 = 826, + CustomLiquidCoolerChannel1Led66 = 827, + CustomLiquidCoolerChannel1Led67 = 828, + CustomLiquidCoolerChannel1Led68 = 829, + CustomLiquidCoolerChannel1Led69 = 830, + CustomLiquidCoolerChannel1Led70 = 831, + CustomLiquidCoolerChannel1Led71 = 832, + CustomLiquidCoolerChannel1Led72 = 833, + CustomLiquidCoolerChannel1Led73 = 834, + CustomLiquidCoolerChannel1Led74 = 835, + CustomLiquidCoolerChannel1Led75 = 836, + CustomLiquidCoolerChannel1Led76 = 837, + CustomLiquidCoolerChannel1Led77 = 838, + CustomLiquidCoolerChannel1Led78 = 839, + CustomLiquidCoolerChannel1Led79 = 840, + CustomLiquidCoolerChannel1Led80 = 841, + CustomLiquidCoolerChannel1Led81 = 842, + CustomLiquidCoolerChannel1Led82 = 843, + CustomLiquidCoolerChannel1Led83 = 844, + CustomLiquidCoolerChannel1Led84 = 845, + CustomLiquidCoolerChannel1Led85 = 846, + CustomLiquidCoolerChannel1Led86 = 847, + CustomLiquidCoolerChannel1Led87 = 848, + CustomLiquidCoolerChannel1Led88 = 849, + CustomLiquidCoolerChannel1Led89 = 850, + CustomLiquidCoolerChannel1Led90 = 851, + CustomLiquidCoolerChannel1Led91 = 852, + CustomLiquidCoolerChannel1Led92 = 853, + CustomLiquidCoolerChannel1Led93 = 854, + CustomLiquidCoolerChannel1Led94 = 855, + CustomLiquidCoolerChannel1Led95 = 856, + CustomLiquidCoolerChannel1Led96 = 857, + CustomLiquidCoolerChannel1Led97 = 858, + CustomLiquidCoolerChannel1Led98 = 859, + CustomLiquidCoolerChannel1Led99 = 860, + CustomLiquidCoolerChannel1Led100 = 861, + CustomLiquidCoolerChannel1Led101 = 862, + CustomLiquidCoolerChannel1Led102 = 863, + CustomLiquidCoolerChannel1Led103 = 864, + CustomLiquidCoolerChannel1Led104 = 865, + CustomLiquidCoolerChannel1Led105 = 866, + CustomLiquidCoolerChannel1Led106 = 867, + CustomLiquidCoolerChannel1Led107 = 868, + CustomLiquidCoolerChannel1Led108 = 869, + CustomLiquidCoolerChannel1Led109 = 870, + CustomLiquidCoolerChannel1Led110 = 871, + CustomLiquidCoolerChannel1Led111 = 872, + CustomLiquidCoolerChannel1Led112 = 873, + CustomLiquidCoolerChannel1Led113 = 874, + CustomLiquidCoolerChannel1Led114 = 875, + CustomLiquidCoolerChannel1Led115 = 876, + CustomLiquidCoolerChannel1Led116 = 877, + CustomLiquidCoolerChannel1Led117 = 878, + CustomLiquidCoolerChannel1Led118 = 879, + CustomLiquidCoolerChannel1Led119 = 880, + CustomLiquidCoolerChannel1Led120 = 881, + CustomLiquidCoolerChannel1Led121 = 882, + CustomLiquidCoolerChannel1Led122 = 883, + CustomLiquidCoolerChannel1Led123 = 884, + CustomLiquidCoolerChannel1Led124 = 885, + CustomLiquidCoolerChannel1Led125 = 886, + CustomLiquidCoolerChannel1Led126 = 887, + CustomLiquidCoolerChannel1Led127 = 888, + CustomLiquidCoolerChannel1Led128 = 889, + CustomLiquidCoolerChannel1Led129 = 890, + CustomLiquidCoolerChannel1Led130 = 891, + CustomLiquidCoolerChannel1Led131 = 892, + CustomLiquidCoolerChannel1Led132 = 893, + CustomLiquidCoolerChannel1Led133 = 894, + CustomLiquidCoolerChannel1Led134 = 895, + CustomLiquidCoolerChannel1Led135 = 896, + CustomLiquidCoolerChannel1Led136 = 897, + CustomLiquidCoolerChannel1Led137 = 898, + CustomLiquidCoolerChannel1Led138 = 899, + CustomLiquidCoolerChannel1Led139 = 900, + CustomLiquidCoolerChannel1Led140 = 901, + CustomLiquidCoolerChannel1Led141 = 902, + CustomLiquidCoolerChannel1Led142 = 903, + CustomLiquidCoolerChannel1Led143 = 904, + CustomLiquidCoolerChannel1Led144 = 905, + CustomLiquidCoolerChannel1Led145 = 906, + CustomLiquidCoolerChannel1Led146 = 907, + CustomLiquidCoolerChannel1Led147 = 908, + CustomLiquidCoolerChannel1Led148 = 909, + CustomLiquidCoolerChannel1Led149 = 910, + CustomLiquidCoolerChannel1Led150 = 911, - CustomDeviceChannel2Led151 = 1062, - CustomDeviceChannel2Led152 = 1063, - CustomDeviceChannel2Led153 = 1064, - CustomDeviceChannel2Led154 = 1065, - CustomDeviceChannel2Led155 = 1066, - CustomDeviceChannel2Led156 = 1067, - CustomDeviceChannel2Led157 = 1068, - CustomDeviceChannel2Led158 = 1069, - CustomDeviceChannel2Led159 = 1070, - CustomDeviceChannel2Led160 = 1071, - CustomDeviceChannel2Led161 = 1072, - CustomDeviceChannel2Led162 = 1073, - CustomDeviceChannel2Led163 = 1074, - CustomDeviceChannel2Led164 = 1075, - CustomDeviceChannel2Led165 = 1076, - CustomDeviceChannel2Led166 = 1077, - CustomDeviceChannel2Led167 = 1078, - CustomDeviceChannel2Led168 = 1079, - CustomDeviceChannel2Led169 = 1080, - CustomDeviceChannel2Led170 = 1081, - CustomDeviceChannel2Led171 = 1082, - CustomDeviceChannel2Led172 = 1083, - CustomDeviceChannel2Led173 = 1084, - CustomDeviceChannel2Led174 = 1085, - CustomDeviceChannel2Led175 = 1086, - CustomDeviceChannel2Led176 = 1087, - CustomDeviceChannel2Led177 = 1088, - CustomDeviceChannel2Led178 = 1089, - CustomDeviceChannel2Led179 = 1090, - CustomDeviceChannel2Led180 = 1091, - CustomDeviceChannel2Led181 = 1092, - CustomDeviceChannel2Led182 = 1093, - CustomDeviceChannel2Led183 = 1094, - CustomDeviceChannel2Led184 = 1095, - CustomDeviceChannel2Led185 = 1096, - CustomDeviceChannel2Led186 = 1097, - CustomDeviceChannel2Led187 = 1098, - CustomDeviceChannel2Led188 = 1099, - CustomDeviceChannel2Led189 = 1100, - CustomDeviceChannel2Led190 = 1101, - CustomDeviceChannel2Led191 = 1102, - CustomDeviceChannel2Led192 = 1103, - CustomDeviceChannel2Led193 = 1104, - CustomDeviceChannel2Led194 = 1105, - CustomDeviceChannel2Led195 = 1106, - CustomDeviceChannel2Led196 = 1107, - CustomDeviceChannel2Led197 = 1108, - CustomDeviceChannel2Led198 = 1109, - CustomDeviceChannel2Led199 = 1110, - CustomDeviceChannel2Led200 = 1111, - CustomDeviceChannel2Led201 = 1112, - CustomDeviceChannel2Led202 = 1113, - CustomDeviceChannel2Led203 = 1114, - CustomDeviceChannel2Led204 = 1115, - CustomDeviceChannel2Led205 = 1116, - CustomDeviceChannel2Led206 = 1117, - CustomDeviceChannel2Led207 = 1118, - CustomDeviceChannel2Led208 = 1119, - CustomDeviceChannel2Led209 = 1120, - CustomDeviceChannel2Led210 = 1121, - CustomDeviceChannel2Led211 = 1122, - CustomDeviceChannel2Led212 = 1123, - CustomDeviceChannel2Led213 = 1124, - CustomDeviceChannel2Led214 = 1125, - CustomDeviceChannel2Led215 = 1126, - CustomDeviceChannel2Led216 = 1127, - CustomDeviceChannel2Led217 = 1128, - CustomDeviceChannel2Led218 = 1129, - CustomDeviceChannel2Led219 = 1130, - CustomDeviceChannel2Led220 = 1131, - CustomDeviceChannel2Led221 = 1132, - CustomDeviceChannel2Led222 = 1133, - CustomDeviceChannel2Led223 = 1134, - CustomDeviceChannel2Led224 = 1135, - CustomDeviceChannel2Led225 = 1136, - CustomDeviceChannel2Led226 = 1137, - CustomDeviceChannel2Led227 = 1138, - CustomDeviceChannel2Led228 = 1139, - CustomDeviceChannel2Led229 = 1140, - CustomDeviceChannel2Led230 = 1141, - CustomDeviceChannel2Led231 = 1142, - CustomDeviceChannel2Led232 = 1143, - CustomDeviceChannel2Led233 = 1144, - CustomDeviceChannel2Led234 = 1145, - CustomDeviceChannel2Led235 = 1146, - CustomDeviceChannel2Led236 = 1147, - CustomDeviceChannel2Led237 = 1148, - CustomDeviceChannel2Led238 = 1149, - CustomDeviceChannel2Led239 = 1150, - CustomDeviceChannel2Led240 = 1151, - CustomDeviceChannel2Led241 = 1152, - CustomDeviceChannel2Led242 = 1153, - CustomDeviceChannel2Led243 = 1154, - CustomDeviceChannel2Led244 = 1155, - CustomDeviceChannel2Led245 = 1156, - CustomDeviceChannel2Led246 = 1157, - CustomDeviceChannel2Led247 = 1158, - CustomDeviceChannel2Led248 = 1159, - CustomDeviceChannel2Led249 = 1160, - CustomDeviceChannel2Led250 = 1161, - CustomDeviceChannel2Led251 = 1162, - CustomDeviceChannel2Led252 = 1163, - CustomDeviceChannel2Led253 = 1164, - CustomDeviceChannel2Led254 = 1165, - CustomDeviceChannel2Led255 = 1166, - CustomDeviceChannel2Led256 = 1167, - CustomDeviceChannel2Led257 = 1168, - CustomDeviceChannel2Led258 = 1169, - CustomDeviceChannel2Led259 = 1170, - CustomDeviceChannel2Led260 = 1171, - CustomDeviceChannel2Led261 = 1172, - CustomDeviceChannel2Led262 = 1173, - CustomDeviceChannel2Led263 = 1174, - CustomDeviceChannel2Led264 = 1175, - CustomDeviceChannel2Led265 = 1176, - CustomDeviceChannel2Led266 = 1177, - CustomDeviceChannel2Led267 = 1178, - CustomDeviceChannel2Led268 = 1179, - CustomDeviceChannel2Led269 = 1180, - CustomDeviceChannel2Led270 = 1181, - CustomDeviceChannel2Led271 = 1182, - CustomDeviceChannel2Led272 = 1183, - CustomDeviceChannel2Led273 = 1184, - CustomDeviceChannel2Led274 = 1185, - CustomDeviceChannel2Led275 = 1186, - CustomDeviceChannel2Led276 = 1187, - CustomDeviceChannel2Led277 = 1188, - CustomDeviceChannel2Led278 = 1189, - CustomDeviceChannel2Led279 = 1190, - CustomDeviceChannel2Led280 = 1191, - CustomDeviceChannel2Led281 = 1192, - CustomDeviceChannel2Led282 = 1193, - CustomDeviceChannel2Led283 = 1194, - CustomDeviceChannel2Led284 = 1195, - CustomDeviceChannel2Led285 = 1196, - CustomDeviceChannel2Led286 = 1197, - CustomDeviceChannel2Led287 = 1198, - CustomDeviceChannel2Led288 = 1199, - CustomDeviceChannel2Led289 = 1200, - CustomDeviceChannel2Led290 = 1201, - CustomDeviceChannel2Led291 = 1202, - CustomDeviceChannel2Led292 = 1203, - CustomDeviceChannel2Led293 = 1204, - CustomDeviceChannel2Led294 = 1205, - CustomDeviceChannel2Led295 = 1206, - CustomDeviceChannel2Led296 = 1207, - CustomDeviceChannel2Led297 = 1208, - CustomDeviceChannel2Led298 = 1209, - CustomDeviceChannel2Led299 = 1210, - CustomDeviceChannel2Led300 = 1211, + CustomDeviceChannel1Led151 = 912, + CustomDeviceChannel1Led152 = 913, + CustomDeviceChannel1Led153 = 914, + CustomDeviceChannel1Led154 = 915, + CustomDeviceChannel1Led155 = 916, + CustomDeviceChannel1Led156 = 917, + CustomDeviceChannel1Led157 = 918, + CustomDeviceChannel1Led158 = 919, + CustomDeviceChannel1Led159 = 920, + CustomDeviceChannel1Led160 = 921, + CustomDeviceChannel1Led161 = 922, + CustomDeviceChannel1Led162 = 923, + CustomDeviceChannel1Led163 = 924, + CustomDeviceChannel1Led164 = 925, + CustomDeviceChannel1Led165 = 926, + CustomDeviceChannel1Led166 = 927, + CustomDeviceChannel1Led167 = 928, + CustomDeviceChannel1Led168 = 929, + CustomDeviceChannel1Led169 = 930, + CustomDeviceChannel1Led170 = 931, + CustomDeviceChannel1Led171 = 932, + CustomDeviceChannel1Led172 = 933, + CustomDeviceChannel1Led173 = 934, + CustomDeviceChannel1Led174 = 935, + CustomDeviceChannel1Led175 = 936, + CustomDeviceChannel1Led176 = 937, + CustomDeviceChannel1Led177 = 938, + CustomDeviceChannel1Led178 = 939, + CustomDeviceChannel1Led179 = 940, + CustomDeviceChannel1Led180 = 941, + CustomDeviceChannel1Led181 = 942, + CustomDeviceChannel1Led182 = 943, + CustomDeviceChannel1Led183 = 944, + CustomDeviceChannel1Led184 = 945, + CustomDeviceChannel1Led185 = 946, + CustomDeviceChannel1Led186 = 947, + CustomDeviceChannel1Led187 = 948, + CustomDeviceChannel1Led188 = 949, + CustomDeviceChannel1Led189 = 950, + CustomDeviceChannel1Led190 = 951, + CustomDeviceChannel1Led191 = 952, + CustomDeviceChannel1Led192 = 953, + CustomDeviceChannel1Led193 = 954, + CustomDeviceChannel1Led194 = 955, + CustomDeviceChannel1Led195 = 956, + CustomDeviceChannel1Led196 = 957, + CustomDeviceChannel1Led197 = 958, + CustomDeviceChannel1Led198 = 959, + CustomDeviceChannel1Led199 = 960, + CustomDeviceChannel1Led200 = 961, + CustomDeviceChannel1Led201 = 962, + CustomDeviceChannel1Led202 = 963, + CustomDeviceChannel1Led203 = 964, + CustomDeviceChannel1Led204 = 965, + CustomDeviceChannel1Led205 = 966, + CustomDeviceChannel1Led206 = 967, + CustomDeviceChannel1Led207 = 968, + CustomDeviceChannel1Led208 = 969, + CustomDeviceChannel1Led209 = 970, + CustomDeviceChannel1Led210 = 971, + CustomDeviceChannel1Led211 = 972, + CustomDeviceChannel1Led212 = 973, + CustomDeviceChannel1Led213 = 974, + CustomDeviceChannel1Led214 = 975, + CustomDeviceChannel1Led215 = 976, + CustomDeviceChannel1Led216 = 977, + CustomDeviceChannel1Led217 = 978, + CustomDeviceChannel1Led218 = 979, + CustomDeviceChannel1Led219 = 980, + CustomDeviceChannel1Led220 = 981, + CustomDeviceChannel1Led221 = 982, + CustomDeviceChannel1Led222 = 983, + CustomDeviceChannel1Led223 = 984, + CustomDeviceChannel1Led224 = 985, + CustomDeviceChannel1Led225 = 986, + CustomDeviceChannel1Led226 = 987, + CustomDeviceChannel1Led227 = 988, + CustomDeviceChannel1Led228 = 989, + CustomDeviceChannel1Led229 = 990, + CustomDeviceChannel1Led230 = 991, + CustomDeviceChannel1Led231 = 992, + CustomDeviceChannel1Led232 = 993, + CustomDeviceChannel1Led233 = 994, + CustomDeviceChannel1Led234 = 995, + CustomDeviceChannel1Led235 = 996, + CustomDeviceChannel1Led236 = 997, + CustomDeviceChannel1Led237 = 998, + CustomDeviceChannel1Led238 = 999, + CustomDeviceChannel1Led239 = 1000, + CustomDeviceChannel1Led240 = 1001, + CustomDeviceChannel1Led241 = 1002, + CustomDeviceChannel1Led242 = 1003, + CustomDeviceChannel1Led243 = 1004, + CustomDeviceChannel1Led244 = 1005, + CustomDeviceChannel1Led245 = 1006, + CustomDeviceChannel1Led246 = 1007, + CustomDeviceChannel1Led247 = 1008, + CustomDeviceChannel1Led248 = 1009, + CustomDeviceChannel1Led249 = 1010, + CustomDeviceChannel1Led250 = 1011, + CustomDeviceChannel1Led251 = 1012, + CustomDeviceChannel1Led252 = 1013, + CustomDeviceChannel1Led253 = 1014, + CustomDeviceChannel1Led254 = 1015, + CustomDeviceChannel1Led255 = 1016, + CustomDeviceChannel1Led256 = 1017, + CustomDeviceChannel1Led257 = 1018, + CustomDeviceChannel1Led258 = 1019, + CustomDeviceChannel1Led259 = 1020, + CustomDeviceChannel1Led260 = 1021, + CustomDeviceChannel1Led261 = 1022, + CustomDeviceChannel1Led262 = 1023, + CustomDeviceChannel1Led263 = 1024, + CustomDeviceChannel1Led264 = 1025, + CustomDeviceChannel1Led265 = 1026, + CustomDeviceChannel1Led266 = 1027, + CustomDeviceChannel1Led267 = 1028, + CustomDeviceChannel1Led268 = 1029, + CustomDeviceChannel1Led269 = 1030, + CustomDeviceChannel1Led270 = 1031, + CustomDeviceChannel1Led271 = 1032, + CustomDeviceChannel1Led272 = 1033, + CustomDeviceChannel1Led273 = 1034, + CustomDeviceChannel1Led274 = 1035, + CustomDeviceChannel1Led275 = 1036, + CustomDeviceChannel1Led276 = 1037, + CustomDeviceChannel1Led277 = 1038, + CustomDeviceChannel1Led278 = 1039, + CustomDeviceChannel1Led279 = 1040, + CustomDeviceChannel1Led280 = 1041, + CustomDeviceChannel1Led281 = 1042, + CustomDeviceChannel1Led282 = 1043, + CustomDeviceChannel1Led283 = 1044, + CustomDeviceChannel1Led284 = 1045, + CustomDeviceChannel1Led285 = 1046, + CustomDeviceChannel1Led286 = 1047, + CustomDeviceChannel1Led287 = 1048, + CustomDeviceChannel1Led288 = 1049, + CustomDeviceChannel1Led289 = 1050, + CustomDeviceChannel1Led290 = 1051, + CustomDeviceChannel1Led291 = 1052, + CustomDeviceChannel1Led292 = 1053, + CustomDeviceChannel1Led293 = 1054, + CustomDeviceChannel1Led294 = 1055, + CustomDeviceChannel1Led295 = 1056, + CustomDeviceChannel1Led296 = 1057, + CustomDeviceChannel1Led297 = 1058, + CustomDeviceChannel1Led298 = 1059, + CustomDeviceChannel1Led299 = 1060, + CustomDeviceChannel1Led300 = 1061, - CustomDeviceChannel3Led151 = 1212, - CustomDeviceChannel3Led152 = 1213, - CustomDeviceChannel3Led153 = 1214, - CustomDeviceChannel3Led154 = 1215, - CustomDeviceChannel3Led155 = 1216, - CustomDeviceChannel3Led156 = 1217, - CustomDeviceChannel3Led157 = 1218, - CustomDeviceChannel3Led158 = 1219, - CustomDeviceChannel3Led159 = 1220, - CustomDeviceChannel3Led160 = 1221, - CustomDeviceChannel3Led161 = 1222, - CustomDeviceChannel3Led162 = 1223, - CustomDeviceChannel3Led163 = 1224, - CustomDeviceChannel3Led164 = 1225, - CustomDeviceChannel3Led165 = 1226, - CustomDeviceChannel3Led166 = 1227, - CustomDeviceChannel3Led167 = 1228, - CustomDeviceChannel3Led168 = 1229, - CustomDeviceChannel3Led169 = 1230, - CustomDeviceChannel3Led170 = 1231, - CustomDeviceChannel3Led171 = 1232, - CustomDeviceChannel3Led172 = 1233, - CustomDeviceChannel3Led173 = 1234, - CustomDeviceChannel3Led174 = 1235, - CustomDeviceChannel3Led175 = 1236, - CustomDeviceChannel3Led176 = 1237, - CustomDeviceChannel3Led177 = 1238, - CustomDeviceChannel3Led178 = 1239, - CustomDeviceChannel3Led179 = 1240, - CustomDeviceChannel3Led180 = 1241, - CustomDeviceChannel3Led181 = 1242, - CustomDeviceChannel3Led182 = 1243, - CustomDeviceChannel3Led183 = 1244, - CustomDeviceChannel3Led184 = 1245, - CustomDeviceChannel3Led185 = 1246, - CustomDeviceChannel3Led186 = 1247, - CustomDeviceChannel3Led187 = 1248, - CustomDeviceChannel3Led188 = 1249, - CustomDeviceChannel3Led189 = 1250, - CustomDeviceChannel3Led190 = 1251, - CustomDeviceChannel3Led191 = 1252, - CustomDeviceChannel3Led192 = 1253, - CustomDeviceChannel3Led193 = 1254, - CustomDeviceChannel3Led194 = 1255, - CustomDeviceChannel3Led195 = 1256, - CustomDeviceChannel3Led196 = 1257, - CustomDeviceChannel3Led197 = 1258, - CustomDeviceChannel3Led198 = 1259, - CustomDeviceChannel3Led199 = 1260, - CustomDeviceChannel3Led200 = 1261, - CustomDeviceChannel3Led201 = 1262, - CustomDeviceChannel3Led202 = 1263, - CustomDeviceChannel3Led203 = 1264, - CustomDeviceChannel3Led204 = 1265, - CustomDeviceChannel3Led205 = 1266, - CustomDeviceChannel3Led206 = 1267, - CustomDeviceChannel3Led207 = 1268, - CustomDeviceChannel3Led208 = 1269, - CustomDeviceChannel3Led209 = 1270, - CustomDeviceChannel3Led210 = 1271, - CustomDeviceChannel3Led211 = 1272, - CustomDeviceChannel3Led212 = 1273, - CustomDeviceChannel3Led213 = 1274, - CustomDeviceChannel3Led214 = 1275, - CustomDeviceChannel3Led215 = 1276, - CustomDeviceChannel3Led216 = 1277, - CustomDeviceChannel3Led217 = 1278, - CustomDeviceChannel3Led218 = 1279, - CustomDeviceChannel3Led219 = 1280, - CustomDeviceChannel3Led220 = 1281, - CustomDeviceChannel3Led221 = 1282, - CustomDeviceChannel3Led222 = 1283, - CustomDeviceChannel3Led223 = 1284, - CustomDeviceChannel3Led224 = 1285, - CustomDeviceChannel3Led225 = 1286, - CustomDeviceChannel3Led226 = 1287, - CustomDeviceChannel3Led227 = 1288, - CustomDeviceChannel3Led228 = 1289, - CustomDeviceChannel3Led229 = 1290, - CustomDeviceChannel3Led230 = 1291, - CustomDeviceChannel3Led231 = 1292, - CustomDeviceChannel3Led232 = 1293, - CustomDeviceChannel3Led233 = 1294, - CustomDeviceChannel3Led234 = 1295, - CustomDeviceChannel3Led235 = 1296, - CustomDeviceChannel3Led236 = 1297, - CustomDeviceChannel3Led237 = 1298, - CustomDeviceChannel3Led238 = 1299, - CustomDeviceChannel3Led239 = 1300, - CustomDeviceChannel3Led240 = 1301, - CustomDeviceChannel3Led241 = 1302, - CustomDeviceChannel3Led242 = 1303, - CustomDeviceChannel3Led243 = 1304, - CustomDeviceChannel3Led244 = 1305, - CustomDeviceChannel3Led245 = 1306, - CustomDeviceChannel3Led246 = 1307, - CustomDeviceChannel3Led247 = 1308, - CustomDeviceChannel3Led248 = 1309, - CustomDeviceChannel3Led249 = 1310, - CustomDeviceChannel3Led250 = 1311, - CustomDeviceChannel3Led251 = 1312, - CustomDeviceChannel3Led252 = 1313, - CustomDeviceChannel3Led253 = 1314, - CustomDeviceChannel3Led254 = 1315, - CustomDeviceChannel3Led255 = 1316, - CustomDeviceChannel3Led256 = 1317, - CustomDeviceChannel3Led257 = 1318, - CustomDeviceChannel3Led258 = 1319, - CustomDeviceChannel3Led259 = 1320, - CustomDeviceChannel3Led260 = 1321, - CustomDeviceChannel3Led261 = 1322, - CustomDeviceChannel3Led262 = 1323, - CustomDeviceChannel3Led263 = 1324, - CustomDeviceChannel3Led264 = 1325, - CustomDeviceChannel3Led265 = 1326, - CustomDeviceChannel3Led266 = 1327, - CustomDeviceChannel3Led267 = 1328, - CustomDeviceChannel3Led268 = 1329, - CustomDeviceChannel3Led269 = 1330, - CustomDeviceChannel3Led270 = 1331, - CustomDeviceChannel3Led271 = 1332, - CustomDeviceChannel3Led272 = 1333, - CustomDeviceChannel3Led273 = 1334, - CustomDeviceChannel3Led274 = 1335, - CustomDeviceChannel3Led275 = 1336, - CustomDeviceChannel3Led276 = 1337, - CustomDeviceChannel3Led277 = 1338, - CustomDeviceChannel3Led278 = 1339, - CustomDeviceChannel3Led279 = 1340, - CustomDeviceChannel3Led280 = 1341, - CustomDeviceChannel3Led281 = 1342, - CustomDeviceChannel3Led282 = 1343, - CustomDeviceChannel3Led283 = 1344, - CustomDeviceChannel3Led284 = 1345, - CustomDeviceChannel3Led285 = 1346, - CustomDeviceChannel3Led286 = 1347, - CustomDeviceChannel3Led287 = 1348, - CustomDeviceChannel3Led288 = 1349, - CustomDeviceChannel3Led289 = 1350, - CustomDeviceChannel3Led290 = 1351, - CustomDeviceChannel3Led291 = 1352, - CustomDeviceChannel3Led292 = 1353, - CustomDeviceChannel3Led293 = 1354, - CustomDeviceChannel3Led294 = 1355, - CustomDeviceChannel3Led295 = 1356, - CustomDeviceChannel3Led296 = 1357, - CustomDeviceChannel3Led297 = 1358, - CustomDeviceChannel3Led298 = 1359, - CustomDeviceChannel3Led299 = 1360, - CustomDeviceChannel3Led300 = 1361, + CustomDeviceChannel2Led151 = 1062, + CustomDeviceChannel2Led152 = 1063, + CustomDeviceChannel2Led153 = 1064, + CustomDeviceChannel2Led154 = 1065, + CustomDeviceChannel2Led155 = 1066, + CustomDeviceChannel2Led156 = 1067, + CustomDeviceChannel2Led157 = 1068, + CustomDeviceChannel2Led158 = 1069, + CustomDeviceChannel2Led159 = 1070, + CustomDeviceChannel2Led160 = 1071, + CustomDeviceChannel2Led161 = 1072, + CustomDeviceChannel2Led162 = 1073, + CustomDeviceChannel2Led163 = 1074, + CustomDeviceChannel2Led164 = 1075, + CustomDeviceChannel2Led165 = 1076, + CustomDeviceChannel2Led166 = 1077, + CustomDeviceChannel2Led167 = 1078, + CustomDeviceChannel2Led168 = 1079, + CustomDeviceChannel2Led169 = 1080, + CustomDeviceChannel2Led170 = 1081, + CustomDeviceChannel2Led171 = 1082, + CustomDeviceChannel2Led172 = 1083, + CustomDeviceChannel2Led173 = 1084, + CustomDeviceChannel2Led174 = 1085, + CustomDeviceChannel2Led175 = 1086, + CustomDeviceChannel2Led176 = 1087, + CustomDeviceChannel2Led177 = 1088, + CustomDeviceChannel2Led178 = 1089, + CustomDeviceChannel2Led179 = 1090, + CustomDeviceChannel2Led180 = 1091, + CustomDeviceChannel2Led181 = 1092, + CustomDeviceChannel2Led182 = 1093, + CustomDeviceChannel2Led183 = 1094, + CustomDeviceChannel2Led184 = 1095, + CustomDeviceChannel2Led185 = 1096, + CustomDeviceChannel2Led186 = 1097, + CustomDeviceChannel2Led187 = 1098, + CustomDeviceChannel2Led188 = 1099, + CustomDeviceChannel2Led189 = 1100, + CustomDeviceChannel2Led190 = 1101, + CustomDeviceChannel2Led191 = 1102, + CustomDeviceChannel2Led192 = 1103, + CustomDeviceChannel2Led193 = 1104, + CustomDeviceChannel2Led194 = 1105, + CustomDeviceChannel2Led195 = 1106, + CustomDeviceChannel2Led196 = 1107, + CustomDeviceChannel2Led197 = 1108, + CustomDeviceChannel2Led198 = 1109, + CustomDeviceChannel2Led199 = 1110, + CustomDeviceChannel2Led200 = 1111, + CustomDeviceChannel2Led201 = 1112, + CustomDeviceChannel2Led202 = 1113, + CustomDeviceChannel2Led203 = 1114, + CustomDeviceChannel2Led204 = 1115, + CustomDeviceChannel2Led205 = 1116, + CustomDeviceChannel2Led206 = 1117, + CustomDeviceChannel2Led207 = 1118, + CustomDeviceChannel2Led208 = 1119, + CustomDeviceChannel2Led209 = 1120, + CustomDeviceChannel2Led210 = 1121, + CustomDeviceChannel2Led211 = 1122, + CustomDeviceChannel2Led212 = 1123, + CustomDeviceChannel2Led213 = 1124, + CustomDeviceChannel2Led214 = 1125, + CustomDeviceChannel2Led215 = 1126, + CustomDeviceChannel2Led216 = 1127, + CustomDeviceChannel2Led217 = 1128, + CustomDeviceChannel2Led218 = 1129, + CustomDeviceChannel2Led219 = 1130, + CustomDeviceChannel2Led220 = 1131, + CustomDeviceChannel2Led221 = 1132, + CustomDeviceChannel2Led222 = 1133, + CustomDeviceChannel2Led223 = 1134, + CustomDeviceChannel2Led224 = 1135, + CustomDeviceChannel2Led225 = 1136, + CustomDeviceChannel2Led226 = 1137, + CustomDeviceChannel2Led227 = 1138, + CustomDeviceChannel2Led228 = 1139, + CustomDeviceChannel2Led229 = 1140, + CustomDeviceChannel2Led230 = 1141, + CustomDeviceChannel2Led231 = 1142, + CustomDeviceChannel2Led232 = 1143, + CustomDeviceChannel2Led233 = 1144, + CustomDeviceChannel2Led234 = 1145, + CustomDeviceChannel2Led235 = 1146, + CustomDeviceChannel2Led236 = 1147, + CustomDeviceChannel2Led237 = 1148, + CustomDeviceChannel2Led238 = 1149, + CustomDeviceChannel2Led239 = 1150, + CustomDeviceChannel2Led240 = 1151, + CustomDeviceChannel2Led241 = 1152, + CustomDeviceChannel2Led242 = 1153, + CustomDeviceChannel2Led243 = 1154, + CustomDeviceChannel2Led244 = 1155, + CustomDeviceChannel2Led245 = 1156, + CustomDeviceChannel2Led246 = 1157, + CustomDeviceChannel2Led247 = 1158, + CustomDeviceChannel2Led248 = 1159, + CustomDeviceChannel2Led249 = 1160, + CustomDeviceChannel2Led250 = 1161, + CustomDeviceChannel2Led251 = 1162, + CustomDeviceChannel2Led252 = 1163, + CustomDeviceChannel2Led253 = 1164, + CustomDeviceChannel2Led254 = 1165, + CustomDeviceChannel2Led255 = 1166, + CustomDeviceChannel2Led256 = 1167, + CustomDeviceChannel2Led257 = 1168, + CustomDeviceChannel2Led258 = 1169, + CustomDeviceChannel2Led259 = 1170, + CustomDeviceChannel2Led260 = 1171, + CustomDeviceChannel2Led261 = 1172, + CustomDeviceChannel2Led262 = 1173, + CustomDeviceChannel2Led263 = 1174, + CustomDeviceChannel2Led264 = 1175, + CustomDeviceChannel2Led265 = 1176, + CustomDeviceChannel2Led266 = 1177, + CustomDeviceChannel2Led267 = 1178, + CustomDeviceChannel2Led268 = 1179, + CustomDeviceChannel2Led269 = 1180, + CustomDeviceChannel2Led270 = 1181, + CustomDeviceChannel2Led271 = 1182, + CustomDeviceChannel2Led272 = 1183, + CustomDeviceChannel2Led273 = 1184, + CustomDeviceChannel2Led274 = 1185, + CustomDeviceChannel2Led275 = 1186, + CustomDeviceChannel2Led276 = 1187, + CustomDeviceChannel2Led277 = 1188, + CustomDeviceChannel2Led278 = 1189, + CustomDeviceChannel2Led279 = 1190, + CustomDeviceChannel2Led280 = 1191, + CustomDeviceChannel2Led281 = 1192, + CustomDeviceChannel2Led282 = 1193, + CustomDeviceChannel2Led283 = 1194, + CustomDeviceChannel2Led284 = 1195, + CustomDeviceChannel2Led285 = 1196, + CustomDeviceChannel2Led286 = 1197, + CustomDeviceChannel2Led287 = 1198, + CustomDeviceChannel2Led288 = 1199, + CustomDeviceChannel2Led289 = 1200, + CustomDeviceChannel2Led290 = 1201, + CustomDeviceChannel2Led291 = 1202, + CustomDeviceChannel2Led292 = 1203, + CustomDeviceChannel2Led293 = 1204, + CustomDeviceChannel2Led294 = 1205, + CustomDeviceChannel2Led295 = 1206, + CustomDeviceChannel2Led296 = 1207, + CustomDeviceChannel2Led297 = 1208, + CustomDeviceChannel2Led298 = 1209, + CustomDeviceChannel2Led299 = 1210, + CustomDeviceChannel2Led300 = 1211, - Mainboard1 = 1362, - Mainboard2 = 1363, - Mainboard3 = 1364, - Mainboard4 = 1365, - Mainboard5 = 1366, - Mainboard6 = 1367, - Mainboard7 = 1368, - Mainboard8 = 1369, - Mainboard9 = 1370, - Mainboard10 = 1371, - Mainboard11 = 1372, - Mainboard12 = 1373, - Mainboard13 = 1374, - Mainboard14 = 1375, - Mainboard15 = 1376, - Mainboard16 = 1377, - Mainboard17 = 1378, - Mainboard18 = 1379, - Mainboard19 = 1380, - Mainboard20 = 1381, - Mainboard21 = 1382, - Mainboard22 = 1383, - Mainboard23 = 1384, - Mainboard24 = 1385, - Mainboard25 = 1386, - Mainboard26 = 1387, - Mainboard27 = 1388, - Mainboard28 = 1389, - Mainboard29 = 1390, - Mainboard30 = 1391, - Mainboard31 = 1392, - Mainboard32 = 1393, - Mainboard33 = 1394, - Mainboard34 = 1395, - Mainboard35 = 1396, - Mainboard36 = 1397, - Mainboard37 = 1398, - Mainboard38 = 1399, - Mainboard39 = 1400, - Mainboard40 = 1401, - Mainboard41 = 1402, - Mainboard42 = 1403, - Mainboard43 = 1404, - Mainboard44 = 1405, - Mainboard45 = 1406, - Mainboard46 = 1407, - Mainboard47 = 1408, - Mainboard48 = 1409, - Mainboard49 = 1410, - Mainboard50 = 1411, - Mainboard51 = 1412, - Mainboard52 = 1413, - Mainboard53 = 1414, - Mainboard54 = 1415, - Mainboard55 = 1416, - Mainboard56 = 1417, - Mainboard57 = 1418, - Mainboard58 = 1419, - Mainboard59 = 1420, - Mainboard60 = 1421, - Mainboard61 = 1422, - Mainboard62 = 1423, - Mainboard63 = 1424, - Mainboard64 = 1425, - Mainboard65 = 1426, - Mainboard66 = 1427, - Mainboard67 = 1428, - Mainboard68 = 1429, - Mainboard69 = 1430, - Mainboard70 = 1431, - Mainboard71 = 1432, - Mainboard72 = 1433, - Mainboard73 = 1434, - Mainboard74 = 1435, - Mainboard75 = 1436, - Mainboard76 = 1437, - Mainboard77 = 1438, - Mainboard78 = 1439, - Mainboard79 = 1440, - Mainboard80 = 1441, - Mainboard81 = 1442, - Mainboard82 = 1443, - Mainboard83 = 1444, - Mainboard84 = 1445, - Mainboard85 = 1446, - Mainboard86 = 1447, - Mainboard87 = 1448, - Mainboard88 = 1449, - Mainboard89 = 1450, - Mainboard90 = 1451, - Mainboard91 = 1452, - Mainboard92 = 1453, - Mainboard93 = 1454, - Mainboard94 = 1455, - Mainboard95 = 1456, - Mainboard96 = 1457, - Mainboard97 = 1458, - Mainboard98 = 1459, - Mainboard99 = 1460, - Mainboard100 = 1461, + CustomDeviceChannel3Led151 = 1212, + CustomDeviceChannel3Led152 = 1213, + CustomDeviceChannel3Led153 = 1214, + CustomDeviceChannel3Led154 = 1215, + CustomDeviceChannel3Led155 = 1216, + CustomDeviceChannel3Led156 = 1217, + CustomDeviceChannel3Led157 = 1218, + CustomDeviceChannel3Led158 = 1219, + CustomDeviceChannel3Led159 = 1220, + CustomDeviceChannel3Led160 = 1221, + CustomDeviceChannel3Led161 = 1222, + CustomDeviceChannel3Led162 = 1223, + CustomDeviceChannel3Led163 = 1224, + CustomDeviceChannel3Led164 = 1225, + CustomDeviceChannel3Led165 = 1226, + CustomDeviceChannel3Led166 = 1227, + CustomDeviceChannel3Led167 = 1228, + CustomDeviceChannel3Led168 = 1229, + CustomDeviceChannel3Led169 = 1230, + CustomDeviceChannel3Led170 = 1231, + CustomDeviceChannel3Led171 = 1232, + CustomDeviceChannel3Led172 = 1233, + CustomDeviceChannel3Led173 = 1234, + CustomDeviceChannel3Led174 = 1235, + CustomDeviceChannel3Led175 = 1236, + CustomDeviceChannel3Led176 = 1237, + CustomDeviceChannel3Led177 = 1238, + CustomDeviceChannel3Led178 = 1239, + CustomDeviceChannel3Led179 = 1240, + CustomDeviceChannel3Led180 = 1241, + CustomDeviceChannel3Led181 = 1242, + CustomDeviceChannel3Led182 = 1243, + CustomDeviceChannel3Led183 = 1244, + CustomDeviceChannel3Led184 = 1245, + CustomDeviceChannel3Led185 = 1246, + CustomDeviceChannel3Led186 = 1247, + CustomDeviceChannel3Led187 = 1248, + CustomDeviceChannel3Led188 = 1249, + CustomDeviceChannel3Led189 = 1250, + CustomDeviceChannel3Led190 = 1251, + CustomDeviceChannel3Led191 = 1252, + CustomDeviceChannel3Led192 = 1253, + CustomDeviceChannel3Led193 = 1254, + CustomDeviceChannel3Led194 = 1255, + CustomDeviceChannel3Led195 = 1256, + CustomDeviceChannel3Led196 = 1257, + CustomDeviceChannel3Led197 = 1258, + CustomDeviceChannel3Led198 = 1259, + CustomDeviceChannel3Led199 = 1260, + CustomDeviceChannel3Led200 = 1261, + CustomDeviceChannel3Led201 = 1262, + CustomDeviceChannel3Led202 = 1263, + CustomDeviceChannel3Led203 = 1264, + CustomDeviceChannel3Led204 = 1265, + CustomDeviceChannel3Led205 = 1266, + CustomDeviceChannel3Led206 = 1267, + CustomDeviceChannel3Led207 = 1268, + CustomDeviceChannel3Led208 = 1269, + CustomDeviceChannel3Led209 = 1270, + CustomDeviceChannel3Led210 = 1271, + CustomDeviceChannel3Led211 = 1272, + CustomDeviceChannel3Led212 = 1273, + CustomDeviceChannel3Led213 = 1274, + CustomDeviceChannel3Led214 = 1275, + CustomDeviceChannel3Led215 = 1276, + CustomDeviceChannel3Led216 = 1277, + CustomDeviceChannel3Led217 = 1278, + CustomDeviceChannel3Led218 = 1279, + CustomDeviceChannel3Led219 = 1280, + CustomDeviceChannel3Led220 = 1281, + CustomDeviceChannel3Led221 = 1282, + CustomDeviceChannel3Led222 = 1283, + CustomDeviceChannel3Led223 = 1284, + CustomDeviceChannel3Led224 = 1285, + CustomDeviceChannel3Led225 = 1286, + CustomDeviceChannel3Led226 = 1287, + CustomDeviceChannel3Led227 = 1288, + CustomDeviceChannel3Led228 = 1289, + CustomDeviceChannel3Led229 = 1290, + CustomDeviceChannel3Led230 = 1291, + CustomDeviceChannel3Led231 = 1292, + CustomDeviceChannel3Led232 = 1293, + CustomDeviceChannel3Led233 = 1294, + CustomDeviceChannel3Led234 = 1295, + CustomDeviceChannel3Led235 = 1296, + CustomDeviceChannel3Led236 = 1297, + CustomDeviceChannel3Led237 = 1298, + CustomDeviceChannel3Led238 = 1299, + CustomDeviceChannel3Led239 = 1300, + CustomDeviceChannel3Led240 = 1301, + CustomDeviceChannel3Led241 = 1302, + CustomDeviceChannel3Led242 = 1303, + CustomDeviceChannel3Led243 = 1304, + CustomDeviceChannel3Led244 = 1305, + CustomDeviceChannel3Led245 = 1306, + CustomDeviceChannel3Led246 = 1307, + CustomDeviceChannel3Led247 = 1308, + CustomDeviceChannel3Led248 = 1309, + CustomDeviceChannel3Led249 = 1310, + CustomDeviceChannel3Led250 = 1311, + CustomDeviceChannel3Led251 = 1312, + CustomDeviceChannel3Led252 = 1313, + CustomDeviceChannel3Led253 = 1314, + CustomDeviceChannel3Led254 = 1315, + CustomDeviceChannel3Led255 = 1316, + CustomDeviceChannel3Led256 = 1317, + CustomDeviceChannel3Led257 = 1318, + CustomDeviceChannel3Led258 = 1319, + CustomDeviceChannel3Led259 = 1320, + CustomDeviceChannel3Led260 = 1321, + CustomDeviceChannel3Led261 = 1322, + CustomDeviceChannel3Led262 = 1323, + CustomDeviceChannel3Led263 = 1324, + CustomDeviceChannel3Led264 = 1325, + CustomDeviceChannel3Led265 = 1326, + CustomDeviceChannel3Led266 = 1327, + CustomDeviceChannel3Led267 = 1328, + CustomDeviceChannel3Led268 = 1329, + CustomDeviceChannel3Led269 = 1330, + CustomDeviceChannel3Led270 = 1331, + CustomDeviceChannel3Led271 = 1332, + CustomDeviceChannel3Led272 = 1333, + CustomDeviceChannel3Led273 = 1334, + CustomDeviceChannel3Led274 = 1335, + CustomDeviceChannel3Led275 = 1336, + CustomDeviceChannel3Led276 = 1337, + CustomDeviceChannel3Led277 = 1338, + CustomDeviceChannel3Led278 = 1339, + CustomDeviceChannel3Led279 = 1340, + CustomDeviceChannel3Led280 = 1341, + CustomDeviceChannel3Led281 = 1342, + CustomDeviceChannel3Led282 = 1343, + CustomDeviceChannel3Led283 = 1344, + CustomDeviceChannel3Led284 = 1345, + CustomDeviceChannel3Led285 = 1346, + CustomDeviceChannel3Led286 = 1347, + CustomDeviceChannel3Led287 = 1348, + CustomDeviceChannel3Led288 = 1349, + CustomDeviceChannel3Led289 = 1350, + CustomDeviceChannel3Led290 = 1351, + CustomDeviceChannel3Led291 = 1352, + CustomDeviceChannel3Led292 = 1353, + CustomDeviceChannel3Led293 = 1354, + CustomDeviceChannel3Led294 = 1355, + CustomDeviceChannel3Led295 = 1356, + CustomDeviceChannel3Led296 = 1357, + CustomDeviceChannel3Led297 = 1358, + CustomDeviceChannel3Led298 = 1359, + CustomDeviceChannel3Led299 = 1360, + CustomDeviceChannel3Led300 = 1361, - GPU1 = 1462, - GPU2 = 1463, - GPU3 = 1464, - GPU4 = 1465, - GPU5 = 1466, - GPU6 = 1467, - GPU7 = 1468, - GPU8 = 1469, - GPU9 = 1470, - GPU10 = 1471, - GPU11 = 1472, - GPU12 = 1473, - GPU13 = 1474, - GPU14 = 1475, - GPU15 = 1476, - GPU16 = 1477, - GPU17 = 1478, - GPU18 = 1479, - GPU19 = 1480, - GPU20 = 1481, - GPU21 = 1482, - GPU22 = 1483, - GPU23 = 1484, - GPU24 = 1485, - GPU25 = 1486, - GPU26 = 1487, - GPU27 = 1488, - GPU28 = 1489, - GPU29 = 1490, - GPU30 = 1491, - GPU31 = 1492, - GPU32 = 1493, - GPU33 = 1494, - GPU34 = 1495, - GPU35 = 1496, - GPU36 = 1497, - GPU37 = 1498, - GPU38 = 1499, - GPU39 = 1500, - GPU40 = 1501, - GPU41 = 1502, - GPU42 = 1503, - GPU43 = 1504, - GPU44 = 1505, - GPU45 = 1506, - GPU46 = 1507, - GPU47 = 1508, - GPU48 = 1509, - GPU49 = 1510, - GPU50 = 1511, + Mainboard1 = 1362, + Mainboard2 = 1363, + Mainboard3 = 1364, + Mainboard4 = 1365, + Mainboard5 = 1366, + Mainboard6 = 1367, + Mainboard7 = 1368, + Mainboard8 = 1369, + Mainboard9 = 1370, + Mainboard10 = 1371, + Mainboard11 = 1372, + Mainboard12 = 1373, + Mainboard13 = 1374, + Mainboard14 = 1375, + Mainboard15 = 1376, + Mainboard16 = 1377, + Mainboard17 = 1378, + Mainboard18 = 1379, + Mainboard19 = 1380, + Mainboard20 = 1381, + Mainboard21 = 1382, + Mainboard22 = 1383, + Mainboard23 = 1384, + Mainboard24 = 1385, + Mainboard25 = 1386, + Mainboard26 = 1387, + Mainboard27 = 1388, + Mainboard28 = 1389, + Mainboard29 = 1390, + Mainboard30 = 1391, + Mainboard31 = 1392, + Mainboard32 = 1393, + Mainboard33 = 1394, + Mainboard34 = 1395, + Mainboard35 = 1396, + Mainboard36 = 1397, + Mainboard37 = 1398, + Mainboard38 = 1399, + Mainboard39 = 1400, + Mainboard40 = 1401, + Mainboard41 = 1402, + Mainboard42 = 1403, + Mainboard43 = 1404, + Mainboard44 = 1405, + Mainboard45 = 1406, + Mainboard46 = 1407, + Mainboard47 = 1408, + Mainboard48 = 1409, + Mainboard49 = 1410, + Mainboard50 = 1411, + Mainboard51 = 1412, + Mainboard52 = 1413, + Mainboard53 = 1414, + Mainboard54 = 1415, + Mainboard55 = 1416, + Mainboard56 = 1417, + Mainboard57 = 1418, + Mainboard58 = 1419, + Mainboard59 = 1420, + Mainboard60 = 1421, + Mainboard61 = 1422, + Mainboard62 = 1423, + Mainboard63 = 1424, + Mainboard64 = 1425, + Mainboard65 = 1426, + Mainboard66 = 1427, + Mainboard67 = 1428, + Mainboard68 = 1429, + Mainboard69 = 1430, + Mainboard70 = 1431, + Mainboard71 = 1432, + Mainboard72 = 1433, + Mainboard73 = 1434, + Mainboard74 = 1435, + Mainboard75 = 1436, + Mainboard76 = 1437, + Mainboard77 = 1438, + Mainboard78 = 1439, + Mainboard79 = 1440, + Mainboard80 = 1441, + Mainboard81 = 1442, + Mainboard82 = 1443, + Mainboard83 = 1444, + Mainboard84 = 1445, + Mainboard85 = 1446, + Mainboard86 = 1447, + Mainboard87 = 1448, + Mainboard88 = 1449, + Mainboard89 = 1450, + Mainboard90 = 1451, + Mainboard91 = 1452, + Mainboard92 = 1453, + Mainboard93 = 1454, + Mainboard94 = 1455, + Mainboard95 = 1456, + Mainboard96 = 1457, + Mainboard97 = 1458, + Mainboard98 = 1459, + Mainboard99 = 1460, + Mainboard100 = 1461, - Lightbar20 = 1512, - Lightbar21 = 1513, - Lightbar22 = 1514, - Lightbar23 = 1515, - Lightbar24 = 1516, - Lightbar25 = 1517, - Lightbar26 = 1518, - Lightbar27 = 1519, - Lightbar28 = 1520, - Lightbar29 = 1521, - Lightbar30 = 1522, - Lightbar31 = 1523, - Lightbar32 = 1524, - Lightbar33 = 1525, - Lightbar34 = 1526, - Lightbar35 = 1527, - Lightbar36 = 1528, - Lightbar37 = 1529, - Lightbar38 = 1530, - Lightbar39 = 1531, - Lightbar40 = 1532, - Lightbar41 = 1533, - Lightbar42 = 1534, - Lightbar43 = 1535, - Lightbar44 = 1536, - Lightbar45 = 1537, - Lightbar46 = 1538, - Lightbar47 = 1539, - Lightbar48 = 1540, - Lightbar49 = 1541, - Lightbar50 = 1542, + GPU1 = 1462, + GPU2 = 1463, + GPU3 = 1464, + GPU4 = 1465, + GPU5 = 1466, + GPU6 = 1467, + GPU7 = 1468, + GPU8 = 1469, + GPU9 = 1470, + GPU10 = 1471, + GPU11 = 1472, + GPU12 = 1473, + GPU13 = 1474, + GPU14 = 1475, + GPU15 = 1476, + GPU16 = 1477, + GPU17 = 1478, + GPU18 = 1479, + GPU19 = 1480, + GPU20 = 1481, + GPU21 = 1482, + GPU22 = 1483, + GPU23 = 1484, + GPU24 = 1485, + GPU25 = 1486, + GPU26 = 1487, + GPU27 = 1488, + GPU28 = 1489, + GPU29 = 1490, + GPU30 = 1491, + GPU31 = 1492, + GPU32 = 1493, + GPU33 = 1494, + GPU34 = 1495, + GPU35 = 1496, + GPU36 = 1497, + GPU37 = 1498, + GPU38 = 1499, + GPU39 = 1500, + GPU40 = 1501, + GPU41 = 1502, + GPU42 = 1503, + GPU43 = 1504, + GPU44 = 1505, + GPU45 = 1506, + GPU46 = 1507, + GPU47 = 1508, + GPU48 = 1509, + GPU49 = 1510, + GPU50 = 1511, - Profile = 1543, - } -} + Lightbar20 = 1512, + Lightbar21 = 1513, + Lightbar22 = 1514, + Lightbar23 = 1515, + Lightbar24 = 1516, + Lightbar25 = 1517, + Lightbar26 = 1518, + Lightbar27 = 1519, + Lightbar28 = 1520, + Lightbar29 = 1521, + Lightbar30 = 1522, + Lightbar31 = 1523, + Lightbar32 = 1524, + Lightbar33 = 1525, + Lightbar34 = 1526, + Lightbar35 = 1527, + Lightbar36 = 1528, + Lightbar37 = 1529, + Lightbar38 = 1530, + Lightbar39 = 1531, + Lightbar40 = 1532, + Lightbar41 = 1533, + Lightbar42 = 1534, + Lightbar43 = 1535, + Lightbar44 = 1536, + Lightbar45 = 1537, + Lightbar46 = 1538, + Lightbar47 = 1539, + Lightbar48 = 1540, + Lightbar49 = 1541, + Lightbar50 = 1542, + + Profile = 1543, + + OemLed101 = 1544, + OemLed102 = 1545, + OemLed103 = 1546, + OemLed104 = 1547, + OemLed105 = 1548, + OemLed106 = 1549, + OemLed107 = 1550, + OemLed108 = 1551, + OemLed109 = 1552, + OemLed110 = 1553, + OemLed111 = 1554, + OemLed112 = 1555, + OemLed113 = 1556, + OemLed114 = 1557, + OemLed115 = 1558, + OemLed116 = 1559, + OemLed117 = 1560, + OemLed118 = 1561, + OemLed119 = 1562, + OemLed120 = 1563, + OemLed121 = 1564, + OemLed122 = 1565, + OemLed123 = 1566, + OemLed124 = 1567, + OemLed125 = 1568, + OemLed126 = 1569, + OemLed127 = 1570, + OemLed128 = 1571, + OemLed129 = 1572, + OemLed130 = 1573, + OemLed131 = 1574, + OemLed132 = 1575, + OemLed133 = 1576, + OemLed134 = 1577, + OemLed135 = 1578, + OemLed136 = 1579, + OemLed137 = 1580, + OemLed138 = 1581, + OemLed139 = 1582, + OemLed140 = 1583, + OemLed141 = 1584, + OemLed142 = 1585, + OemLed143 = 1586, + OemLed144 = 1587, + OemLed145 = 1588, + OemLed146 = 1589, + OemLed147 = 1590, + OemLed148 = 1591, + OemLed149 = 1592, + OemLed150 = 1593, + OemLed151 = 1594, + OemLed152 = 1595, + OemLed153 = 1596, + OemLed154 = 1597, + OemLed155 = 1598, + OemLed156 = 1599, + OemLed157 = 1600, + OemLed158 = 1601, + OemLed159 = 1602, + OemLed160 = 1603, + OemLed161 = 1604, + OemLed162 = 1605, + OemLed163 = 1606, + OemLed164 = 1607, + OemLed165 = 1608, + OemLed166 = 1609, + OemLed167 = 1610, + OemLed168 = 1611, + OemLed169 = 1612, + OemLed170 = 1613, + OemLed171 = 1614, + OemLed172 = 1615, + OemLed173 = 1616, + OemLed174 = 1617, + OemLed175 = 1618, + OemLed176 = 1619, + OemLed177 = 1620, + OemLed178 = 1621, + OemLed179 = 1622, + OemLed180 = 1623, + OemLed181 = 1624, + OemLed182 = 1625, + OemLed183 = 1626, + OemLed184 = 1627, + OemLed185 = 1628, + OemLed186 = 1629, + OemLed187 = 1630, + OemLed188 = 1631, + OemLed189 = 1632, + OemLed190 = 1633, + OemLed191 = 1634, + OemLed192 = 1635, + OemLed193 = 1636, + OemLed194 = 1637, + OemLed195 = 1638, + OemLed196 = 1639, + OemLed197 = 1640, + OemLed198 = 1641, + OemLed199 = 1642, + OemLed200 = 1643, + OemLed201 = 1644, + OemLed202 = 1645, + OemLed203 = 1646, + OemLed204 = 1647, + OemLed205 = 1648, + OemLed206 = 1649, + OemLed207 = 1650, + OemLed208 = 1651, + OemLed209 = 1652, + OemLed210 = 1653, + OemLed211 = 1654, + OemLed212 = 1655, + OemLed213 = 1656, + OemLed214 = 1657, + OemLed215 = 1658, + OemLed216 = 1659, + OemLed217 = 1660, + OemLed218 = 1661, + OemLed219 = 1662, + OemLed220 = 1663, + OemLed221 = 1664, + OemLed222 = 1665, + OemLed223 = 1666, + OemLed224 = 1667, + OemLed225 = 1668, + OemLed226 = 1669, + OemLed227 = 1670, + OemLed228 = 1671, + OemLed229 = 1672, + OemLed230 = 1673, + OemLed231 = 1674, + OemLed232 = 1675, + OemLed233 = 1676, + OemLed234 = 1677, + OemLed235 = 1678, + OemLed236 = 1679, + OemLed237 = 1680, + OemLed238 = 1681, + OemLed239 = 1682, + OemLed240 = 1683, + OemLed241 = 1684, + OemLed242 = 1685, + OemLed243 = 1686, + OemLed244 = 1687, + OemLed245 = 1688, + OemLed246 = 1689, + OemLed247 = 1690, + OemLed248 = 1691, + OemLed249 = 1692, + OemLed250 = 1693, + + B7 = 1694, + B8 = 1695, + B9 = 1696, + B10 = 1697, + B11 = 1698, + B12 = 1699, + B13 = 1700, + B14 = 1701, + B15 = 1702, + B16 = 1703, + B17 = 1704, + B18 = 1705, + B19 = 1706, + B20 = 1707, +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairLogicalKeyboardLayout.cs b/RGB.NET.Devices.Corsair/Enum/CorsairLogicalKeyboardLayout.cs index 62175717..ebc4e1b8 100644 --- a/RGB.NET.Devices.Corsair/Enum/CorsairLogicalKeyboardLayout.cs +++ b/RGB.NET.Devices.Corsair/Enum/CorsairLogicalKeyboardLayout.cs @@ -1,32 +1,30 @@ // ReSharper disable InconsistentNaming // ReSharper disable UnusedMember.Global +#pragma warning disable 1591 -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member +namespace RGB.NET.Devices.Corsair; -namespace RGB.NET.Devices.Corsair +/// +/// Contains a list of available logical layouts for corsair keyboards. +/// +public enum CorsairLogicalKeyboardLayout { - /// - /// Contains list of available logical layouts for corsair keyboards. - /// - public enum CorsairLogicalKeyboardLayout - { - US_Int = 1, - NA = 2, - EU = 3, - UK = 4, - BE = 5, - BR = 6, - CH = 7, - CN = 8, - DE = 9, - ES = 10, - FR = 11, - IT = 12, - ND = 13, - RU = 14, - JP = 15, - KR = 16, - TW = 17, - MEX = 18 - }; -} + US_Int = 1, + NA = 2, + EU = 3, + UK = 4, + BE = 5, + BR = 6, + CH = 7, + CN = 8, + DE = 9, + ES = 10, + FR = 11, + IT = 12, + ND = 13, + RU = 14, + JP = 15, + KR = 16, + TW = 17, + MEX = 18 +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Corsair/Enum/CorsairPhysicalKeyboardLayout.cs index 0905b961..9f5c1c37 100644 --- a/RGB.NET.Devices.Corsair/Enum/CorsairPhysicalKeyboardLayout.cs +++ b/RGB.NET.Devices.Corsair/Enum/CorsairPhysicalKeyboardLayout.cs @@ -1,36 +1,35 @@ // ReSharper disable UnusedMember.Global // ReSharper disable InconsistentNaming -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Contains a list of available physical layouts for corsair keyboards. +/// +public enum CorsairPhysicalKeyboardLayout { /// - /// Contains list of available physical layouts for corsair keyboards. + /// US-Keyboard /// - public enum CorsairPhysicalKeyboardLayout - { - /// - /// US-Keyboard - /// - US = 1, + US = 1, - /// - /// UK-Keyboard - /// - UK = 2, + /// + /// UK-Keyboard + /// + UK = 2, - /// - /// BR-Keyboard - /// - BR = 3, + /// + /// BR-Keyboard + /// + BR = 3, - /// - /// JP-Keyboard - /// - JP = 4, + /// + /// JP-Keyboard + /// + JP = 4, - /// - /// KR-Keyboard - /// - KR = 5 - } -} + /// + /// KR-Keyboard + /// + KR = 5 +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Enum/CorsairPhysicalMouseLayout.cs b/RGB.NET.Devices.Corsair/Enum/CorsairPhysicalMouseLayout.cs index 88ee5d42..33c317c3 100644 --- a/RGB.NET.Devices.Corsair/Enum/CorsairPhysicalMouseLayout.cs +++ b/RGB.NET.Devices.Corsair/Enum/CorsairPhysicalMouseLayout.cs @@ -1,28 +1,107 @@ -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Contains a list of available physical layouts for mice. +/// +public enum CorsairPhysicalMouseLayout { /// - /// Contains list of available physical layouts for mice. - /// - public enum CorsairPhysicalMouseLayout - { - /// - /// Zone1-Mouse - /// - Zones1 = 6, - - /// - /// Zone2-Mouse - /// - Zones2 = 7, - - /// - /// Zone3-Mouse - /// - Zones3 = 8, - - /// - /// Zone4-Mouse - /// - Zones4 = 9 - } -} + /// Zone1-Mouse + /// + Zones1 = 6, + + /// + /// Zone2-Mouse + /// + Zones2 = 7, + + /// + /// Zone3-Mouse + /// + Zones3 = 8, + + /// + /// Zone4-Mouse + /// + Zones4 = 9, + + /// + /// Zone5-Mouse + /// + Zones5 = 101, + + /// + /// Zone6-Mouse + /// + Zones6 = 11, + + /// + /// Zone7-Mouse + /// + Zones7 = 12, + + /// + /// Zone8-Mouse + /// + Zones8 = 13, + + /// + /// Zone9-Mouse + /// + Zones9 = 14, + + /// + /// Zone10-Mouse + /// + Zones10 = 15, + + /// + /// Zone11-Mouse + /// + Zones11 = 16, + + /// + /// Zone12-Mouse + /// + Zones12 = 17, + + /// + /// Zone13-Mouse + /// + Zones13 = 18, + + /// + /// Zone14-Mouse + /// + Zones14 = 19, + + /// + /// Zone15-Mouse + /// + Zones15 = 20, + + /// + /// Zone16-Mouse + /// + Zones16 = 21, + + /// + /// Zone17-Mouse + /// + Zones17 = 22, + + /// + /// Zone18-Mouse + /// + Zones18 = 23, + + /// + /// Zone19-Mouse + /// + Zones19 = 24, + + /// + /// Zone20-Mouse + /// + Zones20 = 25 +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Exceptions/CUEException.cs b/RGB.NET.Devices.Corsair/Exceptions/CUEException.cs index 055d512a..aca2994d 100644 --- a/RGB.NET.Devices.Corsair/Exceptions/CUEException.cs +++ b/RGB.NET.Devices.Corsair/Exceptions/CUEException.cs @@ -3,35 +3,34 @@ using System; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents an exception thrown by the CUE. +/// +public class CUEException : ApplicationException { - /// + #region Properties & Fields + /// - /// Represents an exception thrown by the CUE. + /// Gets the provided by CUE. /// - public class CUEException : ApplicationException - { - #region Properties & Fields - - /// - /// Gets the provided by CUE. - /// - public CorsairError Error { get; } - - #endregion + public CorsairError Error { get; } - #region Constructors + #endregion - /// - /// - /// Initializes a new instance of the class. - /// - /// The provided by CUE, which leads to this exception. - public CUEException(CorsairError error) - { - this.Error = error; - } + #region Constructors - #endregion + /// + /// + /// Initializes a new instance of the class. + /// + /// The provided by CUE, which leads to this exception. + public CUEException(CorsairError error) + { + this.Error = error; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs b/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs index 664a6e68..408e907b 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairDeviceUpdateQueue.cs @@ -1,65 +1,63 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents the update-queue performing updates for corsair devices. +/// +public class CorsairDeviceUpdateQueue : UpdateQueue { - /// - /// - /// Represents the update-queue performing updates for corsair devices. - /// - public class CorsairDeviceUpdateQueue : UpdateQueue - { - #region Properties & Fields + #region Properties & Fields - private int _deviceIndex; + private int _deviceIndex; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The index used to identify the device. - public CorsairDeviceUpdateQueue(IDeviceUpdateTrigger updateTrigger, int deviceIndex) - : base(updateTrigger) - { - this._deviceIndex = deviceIndex; - } + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The index used to identify the device. + public CorsairDeviceUpdateQueue(IDeviceUpdateTrigger updateTrigger, int deviceIndex) + : base(updateTrigger) + { + this._deviceIndex = deviceIndex; + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void Update(Dictionary dataSet) + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + int structSize = Marshal.SizeOf(typeof(_CorsairLedColor)); + IntPtr ptr = Marshal.AllocHGlobal(structSize * dataSet.Length); + IntPtr addPtr = new(ptr.ToInt64()); + foreach ((object key, Color color) in dataSet) { - int structSize = Marshal.SizeOf(typeof(_CorsairLedColor)); - IntPtr ptr = Marshal.AllocHGlobal(structSize * dataSet.Count); - IntPtr addPtr = new IntPtr(ptr.ToInt64()); - foreach (KeyValuePair data in dataSet) - { - _CorsairLedColor color = new _CorsairLedColor - { - ledId = (int)data.Key, - r = data.Value.GetR(), - g = data.Value.GetG(), - b = data.Value.GetB() - }; - - Marshal.StructureToPtr(color, addPtr, false); - addPtr = new IntPtr(addPtr.ToInt64() + structSize); - } - - _CUESDK.CorsairSetLedsColorsBufferByDeviceIndex(_deviceIndex, dataSet.Count, ptr); - _CUESDK.CorsairSetLedsColorsFlushBuffer(); - Marshal.FreeHGlobal(ptr); + _CorsairLedColor corsairColor = new() + { + ledId = (int)key, + r = color.GetR(), + g = color.GetG(), + b = color.GetB() + }; + + Marshal.StructureToPtr(corsairColor, addPtr, false); + addPtr = new IntPtr(addPtr.ToInt64() + structSize); } - #endregion + _CUESDK.CorsairSetLedsColorsBufferByDeviceIndex(_deviceIndex, dataSet.Length, ptr); + _CUESDK.CorsairSetLedsColorsFlushBuffer(); + Marshal.FreeHGlobal(ptr); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairProtocolDetails.cs b/RGB.NET.Devices.Corsair/Generic/CorsairProtocolDetails.cs index 3f667615..e764e082 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairProtocolDetails.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairProtocolDetails.cs @@ -5,62 +5,61 @@ using System.Runtime.InteropServices; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Managed wrapper for CorsairProtocolDetails. +/// +public class CorsairProtocolDetails { + #region Properties & Fields + /// - /// Managed wrapper for CorsairProtocolDetails. + /// String containing version of SDK(like "1.0.0.1"). + /// Always contains valid value even if there was no CUE found. /// - public class CorsairProtocolDetails - { - #region Properties & Fields - - /// - /// String containing version of SDK(like "1.0.0.1"). - /// Always contains valid value even if there was no CUE found. - /// - public string SdkVersion { get; } - - /// - /// String containing version of CUE(like "1.0.0.1") or NULL if CUE was not found. - /// - public string ServerVersion { get; } + public string? SdkVersion { get; } - /// - /// Integer that specifies version of protocol that is implemented by current SDK. - /// Numbering starts from 1. - /// Always contains valid value even if there was no CUE found. - /// - public int SdkProtocolVersion { get; } + /// + /// String containing version of CUE(like "1.0.0.1") or NULL if CUE was not found. + /// + public string? ServerVersion { get; } - /// - /// Integer that specifies version of protocol that is implemented by CUE. - /// Numbering starts from 1. - /// If CUE was not found then this value will be 0. - /// - public int ServerProtocolVersion { get; } + /// + /// Integer that specifies version of protocol that is implemented by current SDK. + /// Numbering starts from 1. + /// Always contains valid value even if there was no CUE found. + /// + public int SdkProtocolVersion { get; } - /// - /// Boolean that specifies if there were breaking changes between version of protocol implemented by server and client. - /// - public bool BreakingChanges { get; } + /// + /// Integer that specifies version of protocol that is implemented by CUE. + /// Numbering starts from 1. + /// If CUE was not found then this value will be 0. + /// + public int ServerProtocolVersion { get; } - #endregion + /// + /// Boolean that specifies if there were breaking changes between version of protocol implemented by server and client. + /// + public bool BreakingChanges { get; } - #region Constructors + #endregion - /// - /// Internal constructor of managed CorsairProtocolDetails. - /// - /// The native CorsairProtocolDetails-struct - internal CorsairProtocolDetails(_CorsairProtocolDetails nativeDetails) - { - this.SdkVersion = nativeDetails.sdkVersion == IntPtr.Zero ? null : Marshal.PtrToStringAnsi(nativeDetails.sdkVersion); - this.ServerVersion = nativeDetails.serverVersion == IntPtr.Zero ? null : Marshal.PtrToStringAnsi(nativeDetails.serverVersion); - this.SdkProtocolVersion = nativeDetails.sdkProtocolVersion; - this.ServerProtocolVersion = nativeDetails.serverProtocolVersion; - this.BreakingChanges = nativeDetails.breakingChanges != 0; - } + #region Constructors - #endregion + /// + /// Internal constructor of managed CorsairProtocolDetails. + /// + /// The native CorsairProtocolDetails-struct + internal CorsairProtocolDetails(_CorsairProtocolDetails nativeDetails) + { + this.SdkVersion = nativeDetails.sdkVersion == IntPtr.Zero ? null : Marshal.PtrToStringAnsi(nativeDetails.sdkVersion); + this.ServerVersion = nativeDetails.serverVersion == IntPtr.Zero ? null : Marshal.PtrToStringAnsi(nativeDetails.serverVersion); + this.SdkProtocolVersion = nativeDetails.sdkProtocolVersion; + this.ServerProtocolVersion = nativeDetails.serverProtocolVersion; + this.BreakingChanges = nativeDetails.breakingChanges != 0; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs index 650a61e8..57912a52 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDevice.cs @@ -1,136 +1,76 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic CUE-device. (keyboard, mouse, headset, mousepad). +/// +public abstract class CorsairRGBDevice : AbstractRGBDevice, ICorsairRGBDevice + where TDeviceInfo : CorsairRGBDeviceInfo { - /// - /// + #region Properties & Fields + /// - /// Represents a generic CUE-device. (keyboard, mouse, headset, mousepad). + /// Gets the mapping of to used to update the LEDs of this device. /// - public abstract class CorsairRGBDevice : AbstractRGBDevice, ICorsairRGBDevice - where TDeviceInfo : CorsairRGBDeviceInfo - { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets a dictionary containing all of the . - /// - // ReSharper disable once MemberCanBePrivate.Global - protected Dictionary InternalLedMapping { get; } = new Dictionary(); - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected CorsairDeviceUpdateQueue DeviceUpdateQueue { get; set; } - - #endregion - - #region Indexer - - /// - /// Gets the with the specified . - /// - /// The of the to get. - /// The with the specified or null if no is found. - // ReSharper disable once MemberCanBePrivate.Global - public Led this[CorsairLedId ledId] => InternalLedMapping.TryGetValue(ledId, out Led led) ? led : null; + protected LedMapping Mapping { get; } - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by CUE for the device. - protected CorsairRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(CorsairDeviceUpdateQueue deviceUpdateQueue) - { - DeviceUpdateQueue = deviceUpdateQueue; - - InitializeLayout(); + /// + /// Initializes a new instance of the class. + /// + /// The generic information provided by CUE for the device. + /// The mapping to used to update the LEDs of this device. + /// The queue used to update this device. + protected CorsairRGBDevice(TDeviceInfo info, LedMapping mapping, CorsairDeviceUpdateQueue updateQueue) + : base(info, updateQueue) + { + this.Mapping = mapping; + } - foreach (Led led in LedMapping.Values) - { - CorsairLedId ledId = (CorsairLedId)led.CustomData; - if (ledId != CorsairLedId.Invalid) - InternalLedMapping.Add(ledId, led); - } + #endregion - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - } + #region Methods - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); + void ICorsairRGBDevice.Initialize() => InitializeLayout(); + + /// + /// Initializes the LEDs of the device based on the data provided by the SDK. + /// + protected virtual void InitializeLayout() + { + _CorsairLedPositions? nativeLedPositions = (_CorsairLedPositions?)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); + if (nativeLedPositions == null) return; - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) - => DeviceUpdateQueue.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is CorsairLedId ledId && (ledId != CorsairLedId.Invalid)))); + int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); + IntPtr ptr = nativeLedPositions.pLedPosition; - /// - public override void SyncBack() + for (int i = 0; i < nativeLedPositions.numberOfLed; i++) { - int structSize = Marshal.SizeOf(typeof(_CorsairLedColor)); - IntPtr ptr = Marshal.AllocHGlobal(structSize * LedMapping.Count); - IntPtr addPtr = new IntPtr(ptr.ToInt64()); - foreach (Led led in this) + _CorsairLedPosition? ledPosition = (_CorsairLedPosition?)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); + if (ledPosition == null) { - _CorsairLedColor color = new _CorsairLedColor { ledId = (int)led.CustomData }; - Marshal.StructureToPtr(color, addPtr, false); - addPtr = new IntPtr(addPtr.ToInt64() + structSize); + ptr = new IntPtr(ptr.ToInt64() + structSize); + continue; } - _CUESDK.CorsairGetLedsColorsByDeviceIndex(DeviceInfo.CorsairDeviceIndex, LedMapping.Count, ptr); - IntPtr readPtr = ptr; - for (int i = 0; i < LedMapping.Count; i++) - { - _CorsairLedColor ledColor = (_CorsairLedColor)Marshal.PtrToStructure(readPtr, typeof(_CorsairLedColor)); - SetLedColorWithoutRequest(this[(CorsairLedId)ledColor.ledId], new Color(ledColor.r, ledColor.g, ledColor.b)); + LedId ledId = Mapping.TryGetValue(ledPosition.LedId, out LedId id) ? id : LedId.Invalid; + Rectangle rectangle = ledPosition.ToRectangle(); + AddLed(ledId, rectangle.Location, rectangle.Size); - readPtr = new IntPtr(readPtr.ToInt64() + structSize); - } - - Marshal.FreeHGlobal(ptr); + ptr = new IntPtr(ptr.ToInt64() + structSize); } + } - /// - public override void Dispose() - { - try { DeviceUpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } + /// + protected override object GetLedCustomData(LedId ledId) => Mapping.TryGetValue(ledId, out CorsairLedId corsairLedId) ? corsairLedId : CorsairLedId.Invalid; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs index 88e66009..27c882d4 100644 --- a/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Generic/CorsairRGBDeviceInfo.cs @@ -1,115 +1,95 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text.RegularExpressions; using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a Corsair-. +/// +public class CorsairRGBDeviceInfo : IRGBDeviceInfo { + #region Properties & Fields + + /// + /// Gets the corsair specific device type. + /// + public CorsairDeviceType CorsairDeviceType { get; } + + /// + /// Gets the index of the . + /// + public int CorsairDeviceIndex { get; } + /// + public RGBDeviceType DeviceType { get; } + + /// + public string DeviceName { get; } + + /// + public string Manufacturer => "Corsair"; + + /// + public string Model { get; } + /// - /// Represents a generic information for a Corsair-. + /// Returns the unique ID provided by the Corsair-SDK. + /// Returns string.Empty for Custom devices. /// - public class CorsairRGBDeviceInfo : IRGBDeviceInfo + public string DeviceId { get; } + + /// + public object? LayoutMetadata { get; set; } + + /// + /// Gets a flag that describes device capabilities. () + /// + public CorsairDeviceCaps CapsMask { get; } + + #endregion + + #region Constructors + + /// + /// Internal constructor of managed . + /// + /// The index of the . + /// The type of the . + /// The native -struct + internal CorsairRGBDeviceInfo(int deviceIndex, RGBDeviceType deviceType, _CorsairDeviceInfo nativeInfo) { - #region Properties & Fields - - /// - /// Gets the corsair specific device type. - /// - public CorsairDeviceType CorsairDeviceType { get; } - - /// - /// Gets the index of the . - /// - public int CorsairDeviceIndex { get; } - - /// - public RGBDeviceType DeviceType { get; } - - /// - public string DeviceName { get; } - - /// - public string Manufacturer => "Corsair"; - - /// - public string Model { get; } - - /// - public Uri Image { get; set; } - - /// - public bool SupportsSyncBack => true; - - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - - /// - /// Gets a flag that describes device capabilities. () - /// - public CorsairDeviceCaps CapsMask { get; } - - #endregion - - #region Constructors - - /// - /// Internal constructor of managed . - /// - /// The index of the . - /// The type of the . - /// The native -struct - /// A dictionary containing counters to create unique names for equal devices models. - internal CorsairRGBDeviceInfo(int deviceIndex, RGBDeviceType deviceType, _CorsairDeviceInfo nativeInfo, Dictionary modelCounter) - { - this.CorsairDeviceIndex = deviceIndex; - this.DeviceType = deviceType; - this.CorsairDeviceType = nativeInfo.type; - this.Model = nativeInfo.model == IntPtr.Zero ? null : Regex.Replace(Marshal.PtrToStringAnsi(nativeInfo.model) ?? string.Empty, " ?DEMO", string.Empty, RegexOptions.IgnoreCase); - this.CapsMask = (CorsairDeviceCaps)nativeInfo.capsMask; - - DeviceName = GetUniqueModelName(modelCounter); - } - - /// - /// Internal constructor of managed . - /// - /// The index of the . - /// The type of the . - /// The native -struct - /// The name of the device-model (overwrites the one provided with the device info). - /// A dictionary containing counters to create unique names for equal devices models. - internal CorsairRGBDeviceInfo(int deviceIndex, RGBDeviceType deviceType, _CorsairDeviceInfo nativeInfo, string modelName, Dictionary modelCounter) - { - this.CorsairDeviceIndex = deviceIndex; - this.DeviceType = deviceType; - this.CorsairDeviceType = nativeInfo.type; - this.Model = modelName; - this.CapsMask = (CorsairDeviceCaps)nativeInfo.capsMask; - - DeviceName = GetUniqueModelName(modelCounter); - } - - #endregion - - #region Methods - - private string GetUniqueModelName(Dictionary modelCounter) - { - if (modelCounter.TryGetValue(Model, out int counter)) - { - counter = ++modelCounter[Model]; - return $"{Manufacturer} {Model} {counter}"; - } - else - { - modelCounter.Add(Model, 1); - return $"{Manufacturer} {Model}"; - } - } - - #endregion + this.CorsairDeviceIndex = deviceIndex; + this.DeviceType = deviceType; + this.CorsairDeviceType = nativeInfo.type; + this.Model = nativeInfo.model == IntPtr.Zero ? string.Empty : Regex.Replace(Marshal.PtrToStringAnsi(nativeInfo.model) ?? string.Empty, " ?DEMO", string.Empty, RegexOptions.IgnoreCase); + this.DeviceId = nativeInfo.deviceId ?? string.Empty; + this.CapsMask = (CorsairDeviceCaps)nativeInfo.capsMask; + + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + /// + /// Internal constructor of managed . + /// + /// The index of the . + /// The type of the . + /// The native -struct + /// The name of the device-model (overwrites the one provided with the device info). + internal CorsairRGBDeviceInfo(int deviceIndex, RGBDeviceType deviceType, _CorsairDeviceInfo nativeInfo, string modelName) + { + this.CorsairDeviceIndex = deviceIndex; + this.DeviceType = deviceType; + this.CorsairDeviceType = nativeInfo.type; + this.Model = modelName; + this.DeviceId = nativeInfo.deviceId ?? string.Empty; + this.CapsMask = (CorsairDeviceCaps)nativeInfo.capsMask; + + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs b/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs index 325c46cb..5e49da25 100644 --- a/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Generic/ICorsairRGBDevice.cs @@ -1,12 +1,11 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Represents a corsair RGB-device. +/// +public interface ICorsairRGBDevice : IRGBDevice { - /// - /// Represents a corsair RGB-device. - /// - internal interface ICorsairRGBDevice : IRGBDevice - { - void Initialize(CorsairDeviceUpdateQueue deviceUpdateQueue); - } -} + internal void Initialize(); +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Generic/LedMappings.cs b/RGB.NET.Devices.Corsair/Generic/LedMappings.cs new file mode 100644 index 00000000..911e58f7 --- /dev/null +++ b/RGB.NET.Devices.Corsair/Generic/LedMappings.cs @@ -0,0 +1,302 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.Corsair; + +/// +/// Contains mappings for to . +/// +public static class LedMappings +{ + static LedMappings() + { + for (int i = 0; i <= (CorsairLedId.GPU50 - CorsairLedId.GPU1); i++) + GraphicsCard.Add(LedId.GraphicsCard1 + i, CorsairLedId.GPU1 + i); + + for (int i = 0; i <= (CorsairLedId.HeadsetStandZone9 - CorsairLedId.HeadsetStandZone1); i++) + HeadsetStand.Add(LedId.HeadsetStand1 + i, CorsairLedId.HeadsetStandZone1 + i); + + for (int i = 0; i <= (CorsairLedId.Mainboard100 - CorsairLedId.Mainboard1); i++) + Mainboard.Add(LedId.Mainboard1 + i, CorsairLedId.Mainboard1 + i); + + for (int i = 0; i <= (CorsairLedId.DRAM12 - CorsairLedId.DRAM1); i++) + Memory.Add(LedId.DRAM1 + i, CorsairLedId.DRAM1 + i); + + for (int i = 0; i <= (CorsairLedId.Zone15 - CorsairLedId.Zone1); i++) + Mousepad.Add(LedId.Mousepad1 + i, CorsairLedId.Zone1 + i); + + for (int i = 0; i <= (CorsairLedId.OemLed100 - CorsairLedId.OemLed1); i++) + Keyboard.Add(LedId.Custom1 + i, CorsairLedId.OemLed1 + i); + + for (int i = 0; i <= (CorsairLedId.OemLed250 - CorsairLedId.OemLed101); i++) + Keyboard.Add(LedId.Custom101 + i, CorsairLedId.OemLed101 + i); + } + + /// + /// Gets the mapping for graphics cards. + /// + public static LedMapping GraphicsCard { get; } = new(); + + /// + /// Gets the mapping for headsets. + /// + public static LedMapping HeadsetStand { get; } = new(); + + /// + /// Gets the mapping for mainboards. + /// + public static LedMapping Mainboard { get; } = new(); + + /// + /// Gets the mapping for memory. + /// + public static LedMapping Memory { get; } = new(); + + /// + /// Gets the mapping for mousepads. + /// + public static LedMapping Mousepad { get; } = new(); + + /// + /// Gets the mapping for headsets. + /// + public static LedMapping Headset { get; } = new() + { + { LedId.Headset1, CorsairLedId.LeftLogo }, + { LedId.Headset2, CorsairLedId.RightLogo }, + }; + + /// + /// Gets the mapping for mice. + /// + public static LedMapping Mouse { get; } = new() + { + { LedId.Mouse1, CorsairLedId.B1 }, + { LedId.Mouse2, CorsairLedId.B2 }, + { LedId.Mouse3, CorsairLedId.B3 }, + { LedId.Mouse4, CorsairLedId.B4 }, + { LedId.Mouse5, CorsairLedId.B5 }, + { LedId.Mouse6, CorsairLedId.B6 }, + { LedId.Mouse7, CorsairLedId.B7 }, + { LedId.Mouse8, CorsairLedId.B8 }, + { LedId.Mouse9, CorsairLedId.B9 }, + { LedId.Mouse10, CorsairLedId.B10 }, + { LedId.Mouse11, CorsairLedId.B11 }, + { LedId.Mouse12, CorsairLedId.B12 }, + { LedId.Mouse13, CorsairLedId.B13 }, + { LedId.Mouse14, CorsairLedId.B14 }, + { LedId.Mouse15, CorsairLedId.B15 }, + { LedId.Mouse16, CorsairLedId.B16 }, + { LedId.Mouse17, CorsairLedId.B17 }, + { LedId.Mouse18, CorsairLedId.B18 }, + { LedId.Mouse19, CorsairLedId.B19 }, + { LedId.Mouse20, CorsairLedId.B20 }, + }; + + /// + /// Gets the mapping for keyboards. + /// + public static LedMapping Keyboard { get; } = new() + { + { LedId.Invalid, CorsairLedId.Invalid }, + { LedId.Logo, CorsairLedId.Logo }, + { LedId.Keyboard_Escape, CorsairLedId.Escape }, + { LedId.Keyboard_F1, CorsairLedId.F1 }, + { LedId.Keyboard_F2, CorsairLedId.F2 }, + { LedId.Keyboard_F3, CorsairLedId.F3 }, + { LedId.Keyboard_F4, CorsairLedId.F4 }, + { LedId.Keyboard_F5, CorsairLedId.F5 }, + { LedId.Keyboard_F6, CorsairLedId.F6 }, + { LedId.Keyboard_F7, CorsairLedId.F7 }, + { LedId.Keyboard_F8, CorsairLedId.F8 }, + { LedId.Keyboard_F9, CorsairLedId.F9 }, + { LedId.Keyboard_F10, CorsairLedId.F10 }, + { LedId.Keyboard_F11, CorsairLedId.F11 }, + { LedId.Keyboard_GraveAccentAndTilde, CorsairLedId.GraveAccentAndTilde }, + { LedId.Keyboard_1, CorsairLedId.D1 }, + { LedId.Keyboard_2, CorsairLedId.D2 }, + { LedId.Keyboard_3, CorsairLedId.D3 }, + { LedId.Keyboard_4, CorsairLedId.D4 }, + { LedId.Keyboard_5, CorsairLedId.D5 }, + { LedId.Keyboard_6, CorsairLedId.D6 }, + { LedId.Keyboard_7, CorsairLedId.D7 }, + { LedId.Keyboard_8, CorsairLedId.D8 }, + { LedId.Keyboard_9, CorsairLedId.D9 }, + { LedId.Keyboard_0, CorsairLedId.D0 }, + { LedId.Keyboard_MinusAndUnderscore, CorsairLedId.MinusAndUnderscore }, + { LedId.Keyboard_Tab, CorsairLedId.Tab }, + { LedId.Keyboard_Q, CorsairLedId.Q }, + { LedId.Keyboard_W, CorsairLedId.W }, + { LedId.Keyboard_E, CorsairLedId.E }, + { LedId.Keyboard_R, CorsairLedId.R }, + { LedId.Keyboard_T, CorsairLedId.T }, + { LedId.Keyboard_Y, CorsairLedId.Y }, + { LedId.Keyboard_U, CorsairLedId.U }, + { LedId.Keyboard_I, CorsairLedId.I }, + { LedId.Keyboard_O, CorsairLedId.O }, + { LedId.Keyboard_P, CorsairLedId.P }, + { LedId.Keyboard_BracketLeft, CorsairLedId.BracketLeft }, + { LedId.Keyboard_CapsLock, CorsairLedId.CapsLock }, + { LedId.Keyboard_A, CorsairLedId.A }, + { LedId.Keyboard_S, CorsairLedId.S }, + { LedId.Keyboard_D, CorsairLedId.D }, + { LedId.Keyboard_F, CorsairLedId.F }, + { LedId.Keyboard_G, CorsairLedId.G }, + { LedId.Keyboard_H, CorsairLedId.H }, + { LedId.Keyboard_J, CorsairLedId.J }, + { LedId.Keyboard_K, CorsairLedId.K }, + { LedId.Keyboard_L, CorsairLedId.L }, + { LedId.Keyboard_SemicolonAndColon, CorsairLedId.SemicolonAndColon }, + { LedId.Keyboard_ApostropheAndDoubleQuote, CorsairLedId.ApostropheAndDoubleQuote }, + { LedId.Keyboard_LeftShift, CorsairLedId.LeftShift }, + { LedId.Keyboard_NonUsBackslash, CorsairLedId.NonUsBackslash }, + { LedId.Keyboard_Z, CorsairLedId.Z }, + { LedId.Keyboard_X, CorsairLedId.X }, + { LedId.Keyboard_C, CorsairLedId.C }, + { LedId.Keyboard_V, CorsairLedId.V }, + { LedId.Keyboard_B, CorsairLedId.B }, + { LedId.Keyboard_N, CorsairLedId.N }, + { LedId.Keyboard_M, CorsairLedId.M }, + { LedId.Keyboard_CommaAndLessThan, CorsairLedId.CommaAndLessThan }, + { LedId.Keyboard_PeriodAndBiggerThan, CorsairLedId.PeriodAndBiggerThan }, + { LedId.Keyboard_SlashAndQuestionMark, CorsairLedId.SlashAndQuestionMark }, + { LedId.Keyboard_LeftCtrl, CorsairLedId.LeftCtrl }, + { LedId.Keyboard_LeftGui, CorsairLedId.LeftGui }, + { LedId.Keyboard_LeftAlt, CorsairLedId.LeftAlt }, + { LedId.Keyboard_Lang2, CorsairLedId.Lang2 }, + { LedId.Keyboard_Space, CorsairLedId.Space }, + { LedId.Keyboard_Lang1, CorsairLedId.Lang1 }, + { LedId.Keyboard_International2, CorsairLedId.International2 }, + { LedId.Keyboard_RightAlt, CorsairLedId.RightAlt }, + { LedId.Keyboard_RightGui, CorsairLedId.RightGui }, + { LedId.Keyboard_Application, CorsairLedId.Application }, + { LedId.Keyboard_Brightness, CorsairLedId.Brightness }, + { LedId.Keyboard_F12, CorsairLedId.F12 }, + { LedId.Keyboard_PrintScreen, CorsairLedId.PrintScreen }, + { LedId.Keyboard_ScrollLock, CorsairLedId.ScrollLock }, + { LedId.Keyboard_PauseBreak, CorsairLedId.PauseBreak }, + { LedId.Keyboard_Insert, CorsairLedId.Insert }, + { LedId.Keyboard_Home, CorsairLedId.Home }, + { LedId.Keyboard_PageUp, CorsairLedId.PageUp }, + { LedId.Keyboard_BracketRight, CorsairLedId.BracketRight }, + { LedId.Keyboard_Backslash, CorsairLedId.Backslash }, + { LedId.Keyboard_NonUsTilde, CorsairLedId.NonUsTilde }, + { LedId.Keyboard_Enter, CorsairLedId.Enter }, + { LedId.Keyboard_International1, CorsairLedId.International1 }, + { LedId.Keyboard_EqualsAndPlus, CorsairLedId.EqualsAndPlus }, + { LedId.Keyboard_International3, CorsairLedId.International3 }, + { LedId.Keyboard_Backspace, CorsairLedId.Backspace }, + { LedId.Keyboard_Delete, CorsairLedId.Delete }, + { LedId.Keyboard_End, CorsairLedId.End }, + { LedId.Keyboard_PageDown, CorsairLedId.PageDown }, + { LedId.Keyboard_RightShift, CorsairLedId.RightShift }, + { LedId.Keyboard_RightCtrl, CorsairLedId.RightCtrl }, + { LedId.Keyboard_ArrowUp, CorsairLedId.UpArrow }, + { LedId.Keyboard_ArrowLeft, CorsairLedId.LeftArrow }, + { LedId.Keyboard_ArrowDown, CorsairLedId.DownArrow }, + { LedId.Keyboard_ArrowRight, CorsairLedId.RightArrow }, + { LedId.Keyboard_WinLock, CorsairLedId.WinLock }, + { LedId.Keyboard_MediaMute, CorsairLedId.Mute }, + { LedId.Keyboard_MediaStop, CorsairLedId.Stop }, + { LedId.Keyboard_MediaPreviousTrack, CorsairLedId.ScanPreviousTrack }, + { LedId.Keyboard_MediaPlay, CorsairLedId.PlayPause }, + { LedId.Keyboard_MediaNextTrack, CorsairLedId.ScanNextTrack }, + { LedId.Keyboard_NumLock, CorsairLedId.NumLock }, + { LedId.Keyboard_NumSlash, CorsairLedId.KeypadSlash }, + { LedId.Keyboard_NumAsterisk, CorsairLedId.KeypadAsterisk }, + { LedId.Keyboard_NumMinus, CorsairLedId.KeypadMinus }, + { LedId.Keyboard_NumPlus, CorsairLedId.KeypadPlus }, + { LedId.Keyboard_NumEnter, CorsairLedId.KeypadEnter }, + { LedId.Keyboard_Num7, CorsairLedId.Keypad7 }, + { LedId.Keyboard_Num8, CorsairLedId.Keypad8 }, + { LedId.Keyboard_Num9, CorsairLedId.Keypad9 }, + { LedId.Keyboard_NumComma, CorsairLedId.KeypadComma }, + { LedId.Keyboard_Num4, CorsairLedId.Keypad4 }, + { LedId.Keyboard_Num5, CorsairLedId.Keypad5 }, + { LedId.Keyboard_Num6, CorsairLedId.Keypad6 }, + { LedId.Keyboard_Num1, CorsairLedId.Keypad1 }, + { LedId.Keyboard_Num2, CorsairLedId.Keypad2 }, + { LedId.Keyboard_Num3, CorsairLedId.Keypad3 }, + { LedId.Keyboard_Num0, CorsairLedId.Keypad0 }, + { LedId.Keyboard_NumPeriodAndDelete, CorsairLedId.KeypadPeriodAndDelete }, + { LedId.Keyboard_Programmable1, CorsairLedId.G1 }, + { LedId.Keyboard_Programmable2, CorsairLedId.G2 }, + { LedId.Keyboard_Programmable3, CorsairLedId.G3 }, + { LedId.Keyboard_Programmable4, CorsairLedId.G4 }, + { LedId.Keyboard_Programmable5, CorsairLedId.G5 }, + { LedId.Keyboard_Programmable6, CorsairLedId.G6 }, + { LedId.Keyboard_Programmable7, CorsairLedId.G7 }, + { LedId.Keyboard_Programmable8, CorsairLedId.G8 }, + { LedId.Keyboard_Programmable9, CorsairLedId.G9 }, + { LedId.Keyboard_Programmable10, CorsairLedId.G10 }, + { LedId.Keyboard_MediaVolumeUp, CorsairLedId.VolumeUp }, + { LedId.Keyboard_MediaVolumeDown, CorsairLedId.VolumeDown }, + { LedId.Keyboard_MacroRecording, CorsairLedId.MR }, + { LedId.Keyboard_Macro1, CorsairLedId.M1 }, + { LedId.Keyboard_Macro2, CorsairLedId.M2 }, + { LedId.Keyboard_Macro3, CorsairLedId.M3 }, + { LedId.Keyboard_Programmable11, CorsairLedId.G11 }, + { LedId.Keyboard_Programmable12, CorsairLedId.G12 }, + { LedId.Keyboard_Programmable13, CorsairLedId.G13 }, + { LedId.Keyboard_Programmable14, CorsairLedId.G14 }, + { LedId.Keyboard_Programmable15, CorsairLedId.G15 }, + { LedId.Keyboard_Programmable16, CorsairLedId.G16 }, + { LedId.Keyboard_Programmable17, CorsairLedId.G17 }, + { LedId.Keyboard_Programmable18, CorsairLedId.G18 }, + { LedId.Keyboard_International5, CorsairLedId.International5 }, + { LedId.Keyboard_International4, CorsairLedId.International4 }, + { LedId.Keyboard_Profile, CorsairLedId.Profile }, + { LedId.Keyboard_LedProgramming, CorsairLedId.LedProgramming }, + { LedId.Keyboard_Function, CorsairLedId.Fn }, + + { LedId.LedStripe1, CorsairLedId.Lightbar1 }, + { LedId.LedStripe2, CorsairLedId.Lightbar2 }, + { LedId.LedStripe3, CorsairLedId.Lightbar3 }, + { LedId.LedStripe4, CorsairLedId.Lightbar4 }, + { LedId.LedStripe5, CorsairLedId.Lightbar5 }, + { LedId.LedStripe6, CorsairLedId.Lightbar6 }, + { LedId.LedStripe7, CorsairLedId.Lightbar7 }, + { LedId.LedStripe8, CorsairLedId.Lightbar8 }, + { LedId.LedStripe9, CorsairLedId.Lightbar9 }, + { LedId.LedStripe10, CorsairLedId.Lightbar10 }, + { LedId.LedStripe11, CorsairLedId.Lightbar11 }, + { LedId.LedStripe12, CorsairLedId.Lightbar12 }, + { LedId.LedStripe13, CorsairLedId.Lightbar13 }, + { LedId.LedStripe14, CorsairLedId.Lightbar14 }, + { LedId.LedStripe15, CorsairLedId.Lightbar15 }, + { LedId.LedStripe16, CorsairLedId.Lightbar16 }, + { LedId.LedStripe17, CorsairLedId.Lightbar17 }, + { LedId.LedStripe18, CorsairLedId.Lightbar18 }, + { LedId.LedStripe19, CorsairLedId.Lightbar19 }, + { LedId.LedStripe20, CorsairLedId.Lightbar20 }, + { LedId.LedStripe21, CorsairLedId.Lightbar21 }, + { LedId.LedStripe22, CorsairLedId.Lightbar22 }, + { LedId.LedStripe23, CorsairLedId.Lightbar23 }, + { LedId.LedStripe24, CorsairLedId.Lightbar24 }, + { LedId.LedStripe25, CorsairLedId.Lightbar25 }, + { LedId.LedStripe26, CorsairLedId.Lightbar26 }, + { LedId.LedStripe27, CorsairLedId.Lightbar27 }, + { LedId.LedStripe28, CorsairLedId.Lightbar28 }, + { LedId.LedStripe29, CorsairLedId.Lightbar29 }, + { LedId.LedStripe30, CorsairLedId.Lightbar30 }, + { LedId.LedStripe31, CorsairLedId.Lightbar31 }, + { LedId.LedStripe32, CorsairLedId.Lightbar32 }, + { LedId.LedStripe33, CorsairLedId.Lightbar33 }, + { LedId.LedStripe34, CorsairLedId.Lightbar34 }, + { LedId.LedStripe35, CorsairLedId.Lightbar35 }, + { LedId.LedStripe36, CorsairLedId.Lightbar36 }, + { LedId.LedStripe37, CorsairLedId.Lightbar37 }, + { LedId.LedStripe38, CorsairLedId.Lightbar38 }, + { LedId.LedStripe39, CorsairLedId.Lightbar39 }, + { LedId.LedStripe40, CorsairLedId.Lightbar40 }, + { LedId.LedStripe41, CorsairLedId.Lightbar41 }, + { LedId.LedStripe42, CorsairLedId.Lightbar42 }, + { LedId.LedStripe43, CorsairLedId.Lightbar43 }, + { LedId.LedStripe44, CorsairLedId.Lightbar44 }, + { LedId.LedStripe45, CorsairLedId.Lightbar45 }, + { LedId.LedStripe46, CorsairLedId.Lightbar46 }, + { LedId.LedStripe47, CorsairLedId.Lightbar47 }, + { LedId.LedStripe48, CorsairLedId.Lightbar48 }, + { LedId.LedStripe49, CorsairLedId.Lightbar49 }, + { LedId.LedStripe50, CorsairLedId.Lightbar50 }, + }; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/GraphicsCard/CorsairGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Corsair/GraphicsCard/CorsairGraphicsCardRGBDevice.cs new file mode 100644 index 00000000..b1238c1b --- /dev/null +++ b/RGB.NET.Devices.Corsair/GraphicsCard/CorsairGraphicsCardRGBDevice.cs @@ -0,0 +1,27 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using RGB.NET.Core; + +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair graphics card. +/// +public class CorsairGraphicsCardRGBDevice : CorsairRGBDevice, IGraphicsCard +{ + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The specific information provided by CUE for the graphics card. + /// The queue used to update this device. + internal CorsairGraphicsCardRGBDevice(CorsairGraphicsCardRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, LedMappings.GraphicsCard, updateQueue) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/GraphicsCard/CorsairGraphicsCardRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/GraphicsCard/CorsairGraphicsCardRGBDeviceInfo.cs new file mode 100644 index 00000000..d58120c1 --- /dev/null +++ b/RGB.NET.Devices.Corsair/GraphicsCard/CorsairGraphicsCardRGBDeviceInfo.cs @@ -0,0 +1,28 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using RGB.NET.Core; +using RGB.NET.Devices.Corsair.Native; + +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a . +/// +public class CorsairGraphicsCardRGBDeviceInfo : CorsairRGBDeviceInfo +{ + #region Constructors + + /// + /// + /// Internal constructor of managed . + /// + /// The index of the . + /// The native -struct + internal CorsairGraphicsCardRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo) + : base(deviceIndex, RGBDeviceType.GraphicsCard, nativeInfo) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs index 8152a2ce..f52d5480 100644 --- a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDevice.cs @@ -3,41 +3,25 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair headset. +/// +public class CorsairHeadsetRGBDevice : CorsairRGBDevice, IHeadset { - /// + #region Constructors + + /// /// - /// Represents a corsair headset. + /// Initializes a new instance of the class. /// - public class CorsairHeadsetRGBDevice : CorsairRGBDevice, IHeadset - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the headset - internal CorsairHeadsetRGBDevice(CorsairHeadsetRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - InitializeLed(LedId.Headset1, new Rectangle(0, 0, 10, 10)); - InitializeLed(LedId.Headset2, new Rectangle(10, 0, 10, 10)); - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Headsets", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => HeadsetIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; - - #endregion - } -} + /// The specific information provided by CUE for the headset + /// The queue used to update this device. + internal CorsairHeadsetRGBDevice(CorsairHeadsetRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, LedMappings.Headset, updateQueue) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDeviceInfo.cs index 993d17d1..fb3e6962 100644 --- a/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Headset/CorsairHeadsetRGBDeviceInfo.cs @@ -1,28 +1,25 @@ -using System.Collections.Generic; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a . +/// +public class CorsairHeadsetRGBDeviceInfo : CorsairRGBDeviceInfo { + #region Constructors + /// /// - /// Represents a generic information for a . + /// Internal constructor of managed . /// - public class CorsairHeadsetRGBDeviceInfo : CorsairRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The index of the . - /// The native -struct - /// A dictionary containing counters to create unique names for equal devices models. - internal CorsairHeadsetRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo, Dictionary modelCounter) - : base(deviceIndex, RGBDeviceType.Headset, nativeInfo, modelCounter) - { } + /// The index of the . + /// The native -struct + internal CorsairHeadsetRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo) + : base(deviceIndex, RGBDeviceType.Headset, nativeInfo) + { } - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Headset/HeadsetIdMapping.cs b/RGB.NET.Devices.Corsair/Headset/HeadsetIdMapping.cs deleted file mode 100644 index d446f091..00000000 --- a/RGB.NET.Devices.Corsair/Headset/HeadsetIdMapping.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.Generic; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - internal static class HeadsetIdMapping - { - internal static readonly Dictionary DEFAULT = new Dictionary - { - { LedId.Headset1, CorsairLedId.LeftLogo }, - { LedId.Headset2, CorsairLedId.RightLogo }, - }; - } -} diff --git a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs index d7e28c94..def410df 100644 --- a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDevice.cs @@ -1,62 +1,27 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; using RGB.NET.Core; -using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair headset stand. +/// +public class CorsairHeadsetStandRGBDevice : CorsairRGBDevice, IHeadsetStand { - /// + #region Constructors + + /// /// - /// Represents a corsair headset stand. + /// Initializes a new instance of the class. /// - public class CorsairHeadsetStandRGBDevice : CorsairRGBDevice, IHeadsetStand - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the headset stand - internal CorsairHeadsetStandRGBDevice(CorsairHeadsetStandRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); - - int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); - IntPtr ptr = nativeLedPositions.pLedPosition; - - List<_CorsairLedPosition> positions = new List<_CorsairLedPosition>(); - for (int i = 0; i < nativeLedPositions.numberOfLed; i++) - { - _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); - ptr = new IntPtr(ptr.ToInt64() + structSize); - positions.Add(ledPosition); - } - - Dictionary mapping = HeadsetStandIdMapping.DEFAULT.SwapKeyValue(); - foreach (_CorsairLedPosition ledPosition in positions.OrderBy(p => p.LedId)) - InitializeLed(mapping.TryGetValue(ledPosition.LedId, out LedId ledId) ? ledId : LedId.Invalid, ledPosition.ToRectangle()); - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\HeadsetStands", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => HeadsetStandIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; - - #endregion - } -} + /// The specific information provided by CUE for the headset stand + /// The queue used to update this device. + internal CorsairHeadsetStandRGBDevice(CorsairHeadsetStandRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, LedMappings.HeadsetStand, updateQueue) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDeviceInfo.cs index 50ebbb3c..b880a6c0 100644 --- a/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/HeadsetStand/CorsairHeadsetStandRGBDeviceInfo.cs @@ -1,28 +1,25 @@ -using System.Collections.Generic; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a . +/// +public class CorsairHeadsetStandRGBDeviceInfo : CorsairRGBDeviceInfo { + #region Constructors + /// /// - /// Represents a generic information for a . + /// Internal constructor of managed . /// - public class CorsairHeadsetStandRGBDeviceInfo : CorsairRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The index of the . - /// The native -struct - /// A dictionary containing counters to create unique names for equal devices models. - internal CorsairHeadsetStandRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo, Dictionary modelCounter) - : base(deviceIndex, RGBDeviceType.HeadsetStand, nativeInfo, modelCounter) - { } + /// The index of the . + /// The native -struct + internal CorsairHeadsetStandRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo) + : base(deviceIndex, RGBDeviceType.HeadsetStand, nativeInfo) + { } - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/HeadsetStand/HeadsetStandIdMapping.cs b/RGB.NET.Devices.Corsair/HeadsetStand/HeadsetStandIdMapping.cs deleted file mode 100644 index 619f823f..00000000 --- a/RGB.NET.Devices.Corsair/HeadsetStand/HeadsetStandIdMapping.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.Collections.Generic; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - internal static class HeadsetStandIdMapping - { - internal static readonly Dictionary DEFAULT = new Dictionary - { - { LedId.HeadsetStand1, CorsairLedId.HeadsetStandZone1 }, - { LedId.HeadsetStand2, CorsairLedId.HeadsetStandZone2 }, - { LedId.HeadsetStand3, CorsairLedId.HeadsetStandZone3 }, - { LedId.HeadsetStand4, CorsairLedId.HeadsetStandZone4 }, - { LedId.HeadsetStand5, CorsairLedId.HeadsetStandZone5 }, - { LedId.HeadsetStand6, CorsairLedId.HeadsetStandZone6 }, - { LedId.HeadsetStand7, CorsairLedId.HeadsetStandZone7 }, - { LedId.HeadsetStand8, CorsairLedId.HeadsetStandZone8 }, - { LedId.HeadsetStand9, CorsairLedId.HeadsetStandZone9 } - }; - } -} diff --git a/RGB.NET.Devices.Corsair/Helper/DictionaryExtension.cs b/RGB.NET.Devices.Corsair/Helper/DictionaryExtension.cs index 2bc44f5b..3246e069 100644 --- a/RGB.NET.Devices.Corsair/Helper/DictionaryExtension.cs +++ b/RGB.NET.Devices.Corsair/Helper/DictionaryExtension.cs @@ -1,10 +1,12 @@ using System.Collections.Generic; using System.Linq; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +internal static class DictionaryExtension { - internal static class DictionaryExtension - { - public static Dictionary SwapKeyValue(this Dictionary dictionary) => dictionary.ToDictionary(x => x.Value, x => x.Key); - } -} + public static Dictionary SwapKeyValue(this Dictionary dictionary) + where TKey : notnull + where TValue : notnull + => dictionary.ToDictionary(x => x.Value, x => x.Key); +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Helper/NativeExtensions.cs b/RGB.NET.Devices.Corsair/Helper/NativeExtensions.cs index d823f096..b78851b7 100644 --- a/RGB.NET.Devices.Corsair/Helper/NativeExtensions.cs +++ b/RGB.NET.Devices.Corsair/Helper/NativeExtensions.cs @@ -1,19 +1,18 @@ using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +internal static class NativeExtensions { - internal static class NativeExtensions + internal static Rectangle ToRectangle(this _CorsairLedPosition position) { - internal static Rectangle ToRectangle(this _CorsairLedPosition position) - { - //HACK DarthAffe 08.07.2018: It seems like corsair introduced a bug here - it's always 0. - double width = position.width < 0.5 ? 10 : position.width; - double height = position.height < 0.5 ? 10 : position.height; - double posX = position.left; - double posY = position.top; + //HACK DarthAffe 08.07.2018: It seems like corsair introduced a bug here - it's always 0. + float width = position.width < 0.5f ? 10 : (float)position.width; + float height = position.height < 0.5f ? 10 : (float)position.height; + float posX = (float)position.left; + float posY = (float)position.top; - return new Rectangle(posX, posY, width, height); - } + return new Rectangle(posX, posY, width, height); } -} +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs index c1bb52ac..bdc9425b 100644 --- a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDevice.cs @@ -1,60 +1,33 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; using RGB.NET.Core; -using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair keyboard. +/// +public class CorsairKeyboardRGBDevice : CorsairRGBDevice, IKeyboard { - /// + #region Properties & Fields + + IKeyboardDeviceInfo IKeyboard.DeviceInfo => DeviceInfo; + + #endregion + + #region Constructors + + /// /// - /// Represents a corsair keyboard. + /// Initializes a new instance of the class. /// - public class CorsairKeyboardRGBDevice : CorsairRGBDevice, IKeyboard - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the keyboard - internal CorsairKeyboardRGBDevice(CorsairKeyboardRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); - - int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); - IntPtr ptr = nativeLedPositions.pLedPosition; - - Dictionary mapping = KeyboardIdMapping.DEFAULT.SwapKeyValue(); - for (int i = 0; i < nativeLedPositions.numberOfLed; i++) - { - _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); - InitializeLed(mapping.TryGetValue(ledPosition.LedId, out LedId ledId) ? ledId : LedId.Invalid, ledPosition.ToRectangle()); - - ptr = new IntPtr(ptr.ToInt64() + structSize); - } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\Corsair\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), - DeviceInfo.LogicalLayout.ToString()); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => KeyboardIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; - - #endregion - } -} + /// The specific information provided by CUE for the keyboard. + /// The queue used to update this device. + internal CorsairKeyboardRGBDevice(CorsairKeyboardRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, LedMappings.Keyboard, updateQueue) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDeviceInfo.cs index fe6d699d..efa40a82 100644 --- a/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Keyboard/CorsairKeyboardRGBDeviceInfo.cs @@ -1,48 +1,56 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System.Collections.Generic; using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// Represents a generic information for a . +/// +public class CorsairKeyboardRGBDeviceInfo : CorsairRGBDeviceInfo, IKeyboardDeviceInfo { + #region Properties & Fields + + /// + public KeyboardLayoutType Layout { get; } + + /// + /// Gets the physical layout of the keyboard. + /// + public CorsairPhysicalKeyboardLayout PhysicalLayout { get; } + + /// + /// Gets the logical layout of the keyboard as set in CUE settings. + /// + public CorsairLogicalKeyboardLayout LogicalLayout { get; } + + #endregion + + #region Constructors + /// /// - /// Represents a generic information for a . + /// Internal constructor of managed . /// - public class CorsairKeyboardRGBDeviceInfo : CorsairRGBDeviceInfo + /// The index of the . + /// The native -struct + internal CorsairKeyboardRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo) + : base(deviceIndex, RGBDeviceType.Keyboard, nativeInfo) { - #region Properties & Fields - - /// - /// Gets the physical layout of the keyboard. - /// - public CorsairPhysicalKeyboardLayout PhysicalLayout { get; } - - /// - /// Gets the logical layout of the keyboard as set in CUE settings. - /// - public CorsairLogicalKeyboardLayout LogicalLayout { get; } - - #endregion - - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The index of the . - /// The native -struct - /// A dictionary containing counters to create unique names for equal devices models. - internal CorsairKeyboardRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo, Dictionary modelCounter) - : base(deviceIndex, RGBDeviceType.Keyboard, nativeInfo, modelCounter) + this.PhysicalLayout = (CorsairPhysicalKeyboardLayout)nativeInfo.physicalLayout; + this.LogicalLayout = (CorsairLogicalKeyboardLayout)nativeInfo.logicalLayout; + this.Layout = PhysicalLayout switch { - this.PhysicalLayout = (CorsairPhysicalKeyboardLayout)nativeInfo.physicalLayout; - this.LogicalLayout = (CorsairLogicalKeyboardLayout)nativeInfo.logicalLayout; - } - - #endregion + CorsairPhysicalKeyboardLayout.US => KeyboardLayoutType.ANSI, + CorsairPhysicalKeyboardLayout.UK => KeyboardLayoutType.ISO, + CorsairPhysicalKeyboardLayout.BR => KeyboardLayoutType.ABNT, + CorsairPhysicalKeyboardLayout.JP => KeyboardLayoutType.JIS, + CorsairPhysicalKeyboardLayout.KR => KeyboardLayoutType.KS, + _ => KeyboardLayoutType.Unknown + }; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Keyboard/KeyboardIdMapping.cs b/RGB.NET.Devices.Corsair/Keyboard/KeyboardIdMapping.cs deleted file mode 100644 index 547cfefb..00000000 --- a/RGB.NET.Devices.Corsair/Keyboard/KeyboardIdMapping.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System.Collections.Generic; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - internal static class KeyboardIdMapping - { - internal static readonly Dictionary DEFAULT = new Dictionary - { - { LedId.Invalid, CorsairLedId.Invalid }, - { LedId.Logo, CorsairLedId.Logo }, - { LedId.Keyboard_Escape, CorsairLedId.Escape }, - { LedId.Keyboard_F1, CorsairLedId.F1 }, - { LedId.Keyboard_F2, CorsairLedId.F2 }, - { LedId.Keyboard_F3, CorsairLedId.F3 }, - { LedId.Keyboard_F4, CorsairLedId.F4 }, - { LedId.Keyboard_F5, CorsairLedId.F5 }, - { LedId.Keyboard_F6, CorsairLedId.F6 }, - { LedId.Keyboard_F7, CorsairLedId.F7 }, - { LedId.Keyboard_F8, CorsairLedId.F8 }, - { LedId.Keyboard_F9, CorsairLedId.F9 }, - { LedId.Keyboard_F10, CorsairLedId.F10 }, - { LedId.Keyboard_F11, CorsairLedId.F11 }, - { LedId.Keyboard_GraveAccentAndTilde, CorsairLedId.GraveAccentAndTilde }, - { LedId.Keyboard_1, CorsairLedId.D1 }, - { LedId.Keyboard_2, CorsairLedId.D2 }, - { LedId.Keyboard_3, CorsairLedId.D3 }, - { LedId.Keyboard_4, CorsairLedId.D4 }, - { LedId.Keyboard_5, CorsairLedId.D5 }, - { LedId.Keyboard_6, CorsairLedId.D6 }, - { LedId.Keyboard_7, CorsairLedId.D7 }, - { LedId.Keyboard_8, CorsairLedId.D8 }, - { LedId.Keyboard_9, CorsairLedId.D9 }, - { LedId.Keyboard_0, CorsairLedId.D0 }, - { LedId.Keyboard_MinusAndUnderscore, CorsairLedId.MinusAndUnderscore }, - { LedId.Keyboard_Tab, CorsairLedId.Tab }, - { LedId.Keyboard_Q, CorsairLedId.Q }, - { LedId.Keyboard_W, CorsairLedId.W }, - { LedId.Keyboard_E, CorsairLedId.E }, - { LedId.Keyboard_R, CorsairLedId.R }, - { LedId.Keyboard_T, CorsairLedId.T }, - { LedId.Keyboard_Y, CorsairLedId.Y }, - { LedId.Keyboard_U, CorsairLedId.U }, - { LedId.Keyboard_I, CorsairLedId.I }, - { LedId.Keyboard_O, CorsairLedId.O }, - { LedId.Keyboard_P, CorsairLedId.P }, - { LedId.Keyboard_BracketLeft, CorsairLedId.BracketLeft }, - { LedId.Keyboard_CapsLock, CorsairLedId.CapsLock }, - { LedId.Keyboard_A, CorsairLedId.A }, - { LedId.Keyboard_S, CorsairLedId.S }, - { LedId.Keyboard_D, CorsairLedId.D }, - { LedId.Keyboard_F, CorsairLedId.F }, - { LedId.Keyboard_G, CorsairLedId.G }, - { LedId.Keyboard_H, CorsairLedId.H }, - { LedId.Keyboard_J, CorsairLedId.J }, - { LedId.Keyboard_K, CorsairLedId.K }, - { LedId.Keyboard_L, CorsairLedId.L }, - { LedId.Keyboard_SemicolonAndColon, CorsairLedId.SemicolonAndColon }, - { LedId.Keyboard_ApostropheAndDoubleQuote, CorsairLedId.ApostropheAndDoubleQuote }, - { LedId.Keyboard_LeftShift, CorsairLedId.LeftShift }, - { LedId.Keyboard_NonUsBackslash, CorsairLedId.NonUsBackslash }, - { LedId.Keyboard_Z, CorsairLedId.Z }, - { LedId.Keyboard_X, CorsairLedId.X }, - { LedId.Keyboard_C, CorsairLedId.C }, - { LedId.Keyboard_V, CorsairLedId.V }, - { LedId.Keyboard_B, CorsairLedId.B }, - { LedId.Keyboard_N, CorsairLedId.N }, - { LedId.Keyboard_M, CorsairLedId.M }, - { LedId.Keyboard_CommaAndLessThan, CorsairLedId.CommaAndLessThan }, - { LedId.Keyboard_PeriodAndBiggerThan, CorsairLedId.PeriodAndBiggerThan }, - { LedId.Keyboard_SlashAndQuestionMark, CorsairLedId.SlashAndQuestionMark }, - { LedId.Keyboard_LeftCtrl, CorsairLedId.LeftCtrl }, - { LedId.Keyboard_LeftGui, CorsairLedId.LeftGui }, - { LedId.Keyboard_LeftAlt, CorsairLedId.LeftAlt }, - { LedId.Keyboard_Lang2, CorsairLedId.Lang2 }, - { LedId.Keyboard_Space, CorsairLedId.Space }, - { LedId.Keyboard_Lang1, CorsairLedId.Lang1 }, - { LedId.Keyboard_International2, CorsairLedId.International2 }, - { LedId.Keyboard_RightAlt, CorsairLedId.RightAlt }, - { LedId.Keyboard_RightGui, CorsairLedId.RightGui }, - { LedId.Keyboard_Application, CorsairLedId.Application }, - { LedId.Keyboard_Brightness, CorsairLedId.Brightness }, - { LedId.Keyboard_F12, CorsairLedId.F12 }, - { LedId.Keyboard_PrintScreen, CorsairLedId.PrintScreen }, - { LedId.Keyboard_ScrollLock, CorsairLedId.ScrollLock }, - { LedId.Keyboard_PauseBreak, CorsairLedId.PauseBreak }, - { LedId.Keyboard_Insert, CorsairLedId.Insert }, - { LedId.Keyboard_Home, CorsairLedId.Home }, - { LedId.Keyboard_PageUp, CorsairLedId.PageUp }, - { LedId.Keyboard_BracketRight, CorsairLedId.BracketRight }, - { LedId.Keyboard_Backslash, CorsairLedId.Backslash }, - { LedId.Keyboard_NonUsTilde, CorsairLedId.NonUsTilde }, - { LedId.Keyboard_Enter, CorsairLedId.Enter }, - { LedId.Keyboard_International1, CorsairLedId.International1 }, - { LedId.Keyboard_EqualsAndPlus, CorsairLedId.EqualsAndPlus }, - { LedId.Keyboard_International3, CorsairLedId.International3 }, - { LedId.Keyboard_Backspace, CorsairLedId.Backspace }, - { LedId.Keyboard_Delete, CorsairLedId.Delete }, - { LedId.Keyboard_End, CorsairLedId.End }, - { LedId.Keyboard_PageDown, CorsairLedId.PageDown }, - { LedId.Keyboard_RightShift, CorsairLedId.RightShift }, - { LedId.Keyboard_RightCtrl, CorsairLedId.RightCtrl }, - { LedId.Keyboard_ArrowUp, CorsairLedId.UpArrow }, - { LedId.Keyboard_ArrowLeft, CorsairLedId.LeftArrow }, - { LedId.Keyboard_ArrowDown, CorsairLedId.DownArrow }, - { LedId.Keyboard_ArrowRight, CorsairLedId.RightArrow }, - { LedId.Keyboard_WinLock, CorsairLedId.WinLock }, - { LedId.Keyboard_MediaMute, CorsairLedId.Mute }, - { LedId.Keyboard_MediaStop, CorsairLedId.Stop }, - { LedId.Keyboard_MediaPreviousTrack, CorsairLedId.ScanPreviousTrack }, - { LedId.Keyboard_MediaPlay, CorsairLedId.PlayPause }, - { LedId.Keyboard_MediaNextTrack, CorsairLedId.ScanNextTrack }, - { LedId.Keyboard_NumLock, CorsairLedId.NumLock }, - { LedId.Keyboard_NumSlash, CorsairLedId.KeypadSlash }, - { LedId.Keyboard_NumAsterisk, CorsairLedId.KeypadAsterisk }, - { LedId.Keyboard_NumMinus, CorsairLedId.KeypadMinus }, - { LedId.Keyboard_NumPlus, CorsairLedId.KeypadPlus }, - { LedId.Keyboard_NumEnter, CorsairLedId.KeypadEnter }, - { LedId.Keyboard_Num7, CorsairLedId.Keypad7 }, - { LedId.Keyboard_Num8, CorsairLedId.Keypad8 }, - { LedId.Keyboard_Num9, CorsairLedId.Keypad9 }, - { LedId.Keyboard_NumComma, CorsairLedId.KeypadComma }, - { LedId.Keyboard_Num4, CorsairLedId.Keypad4 }, - { LedId.Keyboard_Num5, CorsairLedId.Keypad5 }, - { LedId.Keyboard_Num6, CorsairLedId.Keypad6 }, - { LedId.Keyboard_Num1, CorsairLedId.Keypad1 }, - { LedId.Keyboard_Num2, CorsairLedId.Keypad2 }, - { LedId.Keyboard_Num3, CorsairLedId.Keypad3 }, - { LedId.Keyboard_Num0, CorsairLedId.Keypad0 }, - { LedId.Keyboard_NumPeriodAndDelete, CorsairLedId.KeypadPeriodAndDelete }, - { LedId.Keyboard_Programmable1, CorsairLedId.G1 }, - { LedId.Keyboard_Programmable2, CorsairLedId.G2 }, - { LedId.Keyboard_Programmable3, CorsairLedId.G3 }, - { LedId.Keyboard_Programmable4, CorsairLedId.G4 }, - { LedId.Keyboard_Programmable5, CorsairLedId.G5 }, - { LedId.Keyboard_Programmable6, CorsairLedId.G6 }, - { LedId.Keyboard_Programmable7, CorsairLedId.G7 }, - { LedId.Keyboard_Programmable8, CorsairLedId.G8 }, - { LedId.Keyboard_Programmable9, CorsairLedId.G9 }, - { LedId.Keyboard_Programmable10, CorsairLedId.G10 }, - { LedId.Keyboard_MediaVolumeUp, CorsairLedId.VolumeUp }, - { LedId.Keyboard_MediaVolumeDown, CorsairLedId.VolumeDown }, - { LedId.Keyboard_MacroRecording, CorsairLedId.MR }, - { LedId.Keyboard_Macro1, CorsairLedId.M1 }, - { LedId.Keyboard_Macro2, CorsairLedId.M2 }, - { LedId.Keyboard_Macro3, CorsairLedId.M3 }, - { LedId.Keyboard_Programmable11, CorsairLedId.G11 }, - { LedId.Keyboard_Programmable12, CorsairLedId.G12 }, - { LedId.Keyboard_Programmable13, CorsairLedId.G13 }, - { LedId.Keyboard_Programmable14, CorsairLedId.G14 }, - { LedId.Keyboard_Programmable15, CorsairLedId.G15 }, - { LedId.Keyboard_Programmable16, CorsairLedId.G16 }, - { LedId.Keyboard_Programmable17, CorsairLedId.G17 }, - { LedId.Keyboard_Programmable18, CorsairLedId.G18 }, - { LedId.Keyboard_International5, CorsairLedId.International5 }, - { LedId.Keyboard_International4, CorsairLedId.International4 }, - { LedId.Keyboard_Custom1, CorsairLedId.Lightbar1 }, - { LedId.Keyboard_Custom2, CorsairLedId.Lightbar2 }, - { LedId.Keyboard_Custom3, CorsairLedId.Lightbar3 }, - { LedId.Keyboard_Custom4, CorsairLedId.Lightbar4 }, - { LedId.Keyboard_Custom5, CorsairLedId.Lightbar5 }, - { LedId.Keyboard_Custom6, CorsairLedId.Lightbar6 }, - { LedId.Keyboard_Custom7, CorsairLedId.Lightbar7 }, - { LedId.Keyboard_Custom8, CorsairLedId.Lightbar8 }, - { LedId.Keyboard_Custom9, CorsairLedId.Lightbar9 }, - { LedId.Keyboard_Custom10, CorsairLedId.Lightbar10 }, - { LedId.Keyboard_Custom11, CorsairLedId.Lightbar11 }, - { LedId.Keyboard_Custom12, CorsairLedId.Lightbar12 }, - { LedId.Keyboard_Custom13, CorsairLedId.Lightbar13 }, - { LedId.Keyboard_Custom14, CorsairLedId.Lightbar14 }, - { LedId.Keyboard_Custom15, CorsairLedId.Lightbar15 }, - { LedId.Keyboard_Custom16, CorsairLedId.Lightbar16 }, - { LedId.Keyboard_Custom17, CorsairLedId.Lightbar17 }, - { LedId.Keyboard_Custom18, CorsairLedId.Lightbar18 }, - { LedId.Keyboard_Custom19, CorsairLedId.Lightbar19 }, - { LedId.Keyboard_Custom20, CorsairLedId.LedProgramming }, - { LedId.Keyboard_Custom21, CorsairLedId.Fn } - }; - } -} diff --git a/RGB.NET.Devices.Corsair/Mainboard/CorsairMainboardRGBDevice.cs b/RGB.NET.Devices.Corsair/Mainboard/CorsairMainboardRGBDevice.cs new file mode 100644 index 00000000..fc23e184 --- /dev/null +++ b/RGB.NET.Devices.Corsair/Mainboard/CorsairMainboardRGBDevice.cs @@ -0,0 +1,27 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using RGB.NET.Core; + +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair memory. +/// +public class CorsairMainboardRGBDevice : CorsairRGBDevice, IMainboard +{ + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The specific information provided by CUE for the memory. + /// The queue used to update this device. + internal CorsairMainboardRGBDevice(CorsairMainboardRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, LedMappings.Mainboard, updateQueue) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Mainboard/CorsairMainboardRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Mainboard/CorsairMainboardRGBDeviceInfo.cs new file mode 100644 index 00000000..94d836cc --- /dev/null +++ b/RGB.NET.Devices.Corsair/Mainboard/CorsairMainboardRGBDeviceInfo.cs @@ -0,0 +1,28 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using RGB.NET.Core; +using RGB.NET.Devices.Corsair.Native; + +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a . +/// +public class CorsairMainboardRGBDeviceInfo : CorsairRGBDeviceInfo +{ + #region Constructors + + /// + /// + /// Internal constructor of managed . + /// + /// The index of the . + /// The native -struct + internal CorsairMainboardRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo) + : base(deviceIndex, RGBDeviceType.Mainboard, nativeInfo) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs index 836e055f..f44d7eea 100644 --- a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDevice.cs @@ -1,59 +1,27 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices; using RGB.NET.Core; -using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair memory. +/// +public class CorsairMemoryRGBDevice : CorsairRGBDevice, IDRAM { - /// + #region Constructors + + /// /// - /// Represents a corsair memory. + /// Initializes a new instance of the class. /// - public class CorsairMemoryRGBDevice : CorsairRGBDevice, IDRAM - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the memory. - internal CorsairMemoryRGBDevice(CorsairMemoryRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); - - int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); - IntPtr ptr = nativeLedPositions.pLedPosition; - - Dictionary mapping = MemoryIdMapping.DEFAULT.SwapKeyValue(); - for (int i = 0; i < nativeLedPositions.numberOfLed; i++) - { - _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); - InitializeLed(mapping.TryGetValue(ledPosition.LedId, out LedId ledId) ? ledId : LedId.Invalid, ledPosition.ToRectangle()); - - ptr = new IntPtr(ptr.ToInt64() + structSize); - } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Memory", $"{model}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => MemoryIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; - - #endregion - } -} + /// The specific information provided by CUE for the memory. + /// The queue used to update this device. + internal CorsairMemoryRGBDevice(CorsairMemoryRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, LedMappings.Memory, updateQueue) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDeviceInfo.cs index 544757af..afd88433 100644 --- a/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Memory/CorsairMemoryRGBDeviceInfo.cs @@ -1,31 +1,28 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System.Collections.Generic; using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a . +/// +public class CorsairMemoryRGBDeviceInfo : CorsairRGBDeviceInfo { + #region Constructors + /// /// - /// Represents a generic information for a . + /// Internal constructor of managed . /// - public class CorsairMemoryRGBDeviceInfo : CorsairRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The index of the . - /// The native -struct - /// A dictionary containing counters to create unique names for equal devices models. - internal CorsairMemoryRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo, Dictionary modelCounter) - : base(deviceIndex, RGBDeviceType.DRAM, nativeInfo, modelCounter) - { } + /// The index of the . + /// The native -struct + internal CorsairMemoryRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo) + : base(deviceIndex, RGBDeviceType.DRAM, nativeInfo) + { } - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Memory/MemoryIdMapping.cs b/RGB.NET.Devices.Corsair/Memory/MemoryIdMapping.cs deleted file mode 100644 index b7d7db4c..00000000 --- a/RGB.NET.Devices.Corsair/Memory/MemoryIdMapping.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Collections.Generic; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - internal static class MemoryIdMapping - { - internal static readonly Dictionary DEFAULT = new Dictionary - { - { LedId.Invalid, CorsairLedId.Invalid }, - { LedId.DRAM1, CorsairLedId.DRAM1 }, - { LedId.DRAM2, CorsairLedId.DRAM2 }, - { LedId.DRAM3, CorsairLedId.DRAM3 }, - { LedId.DRAM4, CorsairLedId.DRAM4 }, - { LedId.DRAM5, CorsairLedId.DRAM5 }, - { LedId.DRAM6, CorsairLedId.DRAM6 }, - { LedId.DRAM7, CorsairLedId.DRAM7 }, - { LedId.DRAM8, CorsairLedId.DRAM8 }, - { LedId.DRAM9, CorsairLedId.DRAM9 }, - { LedId.DRAM10, CorsairLedId.DRAM10 }, - { LedId.DRAM11, CorsairLedId.DRAM11 }, - { LedId.DRAM12, CorsairLedId.DRAM12 }, - }; - } -} diff --git a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs index 292d7d8d..5c81249d 100644 --- a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDevice.cs @@ -1,73 +1,27 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System; using RGB.NET.Core; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair mouse. +/// +public class CorsairMouseRGBDevice : CorsairRGBDevice, IMouse { - /// + #region Constructors + + /// /// - /// Represents a corsair mouse. + /// Initializes a new instance of the class. /// - public class CorsairMouseRGBDevice : CorsairRGBDevice, IMouse - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the mouse - internal CorsairMouseRGBDevice(CorsairMouseRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - switch (DeviceInfo.PhysicalLayout) - { - case CorsairPhysicalMouseLayout.Zones1: - InitializeLed(LedId.Mouse1, new Rectangle(0, 0, 10, 10)); - break; - case CorsairPhysicalMouseLayout.Zones2: - InitializeLed(LedId.Mouse1, new Rectangle(0, 0, 10, 10)); - InitializeLed(LedId.Mouse2, new Rectangle(10, 0, 10, 10)); - break; - case CorsairPhysicalMouseLayout.Zones3: - InitializeLed(LedId.Mouse1, new Rectangle(0, 0, 10, 10)); - InitializeLed(LedId.Mouse2, new Rectangle(10, 0, 10, 10)); - InitializeLed(LedId.Mouse3, new Rectangle(20, 0, 10, 10)); - break; - case CorsairPhysicalMouseLayout.Zones4: - InitializeLed(LedId.Mouse1, new Rectangle(0, 0, 10, 10)); - InitializeLed(LedId.Mouse2, new Rectangle(10, 0, 10, 10)); - InitializeLed(LedId.Mouse3, new Rectangle(20, 0, 10, 10)); - InitializeLed(LedId.Mouse4, new Rectangle(30, 0, 10, 10)); - break; - default: - throw new RGBDeviceException($"Can't initialize mouse with layout '{DeviceInfo.PhysicalLayout}'"); - } - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Mice", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) - { - if (string.Equals(DeviceInfo.Model, "GLAIVE RGB", StringComparison.OrdinalIgnoreCase)) - return MouseIdMapping.GLAIVE.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; - else if (string.Equals(DeviceInfo.Model, "M65 RGB ELITE", StringComparison.OrdinalIgnoreCase)) - return MouseIdMapping.M65_RGB_ELITE.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; - else - return MouseIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; - } - - #endregion - } -} + /// The specific information provided by CUE for the mouse + /// The queue used to update this device. + internal CorsairMouseRGBDevice(CorsairMouseRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, LedMappings.Mouse, updateQueue) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDeviceInfo.cs index be37040f..a5014669 100644 --- a/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Mouse/CorsairMouseRGBDeviceInfo.cs @@ -1,39 +1,36 @@ -using System.Collections.Generic; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a . +/// +public class CorsairMouseRGBDeviceInfo : CorsairRGBDeviceInfo { - /// + #region Properties & Fields + /// - /// Represents a generic information for a . + /// Gets the physical layout of the mouse. /// - public class CorsairMouseRGBDeviceInfo : CorsairRGBDeviceInfo - { - #region Properties & Fields - - /// - /// Gets the physical layout of the mouse. - /// - public CorsairPhysicalMouseLayout PhysicalLayout { get; } - - #endregion + public CorsairPhysicalMouseLayout PhysicalLayout { get; } - #region Constructors + #endregion - /// - /// - /// Internal constructor of managed . - /// - /// The index of the . - /// The native -struct - /// A dictionary containing counters to create unique names for equal devices models. - internal CorsairMouseRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo, Dictionary modelCounter) - : base(deviceIndex, RGBDeviceType.Mouse, nativeInfo, modelCounter) - { - this.PhysicalLayout = (CorsairPhysicalMouseLayout)nativeInfo.physicalLayout; - } + #region Constructors - #endregion + /// + /// + /// Internal constructor of managed . + /// + /// The index of the . + /// The native -struct + internal CorsairMouseRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo) + : base(deviceIndex, RGBDeviceType.Mouse, nativeInfo) + { + this.PhysicalLayout = (CorsairPhysicalMouseLayout)nativeInfo.physicalLayout; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs b/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs deleted file mode 100644 index 00dea5b5..00000000 --- a/RGB.NET.Devices.Corsair/Mouse/MouseIdMapping.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System.Collections.Generic; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - internal static class MouseIdMapping - { - internal static readonly Dictionary DEFAULT = new Dictionary - { - { LedId.Mouse1, CorsairLedId.B1 }, - { LedId.Mouse2, CorsairLedId.B2 }, - { LedId.Mouse3, CorsairLedId.B3 }, - { LedId.Mouse4, CorsairLedId.B4 }, - { LedId.Mouse5, CorsairLedId.B5 }, - { LedId.Mouse6, CorsairLedId.B6 }, - }; - - internal static readonly Dictionary GLAIVE = new Dictionary - { - { LedId.Mouse1, CorsairLedId.B1 }, - { LedId.Mouse2, CorsairLedId.B2 }, - { LedId.Mouse3, CorsairLedId.B5 }, - }; - - internal static readonly Dictionary M65_RGB_ELITE = new Dictionary - { - { LedId.Mouse1, CorsairLedId.B1 }, - { LedId.Mouse2, CorsairLedId.B3 }, - }; - } -} diff --git a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs index b245ca16..65c0f009 100644 --- a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs +++ b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDevice.cs @@ -1,62 +1,27 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.InteropServices; using RGB.NET.Core; -using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair mousepad. +/// +public class CorsairMousepadRGBDevice : CorsairRGBDevice, IMousepad { - /// + #region Constructors + + /// /// - /// Represents a corsair mousepad. + /// Initializes a new instance of the class. /// - public class CorsairMousepadRGBDevice : CorsairRGBDevice, IMousepad - { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the mousepad - internal CorsairMousepadRGBDevice(CorsairMousepadRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - _CorsairLedPositions nativeLedPositions = (_CorsairLedPositions)Marshal.PtrToStructure(_CUESDK.CorsairGetLedPositionsByDeviceIndex(DeviceInfo.CorsairDeviceIndex), typeof(_CorsairLedPositions)); - - int structSize = Marshal.SizeOf(typeof(_CorsairLedPosition)); - IntPtr ptr = nativeLedPositions.pLedPosition; - - List<_CorsairLedPosition> positions = new List<_CorsairLedPosition>(); - for (int i = 0; i < nativeLedPositions.numberOfLed; i++) - { - _CorsairLedPosition ledPosition = (_CorsairLedPosition)Marshal.PtrToStructure(ptr, typeof(_CorsairLedPosition)); - ptr = new IntPtr(ptr.ToInt64() + structSize); - positions.Add(ledPosition); - } - - Dictionary mapping = MousepadIdMapping.DEFAULT.SwapKeyValue(); - foreach (_CorsairLedPosition ledPosition in positions.OrderBy(p => p.LedId)) - InitializeLed(mapping.TryGetValue(ledPosition.LedId, out LedId ledId) ? ledId : LedId.Invalid, ledPosition.ToRectangle()); - - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Corsair\Mousepads", $"{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } - - /// - protected override object CreateLedCustomData(LedId ledId) => MousepadIdMapping.DEFAULT.TryGetValue(ledId, out CorsairLedId id) ? id : CorsairLedId.Invalid; - - #endregion - } -} + /// The specific information provided by CUE for the mousepad + /// The queue used to update this device. + internal CorsairMousepadRGBDevice(CorsairMousepadRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, LedMappings.Mousepad, updateQueue) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDeviceInfo.cs index 86ef31f9..8c5d62c3 100644 --- a/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Mousepad/CorsairMousepadRGBDeviceInfo.cs @@ -1,28 +1,25 @@ -using System.Collections.Generic; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.Corsair.Native; -namespace RGB.NET.Devices.Corsair +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a . +/// +public class CorsairMousepadRGBDeviceInfo : CorsairRGBDeviceInfo { + #region Constructors + /// /// - /// Represents a generic information for a . + /// Internal constructor of managed . /// - public class CorsairMousepadRGBDeviceInfo : CorsairRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The index if the . - /// The native -struct - /// A dictionary containing counters to create unique names for equal devices models. - internal CorsairMousepadRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo, Dictionary modelCounter) - : base(deviceIndex, RGBDeviceType.Mousepad, nativeInfo, modelCounter) - { } + /// The index if the . + /// The native -struct + internal CorsairMousepadRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo) + : base(deviceIndex, RGBDeviceType.Mousepad, nativeInfo) + { } - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Mousepad/MousepadIdMapping.cs b/RGB.NET.Devices.Corsair/Mousepad/MousepadIdMapping.cs deleted file mode 100644 index 3b49ad63..00000000 --- a/RGB.NET.Devices.Corsair/Mousepad/MousepadIdMapping.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - internal static class MousepadIdMapping - { - internal static readonly Dictionary DEFAULT = new Dictionary - { - { LedId.Mousepad1, CorsairLedId.Zone1 }, - { LedId.Mousepad2, CorsairLedId.Zone2 }, - { LedId.Mousepad3, CorsairLedId.Zone3 }, - { LedId.Mousepad4, CorsairLedId.Zone4 }, - { LedId.Mousepad5, CorsairLedId.Zone5 }, - { LedId.Mousepad6, CorsairLedId.Zone6 }, - { LedId.Mousepad7, CorsairLedId.Zone7 }, - { LedId.Mousepad8, CorsairLedId.Zone8 }, - { LedId.Mousepad9, CorsairLedId.Zone9 }, - { LedId.Mousepad10, CorsairLedId.Zone10 }, - { LedId.Mousepad11, CorsairLedId.Zone11 }, - { LedId.Mousepad12, CorsairLedId.Zone12 }, - { LedId.Mousepad13, CorsairLedId.Zone13 }, - { LedId.Mousepad14, CorsairLedId.Zone14 }, - { LedId.Mousepad15, CorsairLedId.Zone15 } - }; - } -} diff --git a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs index 9b217e46..9455cb32 100644 --- a/RGB.NET.Devices.Corsair/Native/_CUESDK.cs +++ b/RGB.NET.Devices.Corsair/Native/_CUESDK.cs @@ -1,4 +1,5 @@ -// ReSharper disable UnusedMethodReturnValue.Global +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable UnusedMethodReturnValue.Global // ReSharper disable UnusedMember.Global using System; @@ -8,207 +9,185 @@ using System.Runtime.InteropServices; using RGB.NET.Core; -namespace RGB.NET.Devices.Corsair.Native -{ - // ReSharper disable once InconsistentNaming - internal static class _CUESDK - { - #region Libary Management - - private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - - /// - /// Reloads the SDK. - /// - internal static void Reload() - { - UnloadCUESDK(); - LoadCUESDK(); - } - - private static void LoadCUESDK() - { - if (_dllHandle != IntPtr.Zero) return; +namespace RGB.NET.Devices.Corsair.Native; - // HACK: Load library at runtime to support both, x86 and x64 with one managed dll - List possiblePathList = Environment.Is64BitProcess ? CorsairDeviceProvider.PossibleX64NativePaths : CorsairDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); - if (dllPath == null) throw new RGBDeviceException($"Can't find the CUE-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - - _dllHandle = LoadLibrary(dllPath); - - _corsairSetLedsColorsBufferByDeviceIndexPointer = (CorsairSetLedsColorsBufferByDeviceIndexPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairSetLedsColorsBufferByDeviceIndex"), typeof(CorsairSetLedsColorsBufferByDeviceIndexPointer)); - _corsairSetLedsColorsFlushBufferPointer = (CorsairSetLedsColorsFlushBufferPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairSetLedsColorsFlushBuffer"), typeof(CorsairSetLedsColorsFlushBufferPointer)); - _corsairGetLedsColorsByDeviceIndexPointer = (CorsairGetLedsColorsByDeviceIndexPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedsColorsByDeviceIndex"), typeof(CorsairGetLedsColorsByDeviceIndexPointer)); - _corsairSetLayerPriorityPointer = (CorsairSetLayerPriorityPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairSetLayerPriority"), typeof(CorsairSetLayerPriorityPointer)); - _corsairGetDeviceCountPointer = (CorsairGetDeviceCountPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceCount"), typeof(CorsairGetDeviceCountPointer)); - _corsairGetDeviceInfoPointer = (CorsairGetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetDeviceInfo"), typeof(CorsairGetDeviceInfoPointer)); - _corsairGetLedPositionsByDeviceIndexPointer = (CorsairGetLedPositionsByDeviceIndexPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedPositionsByDeviceIndex"), typeof(CorsairGetLedPositionsByDeviceIndexPointer)); - _corsairGetLedIdForKeyNamePointer = (CorsairGetLedIdForKeyNamePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLedIdForKeyName"), typeof(CorsairGetLedIdForKeyNamePointer)); - _corsairRequestControlPointer = (CorsairRequestControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairRequestControl"), typeof(CorsairRequestControlPointer)); - _corsairReleaseControlPointer = (CorsairReleaseControlPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairReleaseControl"), typeof(CorsairReleaseControlPointer)); - _corsairPerformProtocolHandshakePointer = (CorsairPerformProtocolHandshakePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairPerformProtocolHandshake"), typeof(CorsairPerformProtocolHandshakePointer)); - _corsairGetLastErrorPointer = (CorsairGetLastErrorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CorsairGetLastError"), typeof(CorsairGetLastErrorPointer)); - } - - internal static void UnloadCUESDK() - { - if (_dllHandle == IntPtr.Zero) return; +// ReSharper disable once InconsistentNaming +internal static class _CUESDK +{ + #region Libary Management - // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 20.02.2016: We might need to reduce the internal reference counter more than once to set the library free - while (FreeLibrary(_dllHandle)) ; - _dllHandle = IntPtr.Zero; - } - - [DllImport("kernel32.dll")] - private static extern IntPtr LoadLibrary(string dllToLoad); - - [DllImport("kernel32.dll")] - private static extern bool FreeLibrary(IntPtr dllHandle); - - [DllImport("kernel32.dll")] - private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); - - #endregion - - #region SDK-METHODS - - #region Pointers - - private static CorsairSetLedsColorsBufferByDeviceIndexPointer _corsairSetLedsColorsBufferByDeviceIndexPointer; - private static CorsairSetLedsColorsFlushBufferPointer _corsairSetLedsColorsFlushBufferPointer; - private static CorsairGetLedsColorsByDeviceIndexPointer _corsairGetLedsColorsByDeviceIndexPointer; - private static CorsairSetLayerPriorityPointer _corsairSetLayerPriorityPointer; - private static CorsairGetDeviceCountPointer _corsairGetDeviceCountPointer; - private static CorsairGetDeviceInfoPointer _corsairGetDeviceInfoPointer; - private static CorsairGetLedIdForKeyNamePointer _corsairGetLedIdForKeyNamePointer; - private static CorsairGetLedPositionsByDeviceIndexPointer _corsairGetLedPositionsByDeviceIndexPointer; - private static CorsairRequestControlPointer _corsairRequestControlPointer; - private static CorsairReleaseControlPointer _corsairReleaseControlPointer; - private static CorsairPerformProtocolHandshakePointer _corsairPerformProtocolHandshakePointer; - private static CorsairGetLastErrorPointer _corsairGetLastErrorPointer; - - #endregion - - #region Delegates - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool CorsairSetLedsColorsBufferByDeviceIndexPointer(int deviceIndex, int size, IntPtr ledsColors); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool CorsairSetLedsColorsFlushBufferPointer(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool CorsairGetLedsColorsByDeviceIndexPointer(int deviceIndex, int size, IntPtr ledsColors); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool CorsairSetLayerPriorityPointer(int priority); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int CorsairGetDeviceCountPointer(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate IntPtr CorsairGetDeviceInfoPointer(int deviceIndex); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate IntPtr CorsairGetLedPositionsByDeviceIndexPointer(int deviceIndex); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate CorsairLedId CorsairGetLedIdForKeyNamePointer(char keyName); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool CorsairRequestControlPointer(CorsairAccessMode accessMode); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool CorsairReleaseControlPointer(CorsairAccessMode accessMode); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate _CorsairProtocolDetails CorsairPerformProtocolHandshakePointer(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate CorsairError CorsairGetLastErrorPointer(); - - #endregion - - // ReSharper disable EventExceptionNotDocumented - - /// - /// CUE-SDK: set specified LEDs to some colors. - /// This function set LEDs colors in the buffer which is written to the devices via CorsairSetLedsColorsFlushBuffer or CorsairSetLedsColorsFlushBufferAsync. - /// Typical usecase is next: CorsairSetLedsColorsFlushBuffer or CorsairSetLedsColorsFlushBufferAsync is called to write LEDs colors to the device - /// and follows after one or more calls of CorsairSetLedsColorsBufferByDeviceIndex to set the LEDs buffer. - /// This function does not take logical layout into account. - /// - internal static bool CorsairSetLedsColorsBufferByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors) => _corsairSetLedsColorsBufferByDeviceIndexPointer(deviceIndex, size, ledsColors); - - /// - /// CUE-SDK: writes to the devices LEDs colors buffer which is previously filled by the CorsairSetLedsColorsBufferByDeviceIndex function. - /// This function executes synchronously, if you are concerned about delays consider using CorsairSetLedsColorsFlushBufferAsync - /// - internal static bool CorsairSetLedsColorsFlushBuffer() => _corsairSetLedsColorsFlushBufferPointer(); + private static IntPtr _handle = IntPtr.Zero; - /// - /// CUE-SDK: get current color for the list of requested LEDs. - /// The color should represent the actual state of the hardware LED, which could be a combination of SDK and/or CUE input. - /// This function works for keyboard, mouse, mousemat, headset, headset stand and DIY-devices. - /// - internal static bool CorsairGetLedsColorsByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors) => _corsairGetLedsColorsByDeviceIndexPointer(deviceIndex, size, ledsColors); + /// + /// Reloads the SDK. + /// + internal static void Reload() + { + UnloadCUESDK(); + LoadCUESDK(); + } - /// - /// CUE-SDK: set layer priority for this shared client. - /// By default CUE has priority of 127 and all shared clients have priority of 128 if they don’t call this function. - /// Layers with higher priority value are shown on top of layers with lower priority. - /// - internal static bool CorsairSetLayerPriority(int priority) => _corsairSetLayerPriorityPointer(priority); + private static void LoadCUESDK() + { + if (_handle != IntPtr.Zero) return; + + List possiblePathList = GetPossibleLibraryPaths().ToList(); + + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); + if (dllPath == null) throw new RGBDeviceException($"Can't find the CUE-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); + + if (!NativeLibrary.TryLoad(dllPath, out _handle)) +#if NET6_0 + throw new RGBDeviceException($"Corsair LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}"); +#else + throw new RGBDeviceException($"Corsair LoadLibrary failed with error code {Marshal.GetLastWin32Error()}"); +#endif + + if (!NativeLibrary.TryGetExport(_handle, "CorsairSetLedsColorsBufferByDeviceIndex", out _corsairSetLedsColorsBufferByDeviceIndexPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairSetLedsColorsBufferByDeviceIndex'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairSetLedsColorsFlushBuffer", out _corsairSetLedsColorsFlushBufferPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairSetLedsColorsFlushBuffer'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairGetLedsColorsByDeviceIndex", out _corsairGetLedsColorsByDeviceIndexPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetLedsColorsByDeviceIndex'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairSetLayerPriority", out _corsairSetLayerPriorityPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairSetLayerPriority'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairGetDeviceCount", out _corsairGetDeviceCountPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetDeviceCount'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairGetDeviceInfo", out _corsairGetDeviceInfoPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetDeviceInfo'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairGetLedIdForKeyName", out _corsairGetLedIdForKeyNamePointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetLedIdForKeyName'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairGetLedPositionsByDeviceIndex", out _corsairGetLedPositionsByDeviceIndexPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetLedPositionsByDeviceIndex'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairRequestControl", out _corsairRequestControlPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairRequestControl'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairReleaseControl", out _corsairReleaseControlPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairReleaseControl'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairPerformProtocolHandshake", out _corsairPerformProtocolHandshakePointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairPerformProtocolHandshake'"); + if (!NativeLibrary.TryGetExport(_handle, "CorsairGetLastError", out _corsairGetLastErrorPointer)) throw new RGBDeviceException("Failed to load Corsair function 'CorsairGetLastError'"); + } - /// - /// CUE-SDK: returns number of connected Corsair devices that support lighting control. - /// - internal static int CorsairGetDeviceCount() => _corsairGetDeviceCountPointer(); + private static IEnumerable GetPossibleLibraryPaths() + { + IEnumerable possibleLibraryPaths; - /// - /// CUE-SDK: returns information about device at provided index. - /// - internal static IntPtr CorsairGetDeviceInfo(int deviceIndex) => _corsairGetDeviceInfoPointer(deviceIndex); + if (OperatingSystem.IsWindows()) + possibleLibraryPaths = Environment.Is64BitProcess ? CorsairDeviceProvider.PossibleX64NativePaths : CorsairDeviceProvider.PossibleX86NativePaths; + else + possibleLibraryPaths = Enumerable.Empty(); - /// - /// CUE-SDK: provides list of keyboard or mousepad LEDs with their physical positions. - /// - internal static IntPtr CorsairGetLedPositionsByDeviceIndex(int deviceIndex) => _corsairGetLedPositionsByDeviceIndexPointer(deviceIndex); - - /// - /// CUE-SDK: retrieves led id for key name taking logical layout into account. - /// - internal static CorsairLedId CorsairGetLedIdForKeyName(char keyName) => _corsairGetLedIdForKeyNamePointer(keyName); - - /// - /// CUE-SDK: requestes control using specified access mode. - /// By default client has shared control over lighting so there is no need to call CorsairRequestControl unless client requires exclusive control. - /// - internal static bool CorsairRequestControl(CorsairAccessMode accessMode) => _corsairRequestControlPointer(accessMode); + return possibleLibraryPaths.Select(Environment.ExpandEnvironmentVariables); + } - /// - /// CUE-SDK: releases previously requested control for specified access mode. - /// - internal static bool CorsairReleaseControl(CorsairAccessMode accessMode) => _corsairReleaseControlPointer(accessMode); + internal static void UnloadCUESDK() + { + if (_handle == IntPtr.Zero) return; + + _corsairSetLedsColorsBufferByDeviceIndexPointer = IntPtr.Zero; + _corsairSetLedsColorsFlushBufferPointer = IntPtr.Zero; + _corsairGetLedsColorsByDeviceIndexPointer = IntPtr.Zero; + _corsairSetLayerPriorityPointer = IntPtr.Zero; + _corsairGetDeviceCountPointer = IntPtr.Zero; + _corsairGetDeviceInfoPointer = IntPtr.Zero; + _corsairGetLedIdForKeyNamePointer = IntPtr.Zero; + _corsairGetLedPositionsByDeviceIndexPointer = IntPtr.Zero; + _corsairRequestControlPointer = IntPtr.Zero; + _corsairReleaseControlPointer = IntPtr.Zero; + _corsairPerformProtocolHandshakePointer = IntPtr.Zero; + _corsairGetLastErrorPointer = IntPtr.Zero; + + NativeLibrary.Free(_handle); + _handle = IntPtr.Zero; + } - /// - /// CUE-SDK: checks file and protocol version of CUE to understand which of SDK functions can be used with this version of CUE. - /// - internal static _CorsairProtocolDetails CorsairPerformProtocolHandshake() => _corsairPerformProtocolHandshakePointer(); - - /// - /// CUE-SDK: returns last error that occured while using any of Corsair* functions. - /// - internal static CorsairError CorsairGetLastError() => _corsairGetLastErrorPointer(); - - // ReSharper restore EventExceptionNotDocumented - - #endregion + #endregion + + #region SDK-METHODS + + #region Pointers + + private static IntPtr _corsairSetLedsColorsBufferByDeviceIndexPointer; + private static IntPtr _corsairSetLedsColorsFlushBufferPointer; + private static IntPtr _corsairGetLedsColorsByDeviceIndexPointer; + private static IntPtr _corsairSetLayerPriorityPointer; + private static IntPtr _corsairGetDeviceCountPointer; + private static IntPtr _corsairGetDeviceInfoPointer; + private static IntPtr _corsairGetLedIdForKeyNamePointer; + private static IntPtr _corsairGetLedPositionsByDeviceIndexPointer; + private static IntPtr _corsairRequestControlPointer; + private static IntPtr _corsairReleaseControlPointer; + private static IntPtr _corsairPerformProtocolHandshakePointer; + private static IntPtr _corsairGetLastErrorPointer; + + #endregion + + /// + /// CUE-SDK: set specified LEDs to some colors. + /// This function set LEDs colors in the buffer which is written to the devices via CorsairSetLedsColorsFlushBuffer or CorsairSetLedsColorsFlushBufferAsync. + /// Typical usecase is next: CorsairSetLedsColorsFlushBuffer or CorsairSetLedsColorsFlushBufferAsync is called to write LEDs colors to the device + /// and follows after one or more calls of CorsairSetLedsColorsBufferByDeviceIndex to set the LEDs buffer. + /// This function does not take logical layout into account. + /// + internal static unsafe bool CorsairSetLedsColorsBufferByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairSetLedsColorsBufferByDeviceIndexPointer))(deviceIndex, size, ledsColors); + + /// + /// CUE-SDK: writes to the devices LEDs colors buffer which is previously filled by the CorsairSetLedsColorsBufferByDeviceIndex function. + /// This function executes synchronously, if you are concerned about delays consider using CorsairSetLedsColorsFlushBufferAsync + /// + internal static unsafe bool CorsairSetLedsColorsFlushBuffer() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairSetLedsColorsFlushBufferPointer))(); + + /// + /// CUE-SDK: get current color for the list of requested LEDs. + /// The color should represent the actual state of the hardware LED, which could be a combination of SDK and/or CUE input. + /// This function works for keyboard, mouse, mousemat, headset, headset stand and DIY-devices. + /// + internal static unsafe bool CorsairGetLedsColorsByDeviceIndex(int deviceIndex, int size, IntPtr ledsColors) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairGetLedsColorsByDeviceIndexPointer))(deviceIndex, size, ledsColors); + + /// + /// CUE-SDK: set layer priority for this shared client. + /// By default CUE has priority of 127 and all shared clients have priority of 128 if they don’t call this function. + /// Layers with higher priority value are shown on top of layers with lower priority. + /// + internal static unsafe bool CorsairSetLayerPriority(int priority) => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairSetLayerPriorityPointer))(priority); + + /// + /// CUE-SDK: returns number of connected Corsair devices that support lighting control. + /// + internal static unsafe int CorsairGetDeviceCount() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairGetDeviceCountPointer))(); + + /// + /// CUE-SDK: returns information about device at provided index. + /// + internal static unsafe IntPtr CorsairGetDeviceInfo(int deviceIndex) => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairGetDeviceInfoPointer))(deviceIndex); + + /// + /// CUE-SDK: provides list of keyboard or mousepad LEDs with their physical positions. + /// + internal static unsafe IntPtr CorsairGetLedPositionsByDeviceIndex(int deviceIndex) => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairGetLedPositionsByDeviceIndexPointer))(deviceIndex); + + /// + /// CUE-SDK: retrieves led id for key name taking logical layout into account. + /// + internal static unsafe CorsairLedId CorsairGetLedIdForKeyName(char keyName) => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairGetLedIdForKeyNamePointer))(keyName); + + /// + /// CUE-SDK: requestes control using specified access mode. + /// By default client has shared control over lighting so there is no need to call CorsairRequestControl unless client requires exclusive control. + /// + internal static unsafe bool CorsairRequestControl(CorsairAccessMode accessMode) => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairRequestControlPointer))(accessMode); + + /// + /// CUE-SDK: releases previously requested control for specified access mode. + /// + internal static unsafe bool CorsairReleaseControl(CorsairAccessMode accessMode) => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairReleaseControlPointer))(accessMode); + + /// + /// CUE-SDK: checks file and protocol version of CUE to understand which of SDK functions can be used with this version of CUE. + /// + internal static unsafe _CorsairProtocolDetails CorsairPerformProtocolHandshake() => ((delegate* unmanaged[Cdecl]<_CorsairProtocolDetails>)ThrowIfZero(_corsairPerformProtocolHandshakePointer))(); + + /// + /// CUE-SDK: returns last error that occured while using any of Corsair* functions. + /// + internal static unsafe CorsairError CorsairGetLastError() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_corsairGetLastErrorPointer))(); + + private static IntPtr ThrowIfZero(IntPtr ptr) + { + if (ptr == IntPtr.Zero) throw new RGBDeviceException("The Corsair-SDK is not initialized."); + return ptr; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairChannelDeviceInfo.cs b/RGB.NET.Devices.Corsair/Native/_CorsairChannelDeviceInfo.cs index d3ce82f8..3f44c7ae 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairChannelDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairChannelDeviceInfo.cs @@ -1,26 +1,27 @@ #pragma warning disable 169 // Field 'x' is never used #pragma warning disable 414 // Field 'x' is assigned but its value never used #pragma warning disable 649 // Field 'x' is never assigned +#pragma warning disable IDE1006 // Naming Styles using System.Runtime.InteropServices; -namespace RGB.NET.Devices.Corsair.Native +namespace RGB.NET.Devices.Corsair.Native; + +// ReSharper disable once InconsistentNaming +/// +/// CUE-SDK: contains information about separate LED-device connected to the channel controlled by the DIY-device. +/// +[StructLayout(LayoutKind.Sequential)] + +internal class _CorsairChannelDeviceInfo { - // ReSharper disable once InconsistentNaming /// - /// CUE-SDK: contains information about separate LED-device connected to the channel controlled by the DIY-device. + /// CUE-SDK: type of the LED-device /// - [StructLayout(LayoutKind.Sequential)] - internal class _CorsairChannelDeviceInfo - { - /// - /// CUE-SDK: type of the LED-device - /// - internal CorsairChannelDeviceType type; + internal CorsairChannelDeviceType type; - /// - /// CUE-SDK: number of LEDs controlled by LED-device. - /// - internal int deviceLedCount; - } -} + /// + /// CUE-SDK: number of LEDs controlled by LED-device. + /// + internal int deviceLedCount; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairChannelInfo.cs b/RGB.NET.Devices.Corsair/Native/_CorsairChannelInfo.cs index 5933b4e0..3190b878 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairChannelInfo.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairChannelInfo.cs @@ -1,33 +1,33 @@ #pragma warning disable 169 // Field 'x' is never used #pragma warning disable 414 // Field 'x' is assigned but its value never used #pragma warning disable 649 // Field 'x' is never assigned +#pragma warning disable IDE1006 // Naming Styles using System; using System.Runtime.InteropServices; -namespace RGB.NET.Devices.Corsair.Native +namespace RGB.NET.Devices.Corsair.Native; + +// ReSharper disable once InconsistentNaming +/// +/// CUE-SDK: contains information about separate channel of the DIY-device. +/// +[StructLayout(LayoutKind.Sequential)] +internal class _CorsairChannelInfo { - // ReSharper disable once InconsistentNaming /// - /// CUE-SDK: contains information about separate channel of the DIY-device. + /// CUE-SDK: total number of LEDs connected to the channel; /// - [StructLayout(LayoutKind.Sequential)] - internal class _CorsairChannelInfo - { - /// - /// CUE-SDK: total number of LEDs connected to the channel; - /// - internal int totalLedsCount; + internal int totalLedsCount; - /// - /// CUE-SDK: number of LED-devices (fans, strips, etc.) connected to the channel which is controlled by the DIY device - /// - internal int devicesCount; + /// + /// CUE-SDK: number of LED-devices (fans, strips, etc.) connected to the channel which is controlled by the DIY device + /// + internal int devicesCount; - /// - /// CUE-SDK: array containing information about each separate LED-device connected to the channel controlled by the DIY device. - /// Index of the LED-device in array is same as the index of the LED-device connected to the DIY-device. - /// - internal IntPtr devices; - } -} + /// + /// CUE-SDK: array containing information about each separate LED-device connected to the channel controlled by the DIY device. + /// Index of the LED-device in array is same as the index of the LED-device connected to the DIY-device. + /// + internal IntPtr devices; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairChannelsInfo.cs b/RGB.NET.Devices.Corsair/Native/_CorsairChannelsInfo.cs index 8dacba22..e2a5a12b 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairChannelsInfo.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairChannelsInfo.cs @@ -1,28 +1,28 @@ #pragma warning disable 169 // Field 'x' is never used #pragma warning disable 414 // Field 'x' is assigned but its value never used #pragma warning disable 649 // Field 'x' is never assigned +#pragma warning disable IDE1006 // Naming Styles using System; using System.Runtime.InteropServices; -namespace RGB.NET.Devices.Corsair.Native +namespace RGB.NET.Devices.Corsair.Native; + +// ReSharper disable once InconsistentNaming +/// +/// CUE-SDK: contains information about channels of the DIY-devices. +/// +[StructLayout(LayoutKind.Sequential)] +internal class _CorsairChannelsInfo { - // ReSharper disable once InconsistentNaming /// - /// CUE-SDK: contains information about channels of the DIY-devices. + /// CUE-SDK: number of channels controlled by the device /// - [StructLayout(LayoutKind.Sequential)] - internal class _CorsairChannelsInfo - { - /// - /// CUE-SDK: number of channels controlled by the device - /// - internal int channelsCount; + internal int channelsCount; - /// - /// CUE-SDK: array containing information about each separate channel of the DIY-device. - /// Index of the channel in the array is same as index of the channel on the DIY-device. - /// - internal IntPtr channels; - } -} + /// + /// CUE-SDK: array containing information about each separate channel of the DIY-device. + /// Index of the channel in the array is same as index of the channel on the DIY-device. + /// + internal IntPtr channels; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs b/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs index d584d73f..799fc5ac 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairDeviceInfo.cs @@ -1,52 +1,58 @@ #pragma warning disable 169 // Field 'x' is never used #pragma warning disable 414 // Field 'x' is assigned but its value never used #pragma warning disable 649 // Field 'x' is never assigned +#pragma warning disable IDE1006 // Naming Styles using System; using System.Runtime.InteropServices; -namespace RGB.NET.Devices.Corsair.Native +namespace RGB.NET.Devices.Corsair.Native; + +// ReSharper disable once InconsistentNaming +/// +/// CUE-SDK: contains information about device +/// +[StructLayout(LayoutKind.Sequential)] +internal class _CorsairDeviceInfo { - // ReSharper disable once InconsistentNaming - /// - /// CUE-SDK: contains information about device - /// - [StructLayout(LayoutKind.Sequential)] - internal class _CorsairDeviceInfo - { - /// - /// CUE-SDK: enum describing device type - /// - internal CorsairDeviceType type; - - /// - /// CUE-SDK: null - terminated device model(like “K95RGB”) - /// - internal IntPtr model; - - /// - /// CUE-SDK: enum describing physical layout of the keyboard or mouse - /// - internal int physicalLayout; - - /// - /// CUE-SDK: enum describing logical layout of the keyboard as set in CUE settings - /// - internal int logicalLayout; - - /// - /// CUE-SDK: mask that describes device capabilities, formed as logical “or” of CorsairDeviceCaps enum values - /// - internal int capsMask; - - /// - /// CUE-SDK: number of controllable LEDs on the device - /// - internal int ledsCount; - - /// - /// CUE-SDK: structure that describes channels of the DIY-devices - /// - internal _CorsairChannelsInfo channels; - } -} + /// + /// CUE-SDK: enum describing device type + /// + internal CorsairDeviceType type; + + /// + /// CUE-SDK: null - terminated device model(like “K95RGB”) + /// + internal IntPtr model; + + /// + /// CUE-SDK: enum describing physical layout of the keyboard or mouse + /// + internal int physicalLayout; + + /// + /// CUE-SDK: enum describing logical layout of the keyboard as set in CUE settings + /// + internal int logicalLayout; + + /// + /// CUE-SDK: mask that describes device capabilities, formed as logical “or” of CorsairDeviceCaps enum values + /// + internal int capsMask; + + /// + /// CUE-SDK: number of controllable LEDs on the device + /// + internal int ledsCount; + + /// + /// CUE-SDK: structure that describes channels of the DIY-devices + /// + internal _CorsairChannelsInfo? channels; + + /// + /// CUE-SDK: null-terminated string that contains unique device identifier that uniquely identifies device at least within session + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] + internal string? deviceId; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairLedColor.cs b/RGB.NET.Devices.Corsair/Native/_CorsairLedColor.cs index 349b6c16..004b36a7 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairLedColor.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairLedColor.cs @@ -1,36 +1,37 @@ #pragma warning disable 169 // Field 'x' is never used #pragma warning disable 414 // Field 'x' is assigned but its value never used #pragma warning disable 649 // Field 'x' is never assigned +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable NotAccessedField.Global using System.Runtime.InteropServices; -namespace RGB.NET.Devices.Corsair.Native +namespace RGB.NET.Devices.Corsair.Native; + +// ReSharper disable once InconsistentNaming +/// +/// CUE-SDK: contains information about led and its color +/// +[StructLayout(LayoutKind.Sequential)] +internal class _CorsairLedColor { - // ReSharper disable once InconsistentNaming /// - /// CUE-SDK: contains information about led and its color + /// CUE-SDK: identifier of LED to set /// - [StructLayout(LayoutKind.Sequential)] - internal class _CorsairLedColor - { - /// - /// CUE-SDK: identifier of LED to set - /// - internal int ledId; + internal int ledId; - /// - /// CUE-SDK: red brightness[0..255] - /// - internal int r; + /// + /// CUE-SDK: red brightness[0..255] + /// + internal int r; - /// - /// CUE-SDK: green brightness[0..255] - /// - internal int g; + /// + /// CUE-SDK: green brightness[0..255] + /// + internal int g; - /// - /// CUE-SDK: blue brightness[0..255] - /// - internal int b; - }; -} + /// + /// CUE-SDK: blue brightness[0..255] + /// + internal int b; +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairLedPosition.cs b/RGB.NET.Devices.Corsair/Native/_CorsairLedPosition.cs index 4ea43568..34f4108f 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairLedPosition.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairLedPosition.cs @@ -1,42 +1,42 @@ #pragma warning disable 169 // Field 'x' is never used #pragma warning disable 414 // Field 'x' is assigned but its value never used #pragma warning disable 649 // Field 'x' is never assigned +#pragma warning disable IDE1006 // Naming Styles using System.Runtime.InteropServices; -namespace RGB.NET.Devices.Corsair.Native +namespace RGB.NET.Devices.Corsair.Native; + +// ReSharper disable once InconsistentNaming +/// +/// CUE-SDK: contains led id and position of led rectangle.Most of the keys are rectangular. +/// In case if key is not rectangular(like Enter in ISO / UK layout) it returns the smallest rectangle that fully contains the key +/// +[StructLayout(LayoutKind.Sequential)] +internal class _CorsairLedPosition { - // ReSharper disable once InconsistentNaming /// - /// CUE-SDK: contains led id and position of led rectangle.Most of the keys are rectangular. - /// In case if key is not rectangular(like Enter in ISO / UK layout) it returns the smallest rectangle that fully contains the key + /// CUE-SDK: identifier of led /// - [StructLayout(LayoutKind.Sequential)] - internal class _CorsairLedPosition - { - /// - /// CUE-SDK: identifier of led - /// - internal CorsairLedId LedId; + internal CorsairLedId LedId; - /// - /// CUE-SDK: values in mm - /// - internal double top; + /// + /// CUE-SDK: values in mm + /// + internal double top; - /// - /// CUE-SDK: values in mm - /// - internal double left; + /// + /// CUE-SDK: values in mm + /// + internal double left; - /// - /// CUE-SDK: values in mm - /// - internal double height; + /// + /// CUE-SDK: values in mm + /// + internal double height; - /// - /// CUE-SDK: values in mm - /// - internal double width; - } -} + /// + /// CUE-SDK: values in mm + /// + internal double width; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairLedPositions.cs b/RGB.NET.Devices.Corsair/Native/_CorsairLedPositions.cs index afb8565b..c3186d35 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairLedPositions.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairLedPositions.cs @@ -5,23 +5,22 @@ using System; using System.Runtime.InteropServices; -namespace RGB.NET.Devices.Corsair.Native +namespace RGB.NET.Devices.Corsair.Native; + +// ReSharper disable once InconsistentNaming +/// +/// CUE-SDK: contains number of leds and arrays with their positions +/// +[StructLayout(LayoutKind.Sequential)] +internal class _CorsairLedPositions { - // ReSharper disable once InconsistentNaming /// - /// CUE-SDK: contains number of leds and arrays with their positions + /// CUE-SDK: integer value.Number of elements in following array /// - [StructLayout(LayoutKind.Sequential)] - internal class _CorsairLedPositions - { - /// - /// CUE-SDK: integer value.Number of elements in following array - /// - internal int numberOfLed; + internal int numberOfLed; - /// - /// CUE-SDK: array of led positions - /// - internal IntPtr pLedPosition; - } -} + /// + /// CUE-SDK: array of led positions + /// + internal IntPtr pLedPosition; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Native/_CorsairProtocolDetails.cs b/RGB.NET.Devices.Corsair/Native/_CorsairProtocolDetails.cs index 9fc731b8..cd6bf6e4 100644 --- a/RGB.NET.Devices.Corsair/Native/_CorsairProtocolDetails.cs +++ b/RGB.NET.Devices.Corsair/Native/_CorsairProtocolDetails.cs @@ -5,40 +5,39 @@ using System; using System.Runtime.InteropServices; -namespace RGB.NET.Devices.Corsair.Native +namespace RGB.NET.Devices.Corsair.Native; + +// ReSharper disable once InconsistentNaming +/// +/// CUE-SDK: contains information about SDK and CUE versions +/// +[StructLayout(LayoutKind.Sequential)] +internal struct _CorsairProtocolDetails { - // ReSharper disable once InconsistentNaming /// - /// CUE-SDK: contains information about SDK and CUE versions + /// CUE-SDK: null - terminated string containing version of SDK(like “1.0.0.1”). Always contains valid value even if there was no CUE found /// - [StructLayout(LayoutKind.Sequential)] - internal struct _CorsairProtocolDetails - { - /// - /// CUE-SDK: null - terminated string containing version of SDK(like “1.0.0.1”). Always contains valid value even if there was no CUE found - /// - internal IntPtr sdkVersion; + internal IntPtr sdkVersion; - /// - /// CUE-SDK: null - terminated string containing version of CUE(like “1.0.0.1”) or NULL if CUE was not found. - /// - internal IntPtr serverVersion; + /// + /// CUE-SDK: null - terminated string containing version of CUE(like “1.0.0.1”) or NULL if CUE was not found. + /// + internal IntPtr serverVersion; - /// - /// CUE-SDK: integer number that specifies version of protocol that is implemented by current SDK. - /// Numbering starts from 1. Always contains valid value even if there was no CUE found - /// - internal int sdkProtocolVersion; + /// + /// CUE-SDK: integer number that specifies version of protocol that is implemented by current SDK. + /// Numbering starts from 1. Always contains valid value even if there was no CUE found + /// + internal int sdkProtocolVersion; - /// - /// CUE-SDK: integer number that specifies version of protocol that is implemented by CUE. - /// Numbering starts from 1. If CUE was not found then this value will be 0 - /// - internal int serverProtocolVersion; + /// + /// CUE-SDK: integer number that specifies version of protocol that is implemented by CUE. + /// Numbering starts from 1. If CUE was not found then this value will be 0 + /// + internal int serverProtocolVersion; - /// - /// CUE-SDK: boolean value that specifies if there were breaking changes between version of protocol implemented by server and client - /// - internal byte breakingChanges; - }; -} + /// + /// CUE-SDK: boolean value that specifies if there were breaking changes between version of protocol implemented by server and client + /// + internal byte breakingChanges; +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/README.md b/RGB.NET.Devices.Corsair/README.md new file mode 100644 index 00000000..dd30377f --- /dev/null +++ b/RGB.NET.Devices.Corsair/README.md @@ -0,0 +1,24 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for Corsair-Devices. + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(CorsairDeviceProvider.Instance); +``` + +# Required SDK +This providers requires native SDK-dlls. +You can get them directly from Corsair at [https://github.com/CorsairOfficial/cue-sdk/releases](https://github.com/CorsairOfficial/cue-sdk/releases) + +Since the SDK-dlls are native it's important to use the correct architecture you're building your application for. (If in doubt you can always include both.) + +### x64 +`redist\x64\CUESDK.x64_2019.dll` from the SDK-zip needs to be distributed as `\x64\CUESDK.x64_2019.dll` (or simply named `CUESDK.dll`) + +You can use other, custom paths by adding them to `CorsairDeviceProvider.PossibleX64NativePaths`. + +### x86 +`redist\i386\CUESDK_2019.dll` from the SDK-zip needs to be distributed as `\x86\CUESDK_2019.dll` (or simply named `CUESDK.dll`) + +You can use other, custom paths by adding them to `CorsairDeviceProvider.PossibleX86NativePaths`. diff --git a/RGB.NET.Devices.Corsair/RGB.NET.Devices.Corsair.csproj b/RGB.NET.Devices.Corsair/RGB.NET.Devices.Corsair.csproj index e334b6b0..302d93df 100644 --- a/RGB.NET.Devices.Corsair/RGB.NET.Devices.Corsair.csproj +++ b/RGB.NET.Devices.Corsair/RGB.NET.Devices.Corsair.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.Corsair Corsair-Device-Implementations of RGB.NET Corsair-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,36 +35,29 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg + true $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + - - + + \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/RGB.NET.Devices.Corsair.csproj.DotSettings b/RGB.NET.Devices.Corsair/RGB.NET.Devices.Corsair.csproj.DotSettings index 704d9f95..eeca9716 100644 --- a/RGB.NET.Devices.Corsair/RGB.NET.Devices.Corsair.csproj.DotSettings +++ b/RGB.NET.Devices.Corsair/RGB.NET.Devices.Corsair.csproj.DotSettings @@ -1,8 +1,10 @@  True + True True True True + True True True False @@ -15,4 +17,6 @@ True True True - True \ No newline at end of file + True + True + \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/SpecialParts/LightbarSpecialPart.cs b/RGB.NET.Devices.Corsair/SpecialParts/LightbarSpecialPart.cs deleted file mode 100644 index 705bac09..00000000 --- a/RGB.NET.Devices.Corsair/SpecialParts/LightbarSpecialPart.cs +++ /dev/null @@ -1,79 +0,0 @@ -// ReSharper disable UnusedMember.Global -// ReSharper disable MemberCanBePrivate.Global - -using System.Collections; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Corsair -{ - /// - /// - /// Represents a lightbar attached to a - /// - public class LightbarSpecialPart : IRGBDeviceSpecialPart - { - #region Properties & Fields - - private List _leds; - /// - /// Gets a readonly collection of all of this . - /// - public IEnumerable Leds => new ReadOnlyCollection(_leds); - - private List _left; - /// - /// Gets a readonly collection of all in the left half of this . - /// - public IEnumerable Left => new ReadOnlyCollection(_left); - - private List _right; - /// - /// Gets a readonly collection of all in the right half of this . - /// - public IEnumerable Right => new ReadOnlyCollection(_right); - - /// - /// Gets the Center of this . - /// - public Led Center { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The device associated with this . - public LightbarSpecialPart(IRGBDevice device) - { - _leds = device.Where(led => ((CorsairLedId)led.CustomData >= CorsairLedId.Lightbar1) && ((CorsairLedId)led.CustomData <= CorsairLedId.Lightbar19)).ToList(); - _left = _leds.Where(led => (CorsairLedId)led.CustomData < CorsairLedId.Lightbar10).ToList(); - _right = _leds.Where(led => (CorsairLedId)led.CustomData > CorsairLedId.Lightbar10).ToList(); - Center = _leds.FirstOrDefault(led => (CorsairLedId)led.CustomData == CorsairLedId.Lightbar10); - } - - #endregion - - #region Methods - - /// - /// - /// Returns an enumerator that iterates over all of the . - /// - /// An enumerator for all of the . - public IEnumerator GetEnumerator() => _leds.GetEnumerator(); - - /// - /// - /// Returns an enumerator that iterates over all of the . - /// - /// An enumerator for all of the . - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - #endregion - } -} diff --git a/RGB.NET.Devices.Corsair/Touchbar/CorsairTouchbarRGBDevice.cs b/RGB.NET.Devices.Corsair/Touchbar/CorsairTouchbarRGBDevice.cs new file mode 100644 index 00000000..092e84c0 --- /dev/null +++ b/RGB.NET.Devices.Corsair/Touchbar/CorsairTouchbarRGBDevice.cs @@ -0,0 +1,27 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using RGB.NET.Core; + +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a corsair touchbar. +/// +public class CorsairTouchbarRGBDevice : CorsairRGBDevice, IDRAM +{ + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The specific information provided by CUE for the touchbar. + /// The queue used to update this device. + internal CorsairTouchbarRGBDevice(CorsairTouchbarRGBDeviceInfo info, CorsairDeviceUpdateQueue updateQueue) + : base(info, LedMappings.Keyboard, updateQueue) //TODO DarthAffe 17.07.2022: Find someone with such a device and check which LedIds are actually used + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Corsair/Touchbar/CorsairTouchbarRGBDeviceInfo.cs b/RGB.NET.Devices.Corsair/Touchbar/CorsairTouchbarRGBDeviceInfo.cs new file mode 100644 index 00000000..9ee690c1 --- /dev/null +++ b/RGB.NET.Devices.Corsair/Touchbar/CorsairTouchbarRGBDeviceInfo.cs @@ -0,0 +1,28 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable UnusedMember.Global + +using RGB.NET.Core; +using RGB.NET.Devices.Corsair.Native; + +namespace RGB.NET.Devices.Corsair; + +/// +/// +/// Represents a generic information for a . +/// +public class CorsairTouchbarRGBDeviceInfo : CorsairRGBDeviceInfo +{ + #region Constructors + + /// + /// + /// Internal constructor of managed . + /// + /// The index of the . + /// The native -struct + internal CorsairTouchbarRGBDeviceInfo(int deviceIndex, _CorsairDeviceInfo nativeInfo) + : base(deviceIndex, RGBDeviceType.Keypad, nativeInfo) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs index a151778d..55e8e3fd 100644 --- a/RGB.NET.Devices.DMX/DMXDeviceProvider.cs +++ b/RGB.NET.Devices.DMX/DMXDeviceProvider.cs @@ -3,124 +3,88 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using RGB.NET.Core; using RGB.NET.Devices.DMX.E131; -namespace RGB.NET.Devices.DMX +namespace RGB.NET.Devices.DMX; + +/// +/// +/// Represents a device provider responsible for DMX devices. +/// +public class DMXDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static DMXDeviceProvider? _instance; /// - /// Represents a device provider responsible for DMX devices. + /// Gets the singleton instance. /// - public class DMXDeviceProvider : IRGBDeviceProvider - { - #region Properties & Fields - - private static DMXDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static DMXDeviceProvider Instance => _instance ?? new DMXDeviceProvider(); - - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - public bool HasExclusiveAccess => false; + public static DMXDeviceProvider Instance => _instance ?? new DMXDeviceProvider(); - /// - /// Gets a list of all defined device-definitions. - /// - public List DeviceDefinitions { get; } = new List(); - - /// - /// The used to trigger the updates for dmx devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } + /// + /// Gets a list of all defined device-definitions. + /// + public List DeviceDefinitions { get; } = new(); - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public DMXDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(DMXDeviceProvider)}"); - _instance = this; + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public DMXDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(DMXDeviceProvider)}"); + _instance = this; + } - UpdateTrigger = new DeviceUpdateTrigger(); - } + #endregion - #endregion + #region Methods - #region Methods + /// + /// Adds the specified to this device-provider. + /// + /// The to add. + public void AddDeviceDefinition(IDMXDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); - /// - /// Adds the given to this device-provider. - /// - /// The to add. - public void AddDeviceDefinition(IDMXDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); + /// + protected override void InitializeSDK() { } - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + /// + protected override IEnumerable LoadDevices() + { + for (int i = 0; i < DeviceDefinitions.Count; i++) { - IsInitialized = false; - + IDMXDeviceDefinition dmxDeviceDefinition = DeviceDefinitions[i]; + IRGBDevice? device = null; try { - UpdateTrigger.Stop(); - - IList devices = new List(); - - foreach (IDMXDeviceDefinition dmxDeviceDefinition in DeviceDefinitions) - { - try - { - if (dmxDeviceDefinition is E131DMXDeviceDefinition e131DMXDeviceDefinition) - { - if (e131DMXDeviceDefinition.Leds.Count > 0) - { - E131Device device = new E131Device(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - } - } - catch { if (throwExceptions) throw; } - } - - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; + if (dmxDeviceDefinition is E131DMXDeviceDefinition e131DMXDeviceDefinition) + if (e131DMXDeviceDefinition.Leds.Count > 0) + device = new E131Device(new E131DeviceInfo(e131DMXDeviceDefinition), e131DMXDeviceDefinition.Leds, GetUpdateTrigger(i)); } - catch + catch (Exception ex) { - if (throwExceptions) throw; - return false; + Throw(ex); } - return true; + if (device != null) + yield return device; } + } - /// - public void ResetDevices() - { } - - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } - } + protected override IDeviceUpdateTrigger CreateUpdateTrigger(int id, double updateRateHardLimit) + { + DeviceUpdateTrigger updateTrigger = new(updateRateHardLimit); + if ((DeviceDefinitions[id] is E131DMXDeviceDefinition e131DMXDeviceDefinition)) + updateTrigger.HeartbeatTimer = e131DMXDeviceDefinition.HeartbeatTimer; - #endregion + return updateTrigger; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/DMXDeviceProviderLoader.cs b/RGB.NET.Devices.DMX/DMXDeviceProviderLoader.cs deleted file mode 100644 index 193cc6be..00000000 --- a/RGB.NET.Devices.DMX/DMXDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.DMX -{ - /// - /// Represents a device provider loaded used to dynamically load DMX devices into an application. - /// - public class DMXDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => true; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => DMXDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.DMX/E131/E131DMXDeviceDefinition.cs b/RGB.NET.Devices.DMX/E131/E131DMXDeviceDefinition.cs index 8e7fb9b7..37db5ea0 100644 --- a/RGB.NET.Devices.DMX/E131/E131DMXDeviceDefinition.cs +++ b/RGB.NET.Devices.DMX/E131/E131DMXDeviceDefinition.cs @@ -7,86 +7,91 @@ using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.DMX.E131 +namespace RGB.NET.Devices.DMX.E131; + +/// +/// Represents the data used to create a E1.31 DMX-device. +/// +public class E131DMXDeviceDefinition : IDMXDeviceDefinition { + #region Properties & Fields + /// - /// Represents the data used to create a E1.31 DMX-device. + /// Gets or sets the hostname of the device. /// - public class E131DMXDeviceDefinition : IDMXDeviceDefinition - { - #region Properties & Fields + public string Hostname { get; set; } - /// - /// Gets or sets the hostname of the device. - /// - public string Hostname { get; set; } + /// + /// Gets or sets the port to device is listening to. + /// + public int Port { get; set; } = 5568; - /// - /// Gets or sets the port to device is listening to. - /// - public int Port { get; set; } = 5568; + /// + /// Gets or sets the of the device. + /// + public RGBDeviceType DeviceType { get; set; } = RGBDeviceType.Unknown; - /// - /// Gets or sets the of the device. - /// - public RGBDeviceType DeviceType { get; set; } = RGBDeviceType.Unknown; + /// + /// Gets or sets the manufacturer of the device. + /// + public string Manufacturer { get; set; } = "Unknown"; - /// - /// Gets or sets the manufacturer of the device. - /// - public string Manufacturer { get; set; } = "Unknown"; + /// + /// Gets or sets the model name of the device. + /// + public string Model { get; set; } = "Generic DMX-Device"; - /// - /// Gets or sets the model name of the device. - /// - public string Model { get; set; } = "Generic DMX-Device"; + /// + /// Gets or sets the CID of the device (null will generate a random CID) + /// + // ReSharper disable once InconsistentNaming + public byte[]? CID { get; set; } - /// - /// Gets or sets the CID of the device (null will generate a random CID) - /// - // ReSharper disable once InconsistentNaming - public byte[] CID { get; set; } + /// + /// Gets or sets the universe the device belongs to. + /// + public short Universe { get; set; } = 1; - /// - /// Gets or sets the universe the device belongs to. - /// - public short Universe { get; set; } = 1; + /// + /// Gets or sets the led-mappings used to create the device. + /// + public Dictionary getValueFunc)>> Leds { get; } = new(); - /// - /// Gets or sets the led-mappings used to create the device. - /// - public Dictionary getValueFunc)>> Leds { get; } = new Dictionary getValueFunc)>>(); + /// + /// The time in ms after which the device is updated even if no changes are made in the meantime to prevent the target from timing out or similar problems. + /// To disable heartbeats leave it at 0. + /// + public int HeartbeatTimer { get; set; } = 0; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// - /// - /// - public E131DMXDeviceDefinition(string hostname) - { - this.Hostname = hostname; - } + /// + /// Initializes a new instance of the class. + /// + /// The hostname of the device. + public E131DMXDeviceDefinition(string hostname) + { + this.Hostname = hostname; + } - #endregion + #endregion - #region Methods + #region Methods - /// - /// Adds a led-mapping to the device. - /// - /// The used to identify the led. - /// The channels the led is using and a function mapping parts of the color to them. - public void AddLed(LedId id, params (int channel, Func getValueFunc)[] channels) => Leds[id] = channels.ToList(); + /// + /// Adds a led-mapping to the device. + /// + /// The used to identify the led. + /// The channels the led is using and a function mapping parts of the color to them. + public void AddLed(LedId id, params (int channel, Func getValueFunc)[] channels) => Leds[id] = channels.ToList(); - #endregion + #endregion - #region Factory + #region Factory - //TODO DarthAffe 18.02.2018: Add factory-methods. + //TODO DarthAffe 18.02.2018: Add factory-methods. - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/E131/E131DataPacketExtension.cs b/RGB.NET.Devices.DMX/E131/E131DataPacketExtension.cs index aa76741d..4eac0c93 100644 --- a/RGB.NET.Devices.DMX/E131/E131DataPacketExtension.cs +++ b/RGB.NET.Devices.DMX/E131/E131DataPacketExtension.cs @@ -1,25 +1,24 @@ using System; using System.Linq; -namespace RGB.NET.Devices.DMX.E131 +namespace RGB.NET.Devices.DMX.E131; + +internal static class E131DataPacketExtension { - internal static class E131DataPacketExtension - { - #region Methods + #region Methods - // ReSharper disable once InconsistentNaming - internal static void SetCID(this byte[] data, byte[] cid) => Array.Copy(cid, 0, data, 22, 16); + // ReSharper disable once InconsistentNaming + internal static void SetCID(this byte[] data, byte[] cid) => Array.Copy(cid, 0, data, 22, 16); - internal static void SetSequenceNumber(this byte[] data, byte sequenceNumber) => data[111] = sequenceNumber; + internal static void SetSequenceNumber(this byte[] data, byte sequenceNumber) => data[111] = sequenceNumber; - internal static void SetUniverse(this byte[] data, short universe) => Array.Copy(ToBigEndian(BitConverter.GetBytes(universe)), 0, data, 113, 2); + internal static void SetUniverse(this byte[] data, short universe) => Array.Copy(ToBigEndian(BitConverter.GetBytes(universe)), 0, data, 113, 2); - internal static void ClearColors(this byte[] data) => Array.Clear(data, 126, 512); + internal static void ClearColors(this byte[] data) => Array.Clear(data, 126, 512); - internal static void SetChannel(this byte[] data, int channel, byte value) => data[126 + channel] = value; + internal static void SetChannel(this byte[] data, int channel, byte value) => data[126 + channel] = value; - private static byte[] ToBigEndian(byte[] data) => BitConverter.IsLittleEndian ? data.Reverse().ToArray() : data; + private static byte[] ToBigEndian(byte[] data) => BitConverter.IsLittleEndian ? data.Reverse().ToArray() : data; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/E131/E131Device.cs b/RGB.NET.Devices.DMX/E131/E131Device.cs index a4a69d25..a7d3473e 100644 --- a/RGB.NET.Devices.DMX/E131/E131Device.cs +++ b/RGB.NET.Devices.DMX/E131/E131Device.cs @@ -1,73 +1,48 @@ using System; using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.DMX.E131 -{ - /// - /// Represents a E1.31-DXM-device. - /// - public class E131Device : AbstractRGBDevice, IUnknownDevice - { - #region Properties & Fields - - /// - public override E131DeviceInfo DeviceInfo { get; } - - private readonly Dictionary getValueFunc)>> _ledMappings; - - private E131UpdateQueue _updateQueue; - - #endregion - - #region Constructors +namespace RGB.NET.Devices.DMX.E131; - /// - internal E131Device(E131DeviceInfo deviceInfo, Dictionary getValueFunc)>> ledMappings) - { - this.DeviceInfo = deviceInfo; - this._ledMappings = ledMappings; - } +/// +/// Represents a E1.31-DXM-device. +/// +public class E131Device : AbstractRGBDevice, IUnknownDevice +{ + #region Properties & Fields - #endregion + private readonly Dictionary getValueFunc)>> _ledMappings; - #region Methods + #endregion - internal void Initialize(IDeviceUpdateTrigger updateTrigger) - { - int count = 0; - foreach (LedId id in _ledMappings.Keys) - InitializeLed(id, new Rectangle((count++) * 10, 0, 10, 10)); + #region Constructors - //TODO DarthAffe 18.02.2018: Allow to load a layout. + /// + internal E131Device(E131DeviceInfo deviceInfo, Dictionary getValueFunc)>> ledMappings, IDeviceUpdateTrigger updateTrigger) + : base(deviceInfo, new E131UpdateQueue(updateTrigger, deviceInfo.Hostname, deviceInfo.Port)) + { + this._ledMappings = ledMappings; - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } + InitializeLayout(); - _updateQueue = new E131UpdateQueue(updateTrigger, DeviceInfo.Hostname, DeviceInfo.Port); - _updateQueue.DataPacket.SetCID(DeviceInfo.CID); - _updateQueue.DataPacket.SetUniverse(DeviceInfo.Universe); - } + E131UpdateQueue updateQueue = (E131UpdateQueue)UpdateQueue; + updateQueue.DataPacket.SetCID(DeviceInfo.CID); + updateQueue.DataPacket.SetUniverse(DeviceInfo.Universe); + } - /// - protected override object CreateLedCustomData(LedId ledId) => new LedChannelMapping(_ledMappings[ledId]); + #endregion - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => _updateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + #region Methods - /// - public override void Dispose() - { - try { _updateQueue?.Dispose(); } - catch { /* at least we tried */ } + private void InitializeLayout() + { + int count = 0; + foreach (LedId id in _ledMappings.Keys) + AddLed(id, new Point((count++) * 10, 0), new Size(10, 10)); + } - base.Dispose(); - } + /// + protected override object GetLedCustomData(LedId ledId) => new LedChannelMapping(_ledMappings[ledId]); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs b/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs index 2401f585..330a740f 100644 --- a/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs +++ b/RGB.NET.Devices.DMX/E131/E131DeviceInfo.cs @@ -1,90 +1,85 @@ using System; using RGB.NET.Core; -namespace RGB.NET.Devices.DMX.E131 +namespace RGB.NET.Devices.DMX.E131; + +/// +/// +/// Represents device information for a />. +/// +public class E131DeviceInfo : IRGBDeviceInfo { - /// + #region Constants + /// - /// Represents device information for a />. + /// The length of the CID; /// - public class E131DeviceInfo : IRGBDeviceInfo - { - #region Constants - - /// - /// The length of the CID; - /// - // ReSharper disable once MemberCanBePrivate.Global - public const int CID_LENGTH = 16; - - #endregion + // ReSharper disable once MemberCanBePrivate.Global + public const int CID_LENGTH = 16; - #region Properties & Fields + #endregion - /// - public RGBDeviceType DeviceType { get; } + #region Properties & Fields - /// - public string DeviceName { get; } - - /// - public string Manufacturer { get; } + /// + public RGBDeviceType DeviceType { get; } - /// - public string Model { get; } + /// + public string DeviceName { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public string Manufacturer { get; } - /// - public bool SupportsSyncBack => false; + /// + public string Model { get; } - /// - public Uri Image { get; set; } + /// + public object? LayoutMetadata { get; set; } - /// - /// The hostname of the device. - /// - public string Hostname { get; } + /// + /// The hostname of the device. + /// + public string Hostname { get; } - /// - /// The port of the device. - /// - public int Port { get; } + /// + /// The port of the device. + /// + public int Port { get; } - /// - /// The CID used to identify against the device. - /// - public byte[] CID { get; } + /// + /// The CID used to identify against the device. + /// + public byte[] CID { get; } - /// - /// The Universe this device belongs to. - /// - public short Universe { get; } + /// + /// The Universe this device belongs to. + /// + public short Universe { get; } - #endregion + #endregion - #region Constructors + #region Constructors - internal E131DeviceInfo(E131DMXDeviceDefinition deviceDefinition) + internal E131DeviceInfo(E131DMXDeviceDefinition deviceDefinition) + { + this.DeviceType = deviceDefinition.DeviceType; + this.Manufacturer = deviceDefinition.Manufacturer; + this.Model = deviceDefinition.Model; + this.Hostname = deviceDefinition.Hostname; + this.Port = deviceDefinition.Port; + this.Universe = deviceDefinition.Universe; + + byte[]? cid = deviceDefinition.CID; + if ((cid == null) || (cid.Length != CID_LENGTH)) { - this.DeviceType = deviceDefinition.DeviceType; - this.Manufacturer = deviceDefinition.Manufacturer; - this.Model = deviceDefinition.Model; - this.Hostname = deviceDefinition.Hostname; - this.Port = deviceDefinition.Port; - this.CID = deviceDefinition.CID; - this.Universe = deviceDefinition.Universe; - - if ((CID == null) || (CID.Length != CID_LENGTH)) - { - CID = new byte[CID_LENGTH]; - new Random().NextBytes(CID); - } - - DeviceName = $"{Manufacturer} {Model}"; + cid = new byte[CID_LENGTH]; + new Random().NextBytes(cid); } - #endregion + CID = cid; + + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs b/RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs index dcf301e7..b1bffdb3 100644 --- a/RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs +++ b/RGB.NET.Devices.DMX/E131/E131UpdateQueue.cs @@ -1,86 +1,92 @@ using System; -using System.Collections.Generic; using System.Net.Sockets; using RGB.NET.Core; -namespace RGB.NET.Devices.DMX.E131 +namespace RGB.NET.Devices.DMX.E131; + +/// +/// +/// Represents the update-queue performing updates for E131-DMX devices. +/// +public class E131UpdateQueue : UpdateQueue { + #region Properties & Fields + + /// + /// The UDP-Connection used to send data. + /// + private readonly UdpClient _socket; + + /// + /// Gets the byte-representation of a E1.31 packet as described in http://tsp.esta.org/tsp/documents/docs/E1-31-2016.pdf. + /// CID, SequenceNumber, Universe and PropertyValues needs to be updated before use! + /// + internal byte[] DataPacket { get; } = { 0x00, 0x10, 0x00, 0x00, 0x41, 0x53, 0x43, 0x2D, 0x45, 0x31, 0x2E, 0x31, 0x37, 0x00, 0x00, 0x00, 0x72, 0x6E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x72, 0x0B, 0x02, 0xA1, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + + /// + /// The sequence-number used to detect the order in which packages where sent. + /// + private byte _sequenceNumber; + + #endregion + + #region Constructors + /// /// - /// Represents the update-queue performing updates for E131-DMX devices. + /// Initializes a new instance of the class. /// - public class E131UpdateQueue : UpdateQueue + /// The update trigger used by this queue. + /// The hostname of the device this queue is performing updates for. + /// The port to connect to the device this queue is performing updates for. + public E131UpdateQueue(IDeviceUpdateTrigger updateTrigger, string hostname, int port) + : base(updateTrigger) { - #region Properties & Fields - - /// - /// The UDP-Connection used to send data. - /// - private UdpClient _socket; - - /// - /// Gets the byte-representation of a E1.31 packet as described in http://tsp.esta.org/tsp/documents/docs/E1-31-2016.pdf. - /// CID, SequenceNumber, Universe and PropertyValues needs to be updated before use! - /// - internal byte[] DataPacket { get; } = { 0x00, 0x10, 0x00, 0x00, 0x41, 0x53, 0x43, 0x2D, 0x45, 0x31, 0x2E, 0x31, 0x37, 0x00, 0x00, 0x00, 0x72, 0x6E, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x72, 0x0B, 0x02, 0xA1, 0x00, 0x00, 0x00, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - /// - /// The sequence-number used to detect the order in which packages where sent. - /// - private byte _sequenceNumber = 0; - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The hostname of the device this queue is performing updates for. - /// The port to connect to the device this queue is performing updates for. - public E131UpdateQueue(IDeviceUpdateTrigger updateTrigger, string hostname, int port) - : base(updateTrigger) - { - _socket = new UdpClient(); - _socket.Connect(hostname, port); - } + _socket = new UdpClient(); + _socket.Connect(hostname, port); + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void Update(Dictionary dataSet) - { - DataPacket.SetSequenceNumber(GetNextSequenceNumber()); + protected override void OnUpdate(object? sender, CustomUpdateData customData) + { + if (customData[CustomUpdateDataIndex.HEARTBEAT] as bool? ?? false) + Update(Array.Empty<(object key, Color color)>()); + else + base.OnUpdate(sender, customData); + } - foreach (KeyValuePair data in dataSet) - { - LedChannelMapping mapping = (LedChannelMapping)data.Key; - foreach ((int channel, Func getValue) in mapping) - DataPacket.SetChannel(channel, getValue(data.Value)); - } + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + DataPacket.SetSequenceNumber(GetNextSequenceNumber()); - _socket.Send(DataPacket, DataPacket.Length); + foreach ((object key, Color color) in dataSet) + { + LedChannelMapping mapping = (LedChannelMapping)key; + foreach ((int channel, Func getValue) in mapping) + DataPacket.SetChannel(channel, getValue(color)); } - /// - /// Increments the sequence number and wraps it if neded. - /// - /// The next usable sequence number. - private byte GetNextSequenceNumber() - { - if (_sequenceNumber == byte.MaxValue) - { - _sequenceNumber = byte.MinValue; - return byte.MaxValue; - } + _socket.Send(DataPacket, DataPacket.Length); + } - return _sequenceNumber++; + /// + /// Increments the sequence number and wraps it if neded. + /// + /// The next usable sequence number. + private byte GetNextSequenceNumber() + { + if (_sequenceNumber == byte.MaxValue) + { + _sequenceNumber = byte.MinValue; + return byte.MaxValue; } - #endregion + return _sequenceNumber++; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/Generic/IDMXDeviceDefinition.cs b/RGB.NET.Devices.DMX/Generic/IDMXDeviceDefinition.cs index 5750c2f6..5ec87dfc 100644 --- a/RGB.NET.Devices.DMX/Generic/IDMXDeviceDefinition.cs +++ b/RGB.NET.Devices.DMX/Generic/IDMXDeviceDefinition.cs @@ -1,8 +1,7 @@ -namespace RGB.NET.Devices.DMX -{ - /// - /// Marker interface for DMX device definitions. - /// - public interface IDMXDeviceDefinition - { } -} +namespace RGB.NET.Devices.DMX; + +/// +/// Marker interface for DMX device definitions. +/// +public interface IDMXDeviceDefinition +{ } \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/Generic/LedChannelMapping.cs b/RGB.NET.Devices.DMX/Generic/LedChannelMapping.cs index 63b5b762..2f999e3e 100644 --- a/RGB.NET.Devices.DMX/Generic/LedChannelMapping.cs +++ b/RGB.NET.Devices.DMX/Generic/LedChannelMapping.cs @@ -3,30 +3,29 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.DMX +namespace RGB.NET.Devices.DMX; + +internal class LedChannelMapping : IEnumerable<(int channel, Func getValue)> { - internal class LedChannelMapping : IEnumerable<(int channel, Func getValue)> - { - #region Properties & Fields + #region Properties & Fields - private readonly List<(int channel, Func getValue)> _mappings; + private readonly List<(int channel, Func getValue)> _mappings; - #endregion + #endregion - #region Constructors + #region Constructors - public LedChannelMapping(List<(int channel, Func getValue)> mappings) - { - this._mappings = new List<(int channel, Func getValue)>(mappings); - } + public LedChannelMapping(List<(int channel, Func getValue)> mappings) + { + this._mappings = new List<(int channel, Func getValue)>(mappings); + } - #endregion + #endregion - #region Methods + #region Methods - public IEnumerator<(int channel, Func getValue)> GetEnumerator() => _mappings.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + public IEnumerator<(int channel, Func getValue)> GetEnumerator() => _mappings.GetEnumerator(); + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/README.md b/RGB.NET.Devices.DMX/README.md new file mode 100644 index 00000000..494c5d29 --- /dev/null +++ b/RGB.NET.Devices.DMX/README.md @@ -0,0 +1,16 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for E1.31 DMX-Devices. + +## Usage +This provider does not load anything by default and requires additional configuration to work. + +```csharp +// Add as many DMX devices as you like +DMXDeviceProvider.Instance.AddDeviceDefinition(new E131DMXDeviceDefinition("")); + +surface.Load(DMXDeviceProvider.Instance); +``` + +You can also configure additional things like device names, custom ports, heartbeats and so on in the DeviceDefinition. + +# Required SDK +This provider does not require an additional SDK. diff --git a/RGB.NET.Devices.DMX/RGB.NET.Devices.DMX.csproj b/RGB.NET.Devices.DMX/RGB.NET.Devices.DMX.csproj index 96c1089f..d291aa09 100644 --- a/RGB.NET.Devices.DMX/RGB.NET.Devices.DMX.csproj +++ b/RGB.NET.Devices.DMX/RGB.NET.Devices.DMX.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.DMX DMX-Device-Implementations of RGB.NET DMX-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,36 +35,28 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + - - + + \ No newline at end of file diff --git a/RGB.NET.Devices.DMX/RGB.NET.Devices.DMX.csproj.DotSettings b/RGB.NET.Devices.DMX/RGB.NET.Devices.DMX.csproj.DotSettings index acc5fca7..a54436d3 100644 --- a/RGB.NET.Devices.DMX/RGB.NET.Devices.DMX.csproj.DotSettings +++ b/RGB.NET.Devices.DMX/RGB.NET.Devices.DMX.csproj.DotSettings @@ -1,2 +1,3 @@  - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs index ca6561e6..6ec81424 100644 --- a/RGB.NET.Devices.Debug/DebugDeviceProvider.cs +++ b/RGB.NET.Devices.Debug/DebugDeviceProvider.cs @@ -3,108 +3,75 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using RGB.NET.Core; +using RGB.NET.Layout; -namespace RGB.NET.Devices.Debug +namespace RGB.NET.Devices.Debug; + +/// +/// +/// Represents a device provider responsible for debug devices. +/// +public class DebugDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static DebugDeviceProvider? _instance; /// - /// Represents a device provider responsible for debug devices. + /// Gets the singleton instance. /// - public class DebugDeviceProvider : IRGBDeviceProvider + public static DebugDeviceProvider Instance => _instance ?? new DebugDeviceProvider(); + + private List<(IDeviceLayout layout, Action>? updateLedsAction)> _fakeDeviceDefinitions = new(); + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public DebugDeviceProvider() { - #region Properties & Fields - - private static DebugDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static DebugDeviceProvider Instance => _instance ?? new DebugDeviceProvider(); - - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - public bool HasExclusiveAccess { get; private set; } - - private List<(string layout, string imageLayout, Func> syncBackFunc, Action> updateLedsAction)> _fakeDeviceDefinitions - = new List<(string layout, string imageLayout, Func> syncBackFunc, Action> updateLedsAction)>(); - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public DebugDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(DebugDeviceProvider)}"); - _instance = this; - } - - #endregion - - #region Methods - - /// - /// Adds a new fake device definition. - /// - /// The path of the layout file to be used. - /// The image-layout to load. - /// A function emulating device syncback. - /// A action emulating led-updates. - public void AddFakeDeviceDefinition(string layout, string imageLayout, Func> syncBackFunc = null, Action> updateLedsAction = null) - => _fakeDeviceDefinitions.Add((layout, imageLayout, syncBackFunc, updateLedsAction)); - - /// - /// Removes all previously added fake device definitions. - /// - public void ClearFakeDeviceDefinitions() => _fakeDeviceDefinitions.Clear(); - - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - IsInitialized = false; - try - { - HasExclusiveAccess = exclusiveAccessIfPossible; - - List devices = new List(); - foreach ((string layout, string imageLayout, Func> syncBackFunc, Action> updateLedsAction) in _fakeDeviceDefinitions) - { - DebugRGBDevice device = new DebugRGBDevice(layout, syncBackFunc, updateLedsAction); - device.Initialize(layout, imageLayout); - devices.Add(device); - } - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - - return true; - } - catch - { - if (throwExceptions) throw; - return false; - } - } - - /// - public void ResetDevices() - { } - - /// - public void Dispose() - { - _fakeDeviceDefinitions.Clear(); - } - - #endregion + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(DebugDeviceProvider)}"); + _instance = this; } -} + + #endregion + + #region Methods + + /// + /// Adds a new fake device definition. + /// + /// The path of the layout file to be used. + /// A action emulating led-updates. + public void AddFakeDeviceDefinition(IDeviceLayout layout, Action>? updateLedsAction = null) + => _fakeDeviceDefinitions.Add((layout, updateLedsAction)); + + /// + /// Removes all previously added fake device definitions. + /// + public void ClearFakeDeviceDefinitions() => _fakeDeviceDefinitions.Clear(); + + /// + protected override void InitializeSDK() { } + + /// + protected override IEnumerable LoadDevices() + { + foreach ((IDeviceLayout layout, Action>? updateLedsAction) in _fakeDeviceDefinitions) + yield return new DebugRGBDevice(layout, updateLedsAction); + } + + /// + public override void Dispose() + { + base.Dispose(); + + _fakeDeviceDefinitions.Clear(); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Debug/DebugDeviceProviderLoader.cs b/RGB.NET.Devices.Debug/DebugDeviceProviderLoader.cs deleted file mode 100644 index 819a0841..00000000 --- a/RGB.NET.Devices.Debug/DebugDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Debug -{ - /// - /// Represents a device provider loaded used to dynamically load debug devices into an application. - /// - public class DebugDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => true; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => DebugDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs b/RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs new file mode 100644 index 00000000..ccd03447 --- /dev/null +++ b/RGB.NET.Devices.Debug/DebugDeviceUpdateQueue.cs @@ -0,0 +1,21 @@ +using System; +using RGB.NET.Core; + +namespace RGB.NET.Devices.Debug; + +internal class DebugDeviceUpdateQueue : UpdateQueue +{ + #region Constructors + + public DebugDeviceUpdateQueue() + : base(new DeviceUpdateTrigger()) + { } + + #endregion + + #region Methods + + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Debug/DebugRGBDevice.cs b/RGB.NET.Devices.Debug/DebugRGBDevice.cs index 174e7fd0..35d1765c 100644 --- a/RGB.NET.Devices.Debug/DebugRGBDevice.cs +++ b/RGB.NET.Devices.Debug/DebugRGBDevice.cs @@ -1,71 +1,46 @@ using System; using System.Collections.Generic; using RGB.NET.Core; -using RGB.NET.Core.Layout; +using RGB.NET.Layout; -namespace RGB.NET.Devices.Debug +namespace RGB.NET.Devices.Debug; + +/// +/// +/// Represents a debug device. +/// +public class DebugRGBDevice : AbstractRGBDevice, IUnknownDevice { - /// + #region Properties & Fields + /// - /// Represents a debug device. + /// Gets the layour used to describe this debug device. /// - public class DebugRGBDevice : AbstractRGBDevice, IUnknownDevice - { - #region Properties & Fields - - /// - public override DebugRGBDeviceInfo DeviceInfo { get; } - - /// - /// Gets the path of the layout used to mock this - /// - public string LayoutPath { get; } - - private Func> _syncBackFunc; - private Action> _updateLedsAction; - - #endregion + public IDeviceLayout Layout { get; } - #region Constructors - /// - /// Internal constructor of . - /// - internal DebugRGBDevice(string layoutPath, Func> syncBackFunc = null, Action> updateLedsAction = null) - { - this.LayoutPath = layoutPath; - this._syncBackFunc = syncBackFunc; - this._updateLedsAction = updateLedsAction; + private Action>? _updateLedsAction; - DeviceLayout layout = DeviceLayout.Load(layoutPath); - DeviceInfo = new DebugRGBDeviceInfo(layout.Type, layout.Vendor, layout.Model, layout.Lighting, syncBackFunc != null); - } + #endregion - #endregion - - #region Methods + #region Constructors + /// + /// Internal constructor of . + /// + internal DebugRGBDevice(IDeviceLayout layout, Action>? updateLedsAction = null) + : base(new DebugRGBDeviceInfo(layout.Type, layout.Vendor ?? "RGB.NET", layout.Model ?? "Debug", layout.CustomData), new DebugDeviceUpdateQueue()) + { + this.Layout = layout; + this._updateLedsAction = updateLedsAction; - internal void Initialize(string layoutPath, string imageLayout) => ApplyLayoutFromFile(layoutPath, imageLayout, true); + Layout.ApplyTo(this, true); + } - /// - public override void SyncBack() - { - try - { - Dictionary syncBackValues = _syncBackFunc?.Invoke(); - if (syncBackValues == null) return; + #endregion - foreach (KeyValuePair value in syncBackValues) - { - Led led = ((IRGBDevice)this)[value.Key]; - SetLedColorWithoutRequest(led, value.Value); - } - } - catch {/* idc that's not my fault ... */} - } + #region Methods - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => _updateLedsAction?.Invoke(ledsToUpdate); + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => _updateLedsAction?.Invoke(ledsToUpdate); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Debug/DebugRGBDeviceInfo.cs b/RGB.NET.Devices.Debug/DebugRGBDeviceInfo.cs index e3e62053..d724e366 100644 --- a/RGB.NET.Devices.Debug/DebugRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Debug/DebugRGBDeviceInfo.cs @@ -1,60 +1,50 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Debug -{ - /// - /// - /// Represents device information for a />. - /// - public class DebugRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Devices.Debug; - /// - public RGBDeviceType DeviceType { get; } - - /// - public string DeviceName { get; } - - /// - public string Manufacturer { get; } +/// +/// +/// Represents device information for a />. +/// +public class DebugRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public string Model { get; } + /// + public RGBDeviceType DeviceType { get; } - /// - public RGBDeviceLighting Lighting { get; } + /// + public string DeviceName { get; } - /// - public bool SupportsSyncBack { get; } + /// + public string Manufacturer { get; } - /// - public Uri Image { get; set; } + /// + public string Model { get; } - #endregion + /// + public object? LayoutMetadata { get; set; } - #region Constructors + #endregion - /// - /// Internal constructor of . - /// - /// The of the device. - /// The manufacturer of the device. - /// The model of the device. - /// The of the device. - /// True if the device supports syncback; false if not. - internal DebugRGBDeviceInfo(RGBDeviceType deviceType, string manufacturer, string model, RGBDeviceLighting lighting, bool supportsSyncBack, string deviceName = null) - { - this.DeviceType = deviceType; - this.Manufacturer = manufacturer; - this.Model = model; - this.Lighting = lighting; - this.SupportsSyncBack = supportsSyncBack; + #region Constructors - DeviceName = deviceName ?? $"{Manufacturer} {Model}"; - } + /// + /// Internal constructor of . + /// + /// The of the device. + /// The manufacturer of the device. + /// The model of the device. + /// Some custom data for this device provided by the layout. + internal DebugRGBDeviceInfo(RGBDeviceType deviceType, string manufacturer, string model, object? customData) + { + this.DeviceType = deviceType; + this.Manufacturer = manufacturer; + this.Model = model; + this.LayoutMetadata = customData; - #endregion + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Debug/README.md b/RGB.NET.Devices.Debug/README.md new file mode 100644 index 00000000..621def29 --- /dev/null +++ b/RGB.NET.Devices.Debug/README.md @@ -0,0 +1,16 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for Debug-Devices. + +> This provider is only for debug purposes! + +## Usage +This provider does not load anything by default and requires additional configuration to work. + +```csharp +// Add as many debug devices as you like +DebugDeviceProvider.Instance.AddFakeDeviceDefinition(DeviceLayout.Load("")); + +surface.Load(DebugDeviceProvider.Instance); +``` + +# Required SDK +This provider does not require an additional SDK. diff --git a/RGB.NET.Devices.Debug/RGB.NET.Devices.Debug.csproj b/RGB.NET.Devices.Debug/RGB.NET.Devices.Debug.csproj index 0ad819b9..f4edaaed 100644 --- a/RGB.NET.Devices.Debug/RGB.NET.Devices.Debug.csproj +++ b/RGB.NET.Devices.Debug/RGB.NET.Devices.Debug.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.Debug Debug-Device-Implementations of RGB.NET Debug-Device-Implementations of RGB.NET, a C# (.NET) library - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,36 +35,29 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + - - + + + \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Enum/LogitechDeviceCaps.cs b/RGB.NET.Devices.Logitech/Enum/LogitechDeviceCaps.cs index 0d722427..ee6800d5 100644 --- a/RGB.NET.Devices.Logitech/Enum/LogitechDeviceCaps.cs +++ b/RGB.NET.Devices.Logitech/Enum/LogitechDeviceCaps.cs @@ -4,15 +4,14 @@ #pragma warning disable 1591 // Missing XML comment for publicly visible type or member -namespace RGB.NET.Devices.Logitech +namespace RGB.NET.Devices.Logitech; + +[Flags] +public enum LogitechDeviceCaps { - [Flags] - public enum LogitechDeviceCaps - { - None = 0, - Monochrome = 1 << 0, - DeviceRGB = 1 << 1, - PerKeyRGB = 1 << 2, - All = Monochrome | DeviceRGB | PerKeyRGB - } -} + None = 0, + Monochrome = 1 << 0, + DeviceRGB = 1 << 1, + PerKeyRGB = 1 << 2, + All = Monochrome | DeviceRGB | PerKeyRGB +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Enum/LogitechDeviceType.cs b/RGB.NET.Devices.Logitech/Enum/LogitechDeviceType.cs index 6697b2dd..22873f5e 100644 --- a/RGB.NET.Devices.Logitech/Enum/LogitechDeviceType.cs +++ b/RGB.NET.Devices.Logitech/Enum/LogitechDeviceType.cs @@ -1,11 +1,15 @@ -namespace RGB.NET.Devices.Logitech +#pragma warning disable 1591 + +namespace RGB.NET.Devices.Logitech; + +/// +/// Contains list of available logitech device types. +/// +public enum LogitechDeviceType { - public enum LogitechDeviceType - { - Keyboard = 0x0, - Mouse = 0x3, - Mousemat = 0x4, - Headset = 0x8, - Speaker = 0xE - } -} + Keyboard = 0x0, + Mouse = 0x3, + Mousemat = 0x4, + Headset = 0x8, + Speaker = 0xE +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Enum/LogitechLedId.cs b/RGB.NET.Devices.Logitech/Enum/LogitechLedId.cs index 60d7103d..3bd837b9 100644 --- a/RGB.NET.Devices.Logitech/Enum/LogitechLedId.cs +++ b/RGB.NET.Devices.Logitech/Enum/LogitechLedId.cs @@ -1,138 +1,128 @@ // ReSharper disable InconsistentNaming +#pragma warning disable 1591 -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member +namespace RGB.NET.Devices.Logitech; -namespace RGB.NET.Devices.Logitech +/// +/// Contains a list of Logitech LED IDs +/// +public enum LogitechLedId { - /// - /// Contains list of all LEDs available for all logitech devices. - /// - public enum LogitechLedId - { - Invalid = 0, - ESC = 0x01, - F1 = 0x3b, - F2 = 0x3c, - F3 = 0x3d, - F4 = 0x3e, - F5 = 0x3f, - F6 = 0x40, - F7 = 0x41, - F8 = 0x42, - F9 = 0x43, - F10 = 0x44, - F11 = 0x57, - F12 = 0x58, - PRINT_SCREEN = 0x137, - SCROLL_LOCK = 0x46, - PAUSE_BREAK = 0x45, - - TILDE = 0x29, - ONE = 0x02, - TWO = 0x03, - THREE = 0x04, - FOUR = 0x05, - FIVE = 0x06, - SIX = 0x07, - SEVEN = 0x08, - EIGHT = 0x09, - NINE = 0x0A, - ZERO = 0x0B, - MINUS = 0x0C, - EQUALS = 0x0D, - BACKSPACE = 0x0E, - INSERT = 0x152, - HOME = 0x147, - PAGE_UP = 0x149, - NUM_LOCK = 0x145, - NUM_SLASH = 0x135, - NUM_ASTERISK = 0x37, - NUM_MINUS = 0x4A, - - TAB = 0x0F, - Q = 0x10, - W = 0x11, - E = 0x12, - R = 0x13, - T = 0x14, - Y = 0x15, - U = 0x16, - I = 0x17, - O = 0x18, - P = 0x19, - OPEN_BRACKET = 0x1A, - CLOSE_BRACKET = 0x1B, - BACKSLASH = 0x2B, - KEYBOARD_DELETE = 0x153, - END = 0x14F, - PAGE_DOWN = 0x151, - NUM_SEVEN = 0x47, - NUM_EIGHT = 0x48, - NUM_NINE = 0x49, - NUM_PLUS = 0x4E, - - CAPS_LOCK = 0x3A, - A = 0x1E, - S = 0x1F, - D = 0x20, - F = 0x21, - G = 0x22, - H = 0x23, - J = 0x24, - K = 0x25, - L = 0x26, - SEMICOLON = 0x27, - APOSTROPHE = 0x28, - NonUsTilde = 0xFF, //TODO DarthAffe 26.03.2017: Find the real ID/Name of this key - it's not documented ... - ENTER = 0x1C, - NUM_FOUR = 0x4B, - NUM_FIVE = 0x4C, - NUM_SIX = 0x4D, - - LEFT_SHIFT = 0x2A, - Z = 0x2C, - X = 0x2D, - C = 0x2E, - V = 0x2F, - B = 0x30, - N = 0x31, - M = 0x32, - COMMA = 0x33, - PERIOD = 0x34, - FORWARD_SLASH = 0x35, - RIGHT_SHIFT = 0x36, - ARROW_UP = 0x148, - NUM_ONE = 0x4F, - NUM_TWO = 0x50, - NUM_THREE = 0x51, - NUM_ENTER = 0x11C, - - LEFT_CONTROL = 0x1D, - LEFT_WINDOWS = 0x15B, - LEFT_ALT = 0x38, - SPACE = 0x39, - RIGHT_ALT = 0x138, - RIGHT_WINDOWS = 0x15C, - APPLICATION_SELECT = 0x15D, - RIGHT_CONTROL = 0x11D, - ARROW_LEFT = 0x14B, - ARROW_DOWN = 0x150, - ARROW_RIGHT = 0x14D, - NUM_ZERO = 0x52, - NUM_PERIOD = 0x53, - - G_1 = 0xFFF1, - G_2 = 0xFFF2, - G_3 = 0xFFF3, - G_4 = 0xFFF4, - G_5 = 0xFFF5, - G_6 = 0xFFF6, - G_7 = 0xFFF7, - G_8 = 0xFFF8, - G_9 = 0xFFF9, - G_LOGO = 0xFFFF1, - G_BADGE = 0xFFFF2, - - DEVICE = 0xFFFFFFF - } -} + ESC = 0x01, + F1 = 0x3b, + F2 = 0x3c, + F3 = 0x3d, + F4 = 0x3e, + F5 = 0x3f, + F6 = 0x40, + F7 = 0x41, + F8 = 0x42, + F9 = 0x43, + F10 = 0x44, + F11 = 0x57, + F12 = 0x58, + PRINT_SCREEN = 0x137, + SCROLL_LOCK = 0x46, + PAUSE_BREAK = 0x145, + TILDE = 0x29, + ONE = 0x02, + TWO = 0x03, + THREE = 0x04, + FOUR = 0x05, + FIVE = 0x06, + SIX = 0x07, + SEVEN = 0x08, + EIGHT = 0x09, + NINE = 0x0A, + ZERO = 0x0B, + MINUS = 0x0C, + EQUALS = 0x0D, + BACKSPACE = 0x0E, + INSERT = 0x152, + HOME = 0x147, + PAGE_UP = 0x149, + NUM_LOCK = 0x45, + NUM_SLASH = 0x135, + NUM_ASTERISK = 0x37, + NUM_MINUS = 0x4A, + TAB = 0x0F, + Q = 0x10, + W = 0x11, + E = 0x12, + R = 0x13, + T = 0x14, + Y = 0x15, + U = 0x16, + I = 0x17, + O = 0x18, + P = 0x19, + OPEN_BRACKET = 0x1A, + CLOSE_BRACKET = 0x1B, + BACKSLASH = 0x2B, + KEYBOARD_DELETE = 0x153, + END = 0x14F, + PAGE_DOWN = 0x151, + NUM_SEVEN = 0x47, + NUM_EIGHT = 0x48, + NUM_NINE = 0x49, + NUM_PLUS = 0x4E, + CAPS_LOCK = 0x3A, + A = 0x1E, + S = 0x1F, + D = 0x20, + F = 0x21, + G = 0x22, + H = 0x23, + J = 0x24, + K = 0x25, + L = 0x26, + SEMICOLON = 0x27, + APOSTROPHE = 0x28, + ENTER = 0x1C, + NUM_FOUR = 0x4B, + NUM_FIVE = 0x4C, + NUM_SIX = 0x4D, + LEFT_SHIFT = 0x2A, + Z = 0x2C, + X = 0x2D, + C = 0x2E, + V = 0x2F, + B = 0x30, + N = 0x31, + M = 0x32, + COMMA = 0x33, + PERIOD = 0x34, + FORWARD_SLASH = 0x35, + RIGHT_SHIFT = 0x36, + ARROW_UP = 0x148, + NUM_ONE = 0x4F, + NUM_TWO = 0x50, + NUM_THREE = 0x51, + NUM_ENTER = 0x11C, + LEFT_CONTROL = 0x1D, + LEFT_WINDOWS = 0x15B, + LEFT_ALT = 0x38, + SPACE = 0x39, + RIGHT_ALT = 0x138, + RIGHT_WINDOWS = 0x15C, + APPLICATION_SELECT = 0x15D, + RIGHT_CONTROL = 0x11D, + ARROW_LEFT = 0x14B, + ARROW_DOWN = 0x150, + ARROW_RIGHT = 0x14D, + NUM_ZERO = 0x52, + NUM_PERIOD = 0x53, + ISO_BACKSLASH = 0x56, + ISO_TILDE = 0x5D, + G_1 = 0xFFF1, + G_2 = 0xFFF2, + G_3 = 0xFFF3, + G_4 = 0xFFF4, + G_5 = 0xFFF5, + G_6 = 0xFFF6, + G_7 = 0xFFF7, + G_8 = 0xFFF8, + G_9 = 0xFFF9, + G_LOGO = 0xFFFF1, + G_BADGE = 0xFFFF2 +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Enum/LogitechLogicalKeyboardLayout.cs b/RGB.NET.Devices.Logitech/Enum/LogitechLogicalKeyboardLayout.cs index 808c12d9..60131167 100644 --- a/RGB.NET.Devices.Logitech/Enum/LogitechLogicalKeyboardLayout.cs +++ b/RGB.NET.Devices.Logitech/Enum/LogitechLogicalKeyboardLayout.cs @@ -3,30 +3,29 @@ #pragma warning disable 1591 // Missing XML comment for publicly visible type or member -namespace RGB.NET.Devices.Logitech +namespace RGB.NET.Devices.Logitech; + +/// +/// Contains list of available logical layouts for logitech keyboards. +/// +public enum LogitechLogicalKeyboardLayout { - /// - /// Contains list of available logical layouts for logitech keyboards. - /// - public enum LogitechLogicalKeyboardLayout - { - US_Int = 1, - NA = 2, - EU = 3, - UK = 4, - BE = 5, - BR = 6, - CH = 7, - CN = 8, - DE = 9, - ES = 10, - FR = 11, - IT = 12, - ND = 13, - RU = 14, - JP = 15, - KR = 16, - TW = 17, - MEX = 18 - }; -} + US_Int = 1, + NA = 2, + EU = 3, + UK = 4, + BE = 5, + BR = 6, + CH = 7, + CN = 8, + DE = 9, + ES = 10, + FR = 11, + IT = 12, + ND = 13, + RU = 14, + JP = 15, + KR = 16, + TW = 17, + MEX = 18 +}; \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Enum/LogitechPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Logitech/Enum/LogitechPhysicalKeyboardLayout.cs index 95e608e5..dbeae0a9 100644 --- a/RGB.NET.Devices.Logitech/Enum/LogitechPhysicalKeyboardLayout.cs +++ b/RGB.NET.Devices.Logitech/Enum/LogitechPhysicalKeyboardLayout.cs @@ -1,36 +1,35 @@ // ReSharper disable UnusedMember.Global // ReSharper disable InconsistentNaming -namespace RGB.NET.Devices.Logitech +namespace RGB.NET.Devices.Logitech; + +/// +/// Contains list of available physical layouts for logitech keyboards. +/// +public enum LogitechPhysicalKeyboardLayout { /// - /// Contains list of available physical layouts for logitech keyboards. + /// US-Keyboard /// - public enum LogitechPhysicalKeyboardLayout - { - /// - /// US-Keyboard - /// - US = 1, + US = 1, - /// - /// UK-Keyboard - /// - UK = 2, + /// + /// UK-Keyboard + /// + UK = 2, - /// - /// BR-Keyboard - /// - BR = 3, + /// + /// BR-Keyboard + /// + BR = 3, - /// - /// JP-Keyboard - /// - JP = 4, + /// + /// JP-Keyboard + /// + JP = 4, - /// - /// KR-Keyboard - /// - KR = 5 - } -} + /// + /// KR-Keyboard + /// + KR = 5 +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs b/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs index 4c8e2605..9ff7cc90 100644 --- a/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/Generic/ILogitechRGBDevice.cs @@ -1,12 +1,9 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Logitech -{ - /// - /// Represents a logitech RGB-device. - /// - internal interface ILogitechRGBDevice : IRGBDevice - { - void Initialize(UpdateQueue updateQueue); - } -} +namespace RGB.NET.Devices.Logitech; + +/// +/// Represents a logitech RGB-device. +/// +public interface ILogitechRGBDevice : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Generic/LedMappings.cs b/RGB.NET.Devices.Logitech/Generic/LedMappings.cs new file mode 100644 index 00000000..367b0f00 --- /dev/null +++ b/RGB.NET.Devices.Logitech/Generic/LedMappings.cs @@ -0,0 +1,342 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.Logitech; + +/// +/// Contains mappings for to . +/// +public static class LedMappings +{ + /// + /// Gets the mapping for per key devices. + /// + public static LedMapping PerKey { get; } = new() + { + { LedId.Keyboard_Escape, LogitechLedId.ESC }, + { LedId.Keyboard_F1, LogitechLedId.F1 }, + { LedId.Keyboard_F2, LogitechLedId.F2 }, + { LedId.Keyboard_F3, LogitechLedId.F3 }, + { LedId.Keyboard_F4, LogitechLedId.F4 }, + { LedId.Keyboard_F5, LogitechLedId.F5 }, + { LedId.Keyboard_F6, LogitechLedId.F6 }, + { LedId.Keyboard_F7, LogitechLedId.F7 }, + { LedId.Keyboard_F8, LogitechLedId.F8 }, + { LedId.Keyboard_F9, LogitechLedId.F9 }, + { LedId.Keyboard_F10, LogitechLedId.F10 }, + { LedId.Keyboard_F11, LogitechLedId.F11 }, + { LedId.Keyboard_F12, LogitechLedId.F12 }, + { LedId.Keyboard_PrintScreen, LogitechLedId.PRINT_SCREEN }, + { LedId.Keyboard_ScrollLock, LogitechLedId.SCROLL_LOCK }, + { LedId.Keyboard_PauseBreak, LogitechLedId.PAUSE_BREAK }, + + { LedId.Keyboard_GraveAccentAndTilde, LogitechLedId.TILDE }, + { LedId.Keyboard_1, LogitechLedId.ONE }, + { LedId.Keyboard_2, LogitechLedId.TWO }, + { LedId.Keyboard_3, LogitechLedId.THREE }, + { LedId.Keyboard_4, LogitechLedId.FOUR }, + { LedId.Keyboard_5, LogitechLedId.FIVE }, + { LedId.Keyboard_6, LogitechLedId.SIX }, + { LedId.Keyboard_7, LogitechLedId.SEVEN }, + { LedId.Keyboard_8, LogitechLedId.EIGHT }, + { LedId.Keyboard_9, LogitechLedId.NINE }, + { LedId.Keyboard_0, LogitechLedId.ZERO }, + { LedId.Keyboard_MinusAndUnderscore, LogitechLedId.MINUS }, + { LedId.Keyboard_EqualsAndPlus, LogitechLedId.EQUALS }, + { LedId.Keyboard_Backspace, LogitechLedId.BACKSPACE }, + { LedId.Keyboard_Insert, LogitechLedId.INSERT }, + { LedId.Keyboard_Home, LogitechLedId.HOME }, + { LedId.Keyboard_PageUp, LogitechLedId.PAGE_UP }, + { LedId.Keyboard_NumLock, LogitechLedId.NUM_LOCK }, + { LedId.Keyboard_NumSlash, LogitechLedId.NUM_SLASH }, + { LedId.Keyboard_NumAsterisk, LogitechLedId.NUM_ASTERISK }, + { LedId.Keyboard_NumMinus, LogitechLedId.NUM_MINUS }, + + { LedId.Keyboard_Tab, LogitechLedId.TAB }, + { LedId.Keyboard_Q, LogitechLedId.Q }, + { LedId.Keyboard_W, LogitechLedId.W }, + { LedId.Keyboard_E, LogitechLedId.E }, + { LedId.Keyboard_R, LogitechLedId.R }, + { LedId.Keyboard_T, LogitechLedId.T }, + { LedId.Keyboard_Y, LogitechLedId.Y }, + { LedId.Keyboard_U, LogitechLedId.U }, + { LedId.Keyboard_I, LogitechLedId.I }, + { LedId.Keyboard_O, LogitechLedId.O }, + { LedId.Keyboard_P, LogitechLedId.P }, + { LedId.Keyboard_BracketLeft, LogitechLedId.OPEN_BRACKET }, + { LedId.Keyboard_BracketRight, LogitechLedId.CLOSE_BRACKET }, + { LedId.Keyboard_Backslash, LogitechLedId.BACKSLASH }, + { LedId.Keyboard_Delete, LogitechLedId.KEYBOARD_DELETE }, + { LedId.Keyboard_End, LogitechLedId.END }, + { LedId.Keyboard_PageDown, LogitechLedId.PAGE_DOWN }, + { LedId.Keyboard_Num7, LogitechLedId.NUM_SEVEN }, + { LedId.Keyboard_Num8, LogitechLedId.NUM_EIGHT }, + { LedId.Keyboard_Num9, LogitechLedId.NUM_NINE }, + { LedId.Keyboard_NumPlus, LogitechLedId.NUM_PLUS }, + + { LedId.Keyboard_CapsLock, LogitechLedId.CAPS_LOCK }, + { LedId.Keyboard_A, LogitechLedId.A }, + { LedId.Keyboard_S, LogitechLedId.S }, + { LedId.Keyboard_D, LogitechLedId.D }, + { LedId.Keyboard_F, LogitechLedId.F }, + { LedId.Keyboard_G, LogitechLedId.G }, + { LedId.Keyboard_H, LogitechLedId.H }, + { LedId.Keyboard_J, LogitechLedId.J }, + { LedId.Keyboard_K, LogitechLedId.K }, + { LedId.Keyboard_L, LogitechLedId.L }, + { LedId.Keyboard_SemicolonAndColon, LogitechLedId.SEMICOLON }, + { LedId.Keyboard_ApostropheAndDoubleQuote, LogitechLedId.APOSTROPHE }, + { LedId.Keyboard_NonUsTilde, LogitechLedId.ISO_TILDE }, + { LedId.Keyboard_Enter, LogitechLedId.ENTER }, + { LedId.Keyboard_Num4, LogitechLedId.NUM_FOUR }, + { LedId.Keyboard_Num5, LogitechLedId.NUM_FIVE }, + { LedId.Keyboard_Num6, LogitechLedId.NUM_SIX }, + + { LedId.Keyboard_LeftShift, LogitechLedId.LEFT_SHIFT }, + { LedId.Keyboard_NonUsBackslash, LogitechLedId.ISO_BACKSLASH }, + { LedId.Keyboard_Z, LogitechLedId.Z }, + { LedId.Keyboard_X, LogitechLedId.X }, + { LedId.Keyboard_C, LogitechLedId.C }, + { LedId.Keyboard_V, LogitechLedId.V }, + { LedId.Keyboard_B, LogitechLedId.B }, + { LedId.Keyboard_N, LogitechLedId.N }, + { LedId.Keyboard_M, LogitechLedId.M }, + { LedId.Keyboard_CommaAndLessThan, LogitechLedId.COMMA }, + { LedId.Keyboard_PeriodAndBiggerThan, LogitechLedId.PERIOD }, + { LedId.Keyboard_SlashAndQuestionMark, LogitechLedId.FORWARD_SLASH }, + { LedId.Keyboard_RightShift, LogitechLedId.RIGHT_SHIFT }, + { LedId.Keyboard_ArrowUp, LogitechLedId.ARROW_UP }, + { LedId.Keyboard_Num1, LogitechLedId.NUM_ONE }, + { LedId.Keyboard_Num2, LogitechLedId.NUM_TWO }, + { LedId.Keyboard_Num3, LogitechLedId.NUM_THREE }, + { LedId.Keyboard_NumEnter, LogitechLedId.NUM_ENTER }, + + { LedId.Keyboard_LeftCtrl, LogitechLedId.LEFT_CONTROL }, + { LedId.Keyboard_LeftGui, LogitechLedId.LEFT_WINDOWS }, + { LedId.Keyboard_LeftAlt, LogitechLedId.LEFT_ALT }, + { LedId.Keyboard_Space, LogitechLedId.SPACE }, + { LedId.Keyboard_RightAlt, LogitechLedId.RIGHT_ALT }, + { LedId.Keyboard_RightGui, LogitechLedId.RIGHT_WINDOWS }, + { LedId.Keyboard_Application, LogitechLedId.APPLICATION_SELECT }, + { LedId.Keyboard_RightCtrl, LogitechLedId.RIGHT_CONTROL }, + { LedId.Keyboard_ArrowLeft, LogitechLedId.ARROW_LEFT }, + { LedId.Keyboard_ArrowDown, LogitechLedId.ARROW_DOWN }, + { LedId.Keyboard_ArrowRight, LogitechLedId.ARROW_RIGHT }, + { LedId.Keyboard_Num0, LogitechLedId.NUM_ZERO }, + { LedId.Keyboard_NumPeriodAndDelete, LogitechLedId.NUM_PERIOD }, + + { LedId.Keyboard_Programmable1, LogitechLedId.G_1 }, + { LedId.Keyboard_Programmable2, LogitechLedId.G_2 }, + { LedId.Keyboard_Programmable3, LogitechLedId.G_3 }, + { LedId.Keyboard_Programmable4, LogitechLedId.G_4 }, + { LedId.Keyboard_Programmable5, LogitechLedId.G_5 }, + { LedId.Keyboard_Programmable6, LogitechLedId.G_6 }, + { LedId.Keyboard_Programmable7, LogitechLedId.G_7 }, + { LedId.Keyboard_Programmable8, LogitechLedId.G_8 }, + { LedId.Keyboard_Programmable9, LogitechLedId.G_9 }, + { LedId.Logo, LogitechLedId.G_LOGO }, + { LedId.Keyboard_Custom1, LogitechLedId.G_BADGE }, + }; + + /// + /// Gets the mapping for per device devices. + /// + public static LedMapping Device { get; } = new() + { + { LedId.Custom1, 0 } + }; + + /// + /// Gets the mapping for per zone keyboards. + /// + public static LedMapping ZoneKeyboard { get; } = new() + { + { LedId.Keyboard_Programmable1, 0 }, + { LedId.Keyboard_Programmable2, 1 }, + { LedId.Keyboard_Programmable3, 2 }, + { LedId.Keyboard_Programmable4, 3 }, + { LedId.Keyboard_Programmable5, 4 }, + { LedId.Keyboard_Programmable6, 5 }, + { LedId.Keyboard_Programmable7, 6 }, + { LedId.Keyboard_Programmable8, 7 }, + { LedId.Keyboard_Programmable9, 8 }, + { LedId.Keyboard_Programmable10, 9 }, + { LedId.Keyboard_Programmable11, 10 }, + { LedId.Keyboard_Programmable12, 11 }, + { LedId.Keyboard_Programmable13, 12 }, + { LedId.Keyboard_Programmable14, 13 }, + { LedId.Keyboard_Programmable15, 14 }, + { LedId.Keyboard_Programmable16, 15 }, + { LedId.Keyboard_Programmable17, 16 }, + { LedId.Keyboard_Programmable18, 17 }, + { LedId.Keyboard_Programmable19, 18 }, + { LedId.Keyboard_Programmable20, 19 }, + { LedId.Keyboard_Programmable21, 20 }, + { LedId.Keyboard_Programmable22, 21 }, + { LedId.Keyboard_Programmable23, 22 }, + { LedId.Keyboard_Programmable24, 23 }, + { LedId.Keyboard_Programmable25, 24 }, + { LedId.Keyboard_Programmable26, 25 }, + { LedId.Keyboard_Programmable27, 26 }, + { LedId.Keyboard_Programmable28, 27 }, + { LedId.Keyboard_Programmable29, 28 }, + { LedId.Keyboard_Programmable30, 29 }, + { LedId.Keyboard_Programmable31, 30 }, + { LedId.Keyboard_Programmable32, 31 }, + }; + + /// + /// Gets the mapping for per zone mice. + /// + public static LedMapping ZoneMouse { get; } = new() + { + { LedId.Mouse1, 0 }, + { LedId.Mouse2, 1 }, + { LedId.Mouse3, 2 }, + { LedId.Mouse4, 3 }, + { LedId.Mouse5, 4 }, + { LedId.Mouse6, 5 }, + { LedId.Mouse7, 6 }, + { LedId.Mouse8, 7 }, + { LedId.Mouse9, 8 }, + { LedId.Mouse10, 9 }, + { LedId.Mouse11, 10 }, + { LedId.Mouse12, 11 }, + { LedId.Mouse13, 12 }, + { LedId.Mouse14, 13 }, + { LedId.Mouse15, 14 }, + { LedId.Mouse16, 15 }, + { LedId.Mouse17, 16 }, + { LedId.Mouse18, 17 }, + { LedId.Mouse19, 18 }, + { LedId.Mouse20, 19 }, + { LedId.Mouse21, 20 }, + { LedId.Mouse22, 21 }, + { LedId.Mouse23, 22 }, + { LedId.Mouse24, 23 }, + { LedId.Mouse25, 24 }, + { LedId.Mouse26, 25 }, + { LedId.Mouse27, 26 }, + { LedId.Mouse28, 27 }, + { LedId.Mouse29, 28 }, + { LedId.Mouse30, 29 }, + { LedId.Mouse31, 30 }, + { LedId.Mouse32, 31 }, + }; + + /// + /// Gets the mapping for per zone headsets. + /// + public static LedMapping ZoneHeadset { get; } = new() + { + { LedId.Headset1, 0 }, + { LedId.Headset2, 1 }, + { LedId.Headset3, 2 }, + { LedId.Headset4, 3 }, + { LedId.Headset5, 4 }, + { LedId.Headset6, 5 }, + { LedId.Headset7, 6 }, + { LedId.Headset8, 7 }, + { LedId.Headset9, 8 }, + { LedId.Headset10, 9 }, + { LedId.Headset11, 10 }, + { LedId.Headset12, 11 }, + { LedId.Headset13, 12 }, + { LedId.Headset14, 13 }, + { LedId.Headset15, 14 }, + { LedId.Headset16, 15 }, + { LedId.Headset17, 16 }, + { LedId.Headset18, 17 }, + { LedId.Headset19, 18 }, + { LedId.Headset20, 19 }, + { LedId.Headset21, 20 }, + { LedId.Headset22, 21 }, + { LedId.Headset23, 22 }, + { LedId.Headset24, 23 }, + { LedId.Headset25, 24 }, + { LedId.Headset26, 25 }, + { LedId.Headset27, 26 }, + { LedId.Headset28, 27 }, + { LedId.Headset29, 28 }, + { LedId.Headset30, 29 }, + { LedId.Headset31, 30 }, + { LedId.Headset32, 31 }, + }; + + /// + /// Gets the mapping for per zone mousepads. + /// + public static LedMapping ZoneMousepad { get; } = new() + { + { LedId.Mousepad1, 0 }, + { LedId.Mousepad2, 1 }, + { LedId.Mousepad3, 2 }, + { LedId.Mousepad4, 3 }, + { LedId.Mousepad5, 4 }, + { LedId.Mousepad6, 5 }, + { LedId.Mousepad7, 6 }, + { LedId.Mousepad8, 7 }, + { LedId.Mousepad9, 8 }, + { LedId.Mousepad10, 9 }, + { LedId.Mousepad11, 10 }, + { LedId.Mousepad12, 11 }, + { LedId.Mousepad13, 12 }, + { LedId.Mousepad14, 13 }, + { LedId.Mousepad15, 14 }, + { LedId.Mousepad16, 15 }, + { LedId.Mousepad17, 16 }, + { LedId.Mousepad18, 17 }, + { LedId.Mousepad19, 18 }, + { LedId.Mousepad20, 19 }, + { LedId.Mousepad21, 20 }, + { LedId.Mousepad22, 21 }, + { LedId.Mousepad23, 22 }, + { LedId.Mousepad24, 23 }, + { LedId.Mousepad25, 24 }, + { LedId.Mousepad26, 25 }, + { LedId.Mousepad27, 26 }, + { LedId.Mousepad28, 27 }, + { LedId.Mousepad29, 28 }, + { LedId.Mousepad30, 29 }, + { LedId.Mousepad31, 30 }, + { LedId.Mousepad32, 31 }, + }; + + /// + /// Gets the mapping for per zone speakers. + /// + public static LedMapping ZoneSpeaker { get; } = new() + { + { LedId.Speaker1, 0 }, + { LedId.Speaker2, 1 }, + { LedId.Speaker3, 2 }, + { LedId.Speaker4, 3 }, + { LedId.Speaker5, 4 }, + { LedId.Speaker6, 5 }, + { LedId.Speaker7, 6 }, + { LedId.Speaker8, 7 }, + { LedId.Speaker9, 8 }, + { LedId.Speaker10, 9 }, + { LedId.Speaker11, 10 }, + { LedId.Speaker12, 11 }, + { LedId.Speaker13, 12 }, + { LedId.Speaker14, 13 }, + { LedId.Speaker15, 14 }, + { LedId.Speaker16, 15 }, + { LedId.Speaker17, 16 }, + { LedId.Speaker18, 17 }, + { LedId.Speaker19, 18 }, + { LedId.Speaker20, 19 }, + { LedId.Speaker21, 20 }, + { LedId.Speaker22, 21 }, + { LedId.Speaker23, 22 }, + { LedId.Speaker24, 23 }, + { LedId.Speaker25, 24 }, + { LedId.Speaker26, 25 }, + { LedId.Speaker27, 26 }, + { LedId.Speaker28, 27 }, + { LedId.Speaker29, 28 }, + { LedId.Speaker30, 29 }, + { LedId.Speaker31, 30 }, + { LedId.Speaker32, 31 }, + }; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs index 74104fa1..690dd62a 100644 --- a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDevice.cs @@ -1,84 +1,24 @@ -using System.Linq; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Logitech +namespace RGB.NET.Devices.Logitech; + +/// +/// +/// Represents a generic Logitech-device. (keyboard, mouse, headset, mousepad). +/// +public abstract class LogitechRGBDevice : AbstractRGBDevice, ILogitechRGBDevice + where TDeviceInfo : LogitechRGBDeviceInfo { - /// - /// + #region Constructors + /// - /// Represents a generic Logitech-device. (keyboard, mouse, headset, mousepad). + /// Initializes a new instance of the class. /// - public abstract class LogitechRGBDevice : AbstractRGBDevice, ILogitechRGBDevice - where TDeviceInfo : LogitechRGBDeviceInfo - { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected UpdateQueue UpdateQueue { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by Logitech for the device. - protected LogitechRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(UpdateQueue updateQueue) - { - InitializeLayout(); - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - - UpdateQueue = updateQueue; - } - - /// - /// Initializes the and of the device. - /// - protected virtual void InitializeLayout() - { - if (!(DeviceInfo is LogitechRGBDeviceInfo info)) return; - - string layout = info.ImageLayout; - string layoutPath = info.LayoutPath; - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Logitech", $"{layoutPath}.xml"), layout, true); - } - - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } - - #endregion - } -} + /// The generic information provided by Logitech for the device. + /// The queue used to update this device. + protected LogitechRGBDevice(TDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs index a476c7ff..5e9a5abe 100644 --- a/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Logitech/Generic/LogitechRGBDeviceInfo.cs @@ -1,95 +1,67 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Logitech -{ - /// - /// - /// Represents a generic information for a Logitech-. - /// - public class LogitechRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields - - /// - public RGBDeviceType DeviceType { get; } - - /// - public string DeviceName { get; } +namespace RGB.NET.Devices.Logitech; - /// - public string Manufacturer => "Logitech"; - - /// - public string Model { get; } - - /// - public Uri Image { get; set; } - - /// - public RGBDeviceLighting Lighting - { - get - { - if (DeviceCaps.HasFlag(LogitechDeviceCaps.PerKeyRGB)) - return RGBDeviceLighting.Key; - - if (DeviceCaps.HasFlag(LogitechDeviceCaps.DeviceRGB)) - return RGBDeviceLighting.Device; +/// +/// +/// Represents a generic information for a Logitech-. +/// +public class LogitechRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - return RGBDeviceLighting.None; - } - } + /// + public RGBDeviceType DeviceType { get; } - /// - public bool SupportsSyncBack => false; + /// + public string DeviceName { get; } - /// - /// Gets a flag that describes device capabilities. () - /// - public LogitechDeviceCaps DeviceCaps { get; } + /// + public string Manufacturer => "Logitech"; - /// - /// Gets the amount of zones the is able to control (0 for single-color and per-key devices) - /// - public int Zones { get; } + /// + public string Model { get; } - /// - /// Gets the layout used to decide which images to load. - /// - internal string ImageLayout { get; } + /// + public object? LayoutMetadata { get; set; } - /// - /// Gets the path/name of the layout-file. - /// - internal string LayoutPath { get; } + /// + /// Gets a flag that describes device capabilities. () + /// + public LogitechDeviceCaps DeviceCaps { get; } - #endregion + /// + /// Gets the amount of zones the is able to control (0 for single-color and per-key devices) + /// + public int Zones { get; } - #region Constructors + /// + /// Gets the zone at which LEDs start being mapped + /// + public int ZoneOffset { get; } + + #endregion - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The represented device model. - /// The lighting-capabilities of the device. - /// The amount of zones the device is able to control. - /// The layout used to decide which images to load. - /// The path/name of the layout-file. - internal LogitechRGBDeviceInfo(RGBDeviceType deviceType, string model, LogitechDeviceCaps deviceCaps, - int zones, string imageLayout, string layoutPath) - { - this.DeviceType = deviceType; - this.Model = model; - this.DeviceCaps = deviceCaps; - this.Zones = zones; - this.ImageLayout = imageLayout; - this.LayoutPath = layoutPath; + #region Constructors - DeviceName = $"{Manufacturer} {Model}"; - } + /// + /// Internal constructor of managed . + /// + /// The type of the . + /// The represented device model. + /// The lighting-capabilities of the device. + /// The amount of zones the device is able to control. + /// The zone at which to start mapping LEDs. + internal LogitechRGBDeviceInfo(RGBDeviceType deviceType, string model, LogitechDeviceCaps deviceCaps, int zones, int zoneOffset = 0) + { + this.DeviceType = deviceType; + this.Model = model; + this.DeviceCaps = deviceCaps; + this.Zones = zones; + this.ZoneOffset = zoneOffset; - #endregion + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs b/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs deleted file mode 100644 index 4e8d5518..00000000 --- a/RGB.NET.Devices.Logitech/HID/DeviceChecker.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using HidSharp; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Logitech.HID -{ - //TODO DarthAffe 04.02.2017: Rewrite this once the SDK supports per-device lighting to get all the devices connected. - internal static class DeviceChecker - { - #region Constants - - private const int VENDOR_ID = 0x046D; - - //TODO DarthAffe 14.11.2017: Add devices - private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> PER_KEY_DEVICES - = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> - { - ("G910", RGBDeviceType.Keyboard, 0xC32B, 0, "DE", @"Keyboards\G910\UK"), //TODO DarthAffe 15.11.2017: Somehow detect the current layout - ("G910v2", RGBDeviceType.Keyboard, 0xC335, 0, "DE", @"Keyboards\G910\UK"), - ("G915", RGBDeviceType.Keyboard, 0xC541, 0, "DE", @"Keyboards\G915\UK"), - ("G810", RGBDeviceType.Keyboard, 0xC337, 0, "DE", @"Keyboards\G810\UK"), - ("G810", RGBDeviceType.Keyboard, 0xC331, 0, "DE", @"Keyboards\G810\UK"), - ("G610", RGBDeviceType.Keyboard, 0xC333, 0, "DE", @"Keyboards\G610\UK"), - ("G512", RGBDeviceType.Keyboard, 0xC33C, 0, "DE", @"Keyboards\G512\UK"), - ("G512 SE", RGBDeviceType.Keyboard, 0xC342, 0, "DE", @"Keyboards\G512SE\UK"), - ("G410", RGBDeviceType.Keyboard, 0xC330, 0, "DE", @"Keyboards\G410\UK"), - ("G213", RGBDeviceType.Keyboard, 0xC336, 0, "DE", @"Keyboards\G213\UK"), - ("Pro", RGBDeviceType.Keyboard, 0xC339, 0, "DE", @"Keyboards\Pro\UK"), - }; - - private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> PER_DEVICE_DEVICES - = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> - { - ("G19", RGBDeviceType.Keyboard, 0xC228, 0, "DE", @"Keyboards\G19\UK"), - ("G19s", RGBDeviceType.Keyboard, 0xC229, 0, "DE", @"Keyboards\G19s\UK"), - ("G600", RGBDeviceType.Mouse, 0xC24A, 0, "default", @"Mice\G600"), - ("G300s", RGBDeviceType.Mouse, 0xC246, 0, "default", @"Mice\G300s"), - ("G510", RGBDeviceType.Keyboard, 0xC22D, 0, "DE", @"Keyboards\G510\UK"), - ("G510s", RGBDeviceType.Keyboard, 0xC22E, 0, "DE", @"Keyboards\G510s\UK"), - ("G13", RGBDeviceType.Keypad, 0xC21C, 0, "DE", @"Keypads\G13\UK"), - ("G110", RGBDeviceType.Keyboard, 0xC22B, 0, "DE", @"Keyboards\G110\UK"), - ("G710+", RGBDeviceType.Keyboard, 0xC24D, 0, "DE", @"Keyboards\G710+\UK"), - ("G105", RGBDeviceType.Keyboard, 0xC248, 0, "DE", @"Keyboards\G105\UK"), - ("G15", RGBDeviceType.Keyboard, 0xC222, 0, "DE", @"Keyboards\G15\UK"), - ("G11", RGBDeviceType.Keyboard, 0xC225, 0, "DE", @"Keyboards\G11\UK"), - }; - - private static readonly List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> ZONE_DEVICES - = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> - { - ("G213", RGBDeviceType.Keyboard, 0xC336, 5, "default", @"Keyboards\G213"), - ("G903", RGBDeviceType.Mouse, 0xC086, 2, "default", @"Mice\G903"), - ("G900", RGBDeviceType.Mouse, 0xC539, 2, "default", @"Mice\G900"), - ("G703", RGBDeviceType.Mouse, 0xC087, 2, "default", @"Mice\G703"), - ("G502 HERO", RGBDeviceType.Mouse, 0xC08B, 2, "default", @"Mice\G502"), - ("G502", RGBDeviceType.Mouse, 0xC332, 2, "default", @"Mice\G502"), - ("G403", RGBDeviceType.Mouse, 0xC083, 2, "default", @"Mice\G403"), - ("G303", RGBDeviceType.Mouse, 0xC080, 2, "default", @"Mice\G303"), - ("G203", RGBDeviceType.Mouse, 0xC084, 1, "default", @"Mice\G203"), - ("G Pro", RGBDeviceType.Mouse, 0xC085, 1, "default", @"Mice\GPro"), - ("G Pro Wireless", RGBDeviceType.Mouse, 0xC088, 1, "default", @"Mice\GPro"), - ("G Pro Hero", RGBDeviceType.Mouse, 0xC08C, 1, "default", @"Mice\GProHero"), - ("G633", RGBDeviceType.Headset, 0x0A5C, 2, "default", @"Headsets\G633"), - ("G933", RGBDeviceType.Headset, 0x0A5B, 2, "default", @"Headsets\G933"), - ("G935", RGBDeviceType.Headset, 0x0A87, 2, "default", @"Headsets\G935"), - ("G560", RGBDeviceType.Speaker, 0x0A78, 4, "default", @"Speakers\G560"), - }; - - #endregion - - #region Properties & Fields - - public static bool IsPerKeyDeviceConnected { get; private set; } - public static (string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) PerKeyDeviceData { get; private set; } - - public static bool IsPerDeviceDeviceConnected { get; private set; } - public static (string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) PerDeviceDeviceData { get; private set; } - - public static bool IsZoneDeviceConnected { get; private set; } - public static IEnumerable<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> ZoneDeviceData { get; private set; } - - #endregion - - #region Methods - - internal static void LoadDeviceList() - { - List ids = DeviceList.Local.GetHidDevices(VENDOR_ID).Select(x => x.ProductID).Distinct().ToList(); - - foreach ((string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) deviceData in PER_KEY_DEVICES) - if (ids.Contains(deviceData.id)) - { - IsPerKeyDeviceConnected = true; - PerKeyDeviceData = deviceData; - break; - } - - foreach ((string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) deviceData in PER_DEVICE_DEVICES) - if (ids.Contains(deviceData.id)) - { - IsPerDeviceDeviceConnected = true; - PerDeviceDeviceData = deviceData; - break; - } - - Dictionary> connectedZoneDevices - = new Dictionary>(); - foreach ((string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath) deviceData in ZONE_DEVICES) - { - if (ids.Contains(deviceData.id)) - { - IsZoneDeviceConnected = true; - if (!connectedZoneDevices.TryGetValue(deviceData.deviceType, out List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> deviceList)) - connectedZoneDevices.Add(deviceData.deviceType, deviceList = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)>()); - deviceList.Add(deviceData); - } - } - List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)> zoneDeviceData - = new List<(string model, RGBDeviceType deviceType, int id, int zones, string imageLayout, string layoutPath)>(); - foreach (KeyValuePair> connectedZoneDevice in connectedZoneDevices) - { - int maxZones = connectedZoneDevice.Value.Max(x => x.zones); - zoneDeviceData.Add(connectedZoneDevice.Value.First(x => x.zones == maxZones)); - } - - ZoneDeviceData = zoneDeviceData; - } - - #endregion - } -} diff --git a/RGB.NET.Devices.Logitech/HID/Extensions.cs b/RGB.NET.Devices.Logitech/HID/Extensions.cs new file mode 100644 index 00000000..d1954acc --- /dev/null +++ b/RGB.NET.Devices.Logitech/HID/Extensions.cs @@ -0,0 +1,49 @@ +using HidSharp; +using HidSharp.Reports.Encodings; +using System; +using System.Linq; +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Logitech.HID; + +internal static class Extensions +{ + internal static Span AsSpan(this ref T val) + where T : unmanaged + { + Span valSpan = MemoryMarshal.CreateSpan(ref val, 1); + return MemoryMarshal.Cast(valSpan); + } + + internal static uint GetUsagePage(this HidDevice device) + { + try + { + return device.GetItemByType(ItemType.Global)?.DataValue ?? uint.MaxValue; + } + catch + { + return uint.MaxValue; + } + } + + internal static uint GetUsage(this HidDevice device) + { + try + { + return device.GetItemByType(ItemType.Local)?.DataValue ?? uint.MaxValue; + } + catch + { + return uint.MaxValue; + } + } + + private static EncodedItem? GetItemByType(this HidDevice device, ItemType itemType) + { + byte[] descriptor = device.GetRawReportDescriptor(); + return EncodedItem.DecodeItems(descriptor, 0, descriptor.Length) + .Where(de => (de.TagForLocal == LocalItemTag.Usage) && (de.TagForGlobal == GlobalItemTag.UsagePage)) + .FirstOrDefault(de => de.ItemType == itemType); + } +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/HID/FapResponse.cs b/RGB.NET.Devices.Logitech/HID/FapResponse.cs new file mode 100644 index 00000000..366a8421 --- /dev/null +++ b/RGB.NET.Devices.Logitech/HID/FapResponse.cs @@ -0,0 +1,72 @@ +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Logitech.HID; + +[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 64)] +internal struct FapResponse +{ + public byte Command; + public byte DeviceIndex; + public byte FeatureIndex; + public byte FeatureCommand; + public byte Data00; + public byte Data01; + public byte Data02; + public byte Data03; + public byte Data04; + public byte Data05; + public byte Data06; + public byte Data07; + public byte Data08; + public byte Data09; + public byte Data10; + public byte Data11; + public byte Data12; + public byte Data13; + public byte Data14; + public byte Data15; + public byte Data16; + public byte Data17; + public byte Data18; + public byte Data19; + public byte Data20; + public byte Data21; + public byte Data22; + public byte Data23; + public byte Data24; + public byte Data25; + public byte Data26; + public byte Data27; + public byte Data28; + public byte Data29; + public byte Data30; + public byte Data31; + public byte Data32; + public byte Data33; + public byte Data34; + public byte Data35; + public byte Data36; + public byte Data37; + public byte Data38; + public byte Data39; + public byte Data40; + public byte Data41; + public byte Data42; + public byte Data43; + public byte Data44; + public byte Data45; + public byte Data46; + public byte Data47; + public byte Data48; + public byte Data49; + public byte Data50; + public byte Data51; + public byte Data52; + public byte Data53; + public byte Data54; + public byte Data55; + public byte Data56; + public byte Data57; + public byte Data58; + public byte Data59; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/HID/FapShortRequest.cs b/RGB.NET.Devices.Logitech/HID/FapShortRequest.cs new file mode 100644 index 00000000..7c8f3ffe --- /dev/null +++ b/RGB.NET.Devices.Logitech/HID/FapShortRequest.cs @@ -0,0 +1,41 @@ +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Logitech.HID; + +[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 7)] +internal struct FapShortRequest +{ + #region Constants + + private const byte LOGITECH_SHORT_MESSAGE = 0x10; + + #endregion + + #region Properties & Fields + + public byte ReportId; + public byte DeviceIndex; + public byte FeatureIndex; + public byte FeatureCommand; + public byte Data0; + public byte Data1; + public byte Data2; + + #endregion + + #region Constructors + + public void Init(byte deviceIndex, byte featureIndex) + { + this.DeviceIndex = deviceIndex; + this.FeatureIndex = featureIndex; + + ReportId = LOGITECH_SHORT_MESSAGE; + FeatureCommand = 0; + Data0 = 0; + Data1 = 0; + Data2 = 0; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/HID/LightspeedHidLoader.cs b/RGB.NET.Devices.Logitech/HID/LightspeedHidLoader.cs new file mode 100644 index 00000000..a536a1ef --- /dev/null +++ b/RGB.NET.Devices.Logitech/HID/LightspeedHidLoader.cs @@ -0,0 +1,200 @@ +using HidSharp; +using RGB.NET.Core; +using RGB.NET.HID; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace RGB.NET.Devices.Logitech.HID; + +/// +/// Represents a loaded for logitech HID-devices. +/// +/// The type of the identifier leds are mapped to. +/// The type of the custom data added to the HID-device. +public class LightspeedHIDLoader : IEnumerable> + where TLed : notnull +{ + #region Constants + + private const int LOGITECH_PROTOCOL_TIMEOUT = 300; + private const int VENDOR_ID = 0x046D; + + // ReSharper disable once StaticMemberInGenericType - This is used like a const + private static readonly List RECEIVER_PIDS = new() + { + 0xC539, + 0xC53A, + 0xC541, + 0xC545 + }; + + #endregion + + #region Properties & Fields + + private readonly Dictionary> _deviceDefinitions = new(); + + /// + /// Gets the vendor id used for this loader. + /// + public int VendorId => VENDOR_ID; + + /// + /// Gets or sets the filter used to determine which devices should be loaded. + /// + public RGBDeviceType LoadFilter { get; set; } = RGBDeviceType.All; + + #endregion + + #region Methods + + /// + /// Adds a new to this loader. + /// + /// The virtual product id of the HID-device. + /// The type of the device. + /// The name of the device. + /// The mapping of the leds of the device. + /// Some custom data to attach to the device. + public void Add(int virtualPid, RGBDeviceType deviceType, string name, LedMapping ledMapping, TData customData) + => _deviceDefinitions.Add(virtualPid, new HIDDeviceDefinition(virtualPid, deviceType, name, ledMapping, customData)); + + /// + /// Gets a enumerable containing all devices from the definition-list that are connected and match the . + /// + /// The enumerable containing the connected devices. + public IEnumerable> GetConnectedDevices() + { + foreach (int device in Detect()) + { + if (_deviceDefinitions.TryGetValue(device, out HIDDeviceDefinition? definition)) + if (LoadFilter.HasFlag(definition.DeviceType)) + yield return definition; + } + } + + /// + /// Gets a enumerable containing all the first device of each group of devices from the definition-list that are connected and match the . + /// The grouping is done by the specified function. + /// + /// The type of the key used to group the devices. + /// The function grouping the devices. + /// The enumerable containing the selected devices. + public IEnumerable> GetConnectedDevices(Func, TKey> groupBy) + => GetConnectedDevices().GroupBy(groupBy) + .Select(group => group.First()); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() => _deviceDefinitions.Values.GetEnumerator(); + + #endregion + + #region Private Methods + + private IEnumerable Detect() => RECEIVER_PIDS.SelectMany(Detect); + + private IEnumerable Detect(int pid) + { + Dictionary deviceUsages = DeviceList.Local + .GetHidDevices(VendorId, pid) + .Where(d => d.DevicePath.Contains("mi_02")) + .ToDictionary(x => (byte)x.GetUsage(), x => x); + + foreach ((int wirelessPid, byte _) in GetWirelessDevices(deviceUsages)) + yield return wirelessPid; + } + + [SuppressMessage("ReSharper", "MustUseReturnValue")] + private Dictionary GetWirelessDevices(IReadOnlyDictionary deviceUsages) + { + const byte LOGITECH_RECEIVER_ADDRESS = 0xFF; + const byte LOGITECH_SET_REGISTER_REQUEST = 0x80; + const byte LOGITECH_GET_REGISTER_REQUEST = 0x81; + + Dictionary map = new(); + + if (!deviceUsages.TryGetValue(1, out HidDevice? device) || !device.TryOpen(out HidStream stream)) + return map; + + int tries = 0; + const int MAX_TRIES = 5; + while (tries < MAX_TRIES) + { + try + { + stream.ReadTimeout = LOGITECH_PROTOCOL_TIMEOUT; + stream.WriteTimeout = LOGITECH_PROTOCOL_TIMEOUT; + + FapResponse response = new(); + + FapShortRequest getConnectedDevices = new(); + getConnectedDevices.Init(LOGITECH_RECEIVER_ADDRESS, LOGITECH_GET_REGISTER_REQUEST); + + stream.Write(getConnectedDevices.AsSpan()); + stream.Read(response.AsSpan()); + + bool wirelessNotifications = (response.Data01 & 1) == 1; + if (!wirelessNotifications) + { + response = new FapResponse(); + + getConnectedDevices.Init(LOGITECH_RECEIVER_ADDRESS, LOGITECH_SET_REGISTER_REQUEST); + getConnectedDevices.Data1 = 1; + + stream.Write(getConnectedDevices.AsSpan()); + stream.Read(response.AsSpan()); + + if (getConnectedDevices.FeatureIndex == 0x8f) + { + //error?? + } + } + + response = new FapResponse(); + + getConnectedDevices.Init(LOGITECH_RECEIVER_ADDRESS, LOGITECH_GET_REGISTER_REQUEST); + getConnectedDevices.FeatureCommand = 0x02; + + stream.Write(getConnectedDevices.AsSpan()); + stream.Read(response.AsSpan()); + int deviceCount = response.Data01; + if (deviceCount <= 0) + return map; + + //Add 1 to the device_count to include the receiver + deviceCount++; + + getConnectedDevices.Init(LOGITECH_RECEIVER_ADDRESS, LOGITECH_SET_REGISTER_REQUEST); + getConnectedDevices.FeatureCommand = 0x02; + getConnectedDevices.Data0 = 0x02; + stream.Write(getConnectedDevices.AsSpan()); + + for (int i = 0; i < deviceCount; i++) + { + FapResponse devices = new(); + stream.Read(devices.AsSpan()); + int wirelessPid = (devices.Data02 << 8) | devices.Data01; + if (devices.DeviceIndex != 0xff) + map.Add(wirelessPid, devices.DeviceIndex); + } + + break; + } + catch + { + tries++; + //This might timeout if LGS or GHUB interfere. + //Retry. + } + } + + return map; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs index 5169eb34..1180ff5d 100644 --- a/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs +++ b/RGB.NET.Devices.Logitech/LogitechDeviceProvider.cs @@ -3,197 +3,268 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; +using System.Linq; +using HidSharp; using RGB.NET.Core; -using RGB.NET.Devices.Logitech.HID; using RGB.NET.Devices.Logitech.Native; +using RGB.NET.Devices.Logitech.HID; +using RGB.NET.HID; + +namespace RGB.NET.Devices.Logitech; -namespace RGB.NET.Devices.Logitech +/// +/// +/// Represents a device provider responsible for logitech devices. +/// +public class LogitechDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static LogitechDeviceProvider? _instance; /// - /// Represents a device provider responsible for logitech devices. + /// Gets the singleton instance. /// - public class LogitechDeviceProvider : IRGBDeviceProvider + public static LogitechDeviceProvider Instance => _instance ?? new LogitechDeviceProvider(); + + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. + /// The first match will be used. + /// + public static List PossibleX86NativePaths { get; } = new() { "x86/LogitechLedEnginesWrapper.dll" }; + + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. + /// The first match will be used. + /// + public static List PossibleX64NativePaths { get; } = new() { "x64/LogitechLedEnginesWrapper.dll" }; + + private LogitechPerDeviceUpdateQueue? _perDeviceUpdateQueue; + private LogitechPerKeyUpdateQueue? _perKeyUpdateQueue; + + private const int VENDOR_ID = 0x046D; + + /// + /// Gets the HID-definitions for wired per-key-devices. + /// + public static HIDLoader PerKeyDeviceDefinitions { get; } = new(VENDOR_ID) { - #region Properties & Fields - - private static LogitechDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static LogitechDeviceProvider Instance => _instance ?? new LogitechDeviceProvider(); - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. - /// The first match will be used. - /// - public static List PossibleX86NativePaths { get; } = new List { "x86/LogitechLedEnginesWrapper.dll" }; - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. - /// The first match will be used. - /// - public static List PossibleX64NativePaths { get; } = new List { "x64/LogitechLedEnginesWrapper.dll" }; - - /// - public bool IsInitialized { get; private set; } - - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _LogitechGSDK.LoadedArchitecture; - - /// - public IEnumerable Devices { get; private set; } - - /// - public bool HasExclusiveAccess => false; // Exclusive access isn't possible for logitech devices. - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; - - /// - /// The used to trigger the updates for logitech devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } - - // ReSharper disable once CollectionNeverQueried.Local - for now this is just to make sure they're never collected - private readonly Dictionary _zoneUpdateQueues = new Dictionary(); - private LogitechPerDeviceUpdateQueue _perDeviceUpdateQueue; - private LogitechPerKeyUpdateQueue _perKeyUpdateQueue; + { 0xC32B, RGBDeviceType.Keyboard, "G910", LedMappings.PerKey, 0 }, + { 0xC330, RGBDeviceType.Keyboard, "G410", LedMappings.PerKey, 0 }, + { 0xC331, RGBDeviceType.Keyboard, "G810", LedMappings.PerKey, 0 }, + { 0xC335, RGBDeviceType.Keyboard, "G910v2", LedMappings.PerKey, 0 }, + { 0xC337, RGBDeviceType.Keyboard, "G810", LedMappings.PerKey, 0 }, + { 0xC339, RGBDeviceType.Keyboard, "Pro", LedMappings.PerKey, 0 }, + { 0xC33C, RGBDeviceType.Keyboard, "G513", LedMappings.PerKey, 0 }, + { 0xC33E, RGBDeviceType.Keyboard, "G915", LedMappings.PerKey, 0 }, + { 0xC33F, RGBDeviceType.Keyboard, "G815", LedMappings.PerKey, 0 }, + { 0xC342, RGBDeviceType.Keyboard, "G512", LedMappings.PerKey, 0 }, + { 0xC343, RGBDeviceType.Keyboard, "G915 TKL", LedMappings.PerKey, 0 }, + { 0xC541, RGBDeviceType.Keyboard, "G915", LedMappings.PerKey, 0 }, + + //non-rgb + { 0xC333, RGBDeviceType.Keyboard, "G610", LedMappings.PerKey, 0 }, + { 0xC338, RGBDeviceType.Keyboard, "G610", LedMappings.PerKey, 0 }, + }; - #endregion + /// + /// Gets the HID-definitions for wireless per-key-devices. + /// + public static LightspeedHIDLoader PerKeyWirelessDeviceDefinitions { get; } = new() + { + { 0x407C, RGBDeviceType.Keyboard, "G915", LedMappings.PerKey, 0 }, + { 0x408E, RGBDeviceType.Keyboard, "G915 TKL", LedMappings.PerKey, 0 }, + }; - #region Constructors + /// + /// Gets the HID-definitions for wired per-zone-devices. + /// + public static HIDLoader PerZoneDeviceDefinitions { get; } = new(VENDOR_ID) + { + { 0xC336, RGBDeviceType.Keyboard, "G213", LedMappings.ZoneKeyboard, (LogitechDeviceType.Keyboard, 5, 0) }, + + { 0xC092, RGBDeviceType.Mouse, "G203 Lightsync", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 1, 0) }, + { 0xC080, RGBDeviceType.Mouse, "G303", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC081, RGBDeviceType.Mouse, "G900", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC082, RGBDeviceType.Mouse, "G403", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC083, RGBDeviceType.Mouse, "G403", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC084, RGBDeviceType.Mouse, "G203", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 1, 0) }, + { 0xC085, RGBDeviceType.Mouse, "G Pro", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 1, 0) }, + { 0xC086, RGBDeviceType.Mouse, "G903", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC087, RGBDeviceType.Mouse, "G703", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC088, RGBDeviceType.Mouse, "G Pro Wireless", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC08B, RGBDeviceType.Mouse, "G502 HERO", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC08C, RGBDeviceType.Mouse, "G Pro Hero", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 1, 1) }, + { 0xC08D, RGBDeviceType.Mouse, "G502 Lightspeed", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC08F, RGBDeviceType.Mouse, "G403 HERO", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC090, RGBDeviceType.Mouse, "G703 Lightspeed", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC091, RGBDeviceType.Mouse, "G903 Lightspeed", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0xC24A, RGBDeviceType.Mouse, "G600", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 1, 0) }, + { 0xC332, RGBDeviceType.Mouse, "G502", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + + //G633 and G635 are wired headsets. + { 0x0A5C, RGBDeviceType.Headset, "G633", LedMappings.ZoneHeadset, (LogitechDeviceType.Headset, 2, 0) }, + { 0x0A89, RGBDeviceType.Headset, "G635", LedMappings.ZoneHeadset, (LogitechDeviceType.Headset, 2, 0) }, + + //The other ones are wireless only. These PIDs correpond to the dongles. + { 0x0A5B, RGBDeviceType.Headset, "G933", LedMappings.ZoneHeadset, (LogitechDeviceType.Headset, 2, 0) }, + { 0x0A87, RGBDeviceType.Headset, "G935", LedMappings.ZoneHeadset, (LogitechDeviceType.Headset, 2, 0) }, + + { 0x0A78, RGBDeviceType.Speaker, "G560", LedMappings.ZoneSpeaker, (LogitechDeviceType.Speaker, 4, 0) }, + }; + + /// + /// Gets the HID-definitions for wireless per-zone-devices. + /// + public static LightspeedHIDLoader PerZoneWirelessDeviceDefinitions { get; } = new() + { + { 0x4053, RGBDeviceType.Mouse, "G900", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0x405D, RGBDeviceType.Mouse, "G403", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0x4067, RGBDeviceType.Mouse, "G903", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0x4070, RGBDeviceType.Mouse, "G703", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0x4079, RGBDeviceType.Mouse, "G Pro Wireless", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0x407F, RGBDeviceType.Mouse, "G502 Lightspeed", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0x4086, RGBDeviceType.Mouse, "G703 Lightspeed", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + { 0x4087, RGBDeviceType.Mouse, "G903 Lightspeed", LedMappings.ZoneMouse, (LogitechDeviceType.Mouse, 2, 0) }, + }; - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public LogitechDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(LogitechDeviceProvider)}"); - _instance = this; + /// + /// Gets the HID-definitions for wired per-device-devices. + /// + public static HIDLoader PerDeviceDeviceDefinitions { get; } = new(VENDOR_ID) + { + { 0xC228, RGBDeviceType.Keyboard, "G19", LedMappings.Device, 0 }, + { 0xC229, RGBDeviceType.Keyboard, "G19s", LedMappings.Device, 0 }, + { 0xC24A, RGBDeviceType.Mouse, "G600", LedMappings.Device, 0 }, + { 0xC246, RGBDeviceType.Mouse, "G300s", LedMappings.Device, 0 }, + { 0xC22D, RGBDeviceType.Keyboard, "G510", LedMappings.Device, 0 }, + { 0xC22E, RGBDeviceType.Keyboard, "G510s", LedMappings.Device, 0 }, + { 0xC21C, RGBDeviceType.Keypad, "G13", LedMappings.Device, 0 }, + { 0xC22B, RGBDeviceType.Keyboard, "G110", LedMappings.Device, 0 }, + { 0xC24D, RGBDeviceType.Keyboard, "G710+", LedMappings.Device, 0 }, + { 0xC248, RGBDeviceType.Keyboard, "G105", LedMappings.Device, 0 }, + { 0xC222, RGBDeviceType.Keyboard, "G15", LedMappings.Device, 0 }, + { 0xC225, RGBDeviceType.Keyboard, "G11", LedMappings.Device, 0 }, + { 0x0AB5, RGBDeviceType.Headset, "G733", LedMappings.Device, 0 }, + { 0xC53A, RGBDeviceType.Mousepad, "POWERPLAY", LedMappings.Device, 0 }, + }; - UpdateTrigger = new DeviceUpdateTrigger(); - _perDeviceUpdateQueue = new LogitechPerDeviceUpdateQueue(UpdateTrigger); - _perKeyUpdateQueue = new LogitechPerKeyUpdateQueue(UpdateTrigger); - } + /// + /// Gets the HID-definitions for wireless per-device-devices. + /// + public static LightspeedHIDLoader PerDeviceWirelessDeviceDefinitions { get; } = new(); - #endregion + #endregion - #region Methods + #region Constructors - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - try - { - if (IsInitialized) - _LogitechGSDK.LogiLedRestoreLighting(); - } - catch { /* At least we tried ... */ } + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public LogitechDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(LogitechDeviceProvider)}"); + _instance = this; + } + + #endregion + + #region Methods - IsInitialized = false; + /// + protected override void InitializeSDK() + { + _perDeviceUpdateQueue = new LogitechPerDeviceUpdateQueue(GetUpdateTrigger()); + _perKeyUpdateQueue = new LogitechPerKeyUpdateQueue(GetUpdateTrigger()); + + _LogitechGSDK.Reload(); + if (!_LogitechGSDK.LogiLedInit()) Throw(new RGBDeviceException("Failed to initialize Logitech-SDK."), true); + + _LogitechGSDK.LogiLedSaveCurrentLighting(); + } - try + /// + protected override IEnumerable GetLoadedDevices(RGBDeviceType loadFilter) + { + PerKeyDeviceDefinitions.LoadFilter = loadFilter; + PerZoneDeviceDefinitions.LoadFilter = loadFilter; + PerDeviceDeviceDefinitions.LoadFilter = loadFilter; + + return base.GetLoadedDevices(loadFilter); + } + + /// + protected override IEnumerable LoadDevices() + { + #region PerKey + + if (_perKeyUpdateQueue != null) + { + (HIDDeviceDefinition definition, HidDevice device) perKeyDevice = PerKeyDeviceDefinitions.GetConnectedDevices().FirstOrDefault(); + if (perKeyDevice != default) { - UpdateTrigger?.Stop(); - - _LogitechGSDK.Reload(); - if (!_LogitechGSDK.LogiLedInit()) return false; - - _LogitechGSDK.LogiLedSaveCurrentLighting(); - - IList devices = new List(); - DeviceChecker.LoadDeviceList(); - - try - { - if (DeviceChecker.IsPerKeyDeviceConnected) - { - (string model, RGBDeviceType deviceType, int _, int _, string imageLayout, string layoutPath) = DeviceChecker.PerKeyDeviceData; - if (loadFilter.HasFlag(deviceType)) //TODO DarthAffe 07.12.2017: Check if it's worth to try another device if the one returned doesn't match the filter - { - ILogitechRGBDevice device = new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.PerKeyRGB, 0, imageLayout, layoutPath)); - device.Initialize(_perKeyUpdateQueue); - devices.Add(device); - } - } - } - catch { if (throwExceptions) throw; } - - try - { - if (DeviceChecker.IsPerDeviceDeviceConnected) - { - (string model, RGBDeviceType deviceType, int _, int _, string imageLayout, string layoutPath) = DeviceChecker.PerDeviceDeviceData; - if (loadFilter.HasFlag(deviceType)) //TODO DarthAffe 07.12.2017: Check if it's worth to try another device if the one returned doesn't match the filter - { - ILogitechRGBDevice device = new LogitechPerDeviceRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, 0, imageLayout, layoutPath)); - device.Initialize(_perDeviceUpdateQueue); - devices.Add(device); - } - } - } - catch { if (throwExceptions) throw; } - - try - { - if (DeviceChecker.IsZoneDeviceConnected) - { - foreach ((string model, RGBDeviceType deviceType, int _, int zones, string imageLayout, string layoutPath) in DeviceChecker.ZoneDeviceData) - try - { - if (loadFilter.HasFlag(deviceType)) - { - LogitechZoneUpdateQueue updateQueue = new LogitechZoneUpdateQueue(UpdateTrigger, deviceType); - ILogitechRGBDevice device = new LogitechZoneRGBDevice(new LogitechRGBDeviceInfo(deviceType, model, LogitechDeviceCaps.DeviceRGB, zones, imageLayout, layoutPath)); - device.Initialize(updateQueue); - devices.Add(device); - _zoneUpdateQueues.Add(deviceType, updateQueue); - } - } - catch { if (throwExceptions) throw; } - } - } - catch { if (throwExceptions) throw; } - - UpdateTrigger?.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; + (HIDDeviceDefinition definition, _) = perKeyDevice; + yield return new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(definition.DeviceType, definition.Name, LogitechDeviceCaps.PerKeyRGB, 0), _perKeyUpdateQueue, definition.LedMapping); } - catch + else { - if (throwExceptions) - throw; - return false; + HIDDeviceDefinition? perKeyWirelessDevice = PerKeyWirelessDeviceDefinitions.GetConnectedDevices().FirstOrDefault(); + if (perKeyWirelessDevice != null) + yield return new LogitechPerKeyRGBDevice(new LogitechRGBDeviceInfo(perKeyWirelessDevice.DeviceType, perKeyWirelessDevice.Name, LogitechDeviceCaps.PerKeyRGB, 0), _perKeyUpdateQueue, perKeyWirelessDevice.LedMapping); } - - return true; } - /// - public void ResetDevices() => _LogitechGSDK.LogiLedRestoreLighting(); + #endregion + + #region PerZone - /// - public void Dispose() + IEnumerable> wiredPerZoneDevices = PerZoneDeviceDefinitions.GetConnectedDevices().Select(x => x.definition); + IEnumerable> wirelessPerZoneDevices = PerZoneWirelessDeviceDefinitions.GetConnectedDevices(); + foreach (HIDDeviceDefinition definition in wiredPerZoneDevices.Concat(wirelessPerZoneDevices) + .GroupBy(x => x.CustomData.deviceType) + .Select(group => group.First())) { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } + LogitechZoneUpdateQueue updateQueue = new(GetUpdateTrigger(), definition.CustomData.deviceType); + yield return new LogitechZoneRGBDevice(new LogitechRGBDeviceInfo(definition.DeviceType, definition.Name, LogitechDeviceCaps.DeviceRGB, definition.CustomData.zones, definition.CustomData.zoneOffset), + updateQueue, definition.LedMapping); + } + + #endregion - try { _LogitechGSDK.LogiLedRestoreLighting(); } - catch { /* at least we tried */ } + #region PerDevice - try { _LogitechGSDK.UnloadLogitechGSDK(); } - catch { /* at least we tried */ } + if (_perDeviceUpdateQueue != null) + { + (HIDDeviceDefinition definition, HidDevice device) perDeviceDevice = PerDeviceDeviceDefinitions.GetConnectedDevices().FirstOrDefault(); + if (perDeviceDevice != default) + { + (HIDDeviceDefinition definition, _) = perDeviceDevice; + yield return new LogitechPerDeviceRGBDevice(new LogitechRGBDeviceInfo(definition.DeviceType, definition.Name, LogitechDeviceCaps.DeviceRGB, 0), _perDeviceUpdateQueue, definition.LedMapping); + } + else + { + HIDDeviceDefinition? perDeviceWirelessDevice = PerDeviceWirelessDeviceDefinitions.GetConnectedDevices().FirstOrDefault(); + if (perDeviceWirelessDevice != null) + yield return new LogitechPerDeviceRGBDevice(new LogitechRGBDeviceInfo(perDeviceWirelessDevice.DeviceType, perDeviceWirelessDevice.Name, LogitechDeviceCaps.DeviceRGB, 0), _perDeviceUpdateQueue, perDeviceWirelessDevice.LedMapping); + } } #endregion } -} + + /// + public override void Dispose() + { + base.Dispose(); + + try { _LogitechGSDK.LogiLedRestoreLighting(); } + catch { /* at least we tried */ } + + try { _LogitechGSDK.UnloadLogitechGSDK(); } + catch { /* at least we tried */ } + + GC.SuppressFinalize(this); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/LogitechDeviceProviderLoader.cs b/RGB.NET.Devices.Logitech/LogitechDeviceProviderLoader.cs deleted file mode 100644 index e79691b9..00000000 --- a/RGB.NET.Devices.Logitech/LogitechDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Logitech -{ - /// - /// Represents a device provider loaded used to dynamically load logitech devices into an application. - /// - public class LogitechDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => LogitechDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs b/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs index 8f1b826c..76efa36b 100644 --- a/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs +++ b/RGB.NET.Devices.Logitech/Native/_LogitechGSDK.cs @@ -1,4 +1,5 @@ -// ReSharper disable UnusedMethodReturnValue.Global +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable UnusedMethodReturnValue.Global // ReSharper disable UnusedMember.Global // ReSharper disable MemberCanBePrivate.Global @@ -9,161 +10,147 @@ using System.Runtime.InteropServices; using RGB.NET.Core; -namespace RGB.NET.Devices.Logitech.Native -{ - // ReSharper disable once InconsistentNaming - internal class _LogitechGSDK - { - #region Libary Management - - private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - - /// - /// Reloads the SDK. - /// - internal static void Reload() - { - UnloadLogitechGSDK(); - LoadLogitechGSDK(); - } - - private static void LoadLogitechGSDK() - { - if (_dllHandle != IntPtr.Zero) return; - - // HACK: Load library at runtime to support both, x86 and x64 with one managed dll - List possiblePathList = Environment.Is64BitProcess ? LogitechDeviceProvider.PossibleX64NativePaths : LogitechDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); - if (dllPath == null) throw new RGBDeviceException($"Can't find the Logitech-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - - _dllHandle = LoadLibrary(dllPath); - - _logiLedInitPointer = (LogiLedInitPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedInit"), typeof(LogiLedInitPointer)); - _logiLedShutdownPointer = (LogiLedShutdownPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedShutdown"), typeof(LogiLedShutdownPointer)); - _logiLedSetTargetDevicePointer = (LogiLedSetTargetDevicePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetTargetDevice"), typeof(LogiLedSetTargetDevicePointer)); - _logiLedGetSdkVersionPointer = (LogiLedGetSdkVersionPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedGetSdkVersion"), typeof(LogiLedGetSdkVersionPointer)); - _lgiLedSaveCurrentLightingPointer = (LogiLedSaveCurrentLightingPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSaveCurrentLighting"), typeof(LogiLedSaveCurrentLightingPointer)); - _logiLedRestoreLightingPointer = (LogiLedRestoreLightingPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedRestoreLighting"), typeof(LogiLedRestoreLightingPointer)); - _logiLedSetLightingPointer = (LogiLedSetLightingPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetLighting"), typeof(LogiLedSetLightingPointer)); - _logiLedSetLightingForKeyWithKeyNamePointer = (LogiLedSetLightingForKeyWithKeyNamePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetLightingForKeyWithKeyName"), typeof(LogiLedSetLightingForKeyWithKeyNamePointer)); - _logiLedSetLightingFromBitmapPointer = (LogiLedSetLightingFromBitmapPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetLightingFromBitmap"), typeof(LogiLedSetLightingFromBitmapPointer)); - _logiLedSetLightingForTargetZonePointer = (LogiLedSetLightingForTargetZonePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "LogiLedSetLightingForTargetZone"), typeof(LogiLedSetLightingForTargetZonePointer)); - } - - internal static void UnloadLogitechGSDK() - { - if (_dllHandle == IntPtr.Zero) return; - - LogiLedShutdown(); - - // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 20.02.2016: We might need to reduce the internal reference counter more than once to set the library free - while (FreeLibrary(_dllHandle)) ; - _dllHandle = IntPtr.Zero; - } - - [DllImport("kernel32.dll")] - private static extern IntPtr LoadLibrary(string dllToLoad); - - [DllImport("kernel32.dll")] - private static extern bool FreeLibrary(IntPtr dllHandle); - - [DllImport("kernel32.dll")] - private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); - - #endregion - - #region SDK-METHODS +namespace RGB.NET.Devices.Logitech.Native; - #region Pointers - - private static LogiLedInitPointer _logiLedInitPointer; - private static LogiLedShutdownPointer _logiLedShutdownPointer; - private static LogiLedSetTargetDevicePointer _logiLedSetTargetDevicePointer; - private static LogiLedGetSdkVersionPointer _logiLedGetSdkVersionPointer; - private static LogiLedSaveCurrentLightingPointer _lgiLedSaveCurrentLightingPointer; - private static LogiLedRestoreLightingPointer _logiLedRestoreLightingPointer; - private static LogiLedSetLightingPointer _logiLedSetLightingPointer; - private static LogiLedSetLightingForKeyWithKeyNamePointer _logiLedSetLightingForKeyWithKeyNamePointer; - private static LogiLedSetLightingFromBitmapPointer _logiLedSetLightingFromBitmapPointer; - private static LogiLedSetLightingForTargetZonePointer _logiLedSetLightingForTargetZonePointer; - - #endregion - - #region Delegates - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool LogiLedInitPointer(); +// ReSharper disable once InconsistentNaming +internal static class _LogitechGSDK +{ + #region Libary Management - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void LogiLedShutdownPointer(); + private static IntPtr _handle = IntPtr.Zero; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool LogiLedSetTargetDevicePointer(int targetDevice); + /// + /// Reloads the SDK. + /// + internal static void Reload() + { + UnloadLogitechGSDK(); + LoadLogitechGSDK(); + } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool LogiLedGetSdkVersionPointer(ref int majorNum, ref int minorNum, ref int buildNum); + private static void LoadLogitechGSDK() + { + if (_handle != IntPtr.Zero) return; + + List possiblePathList = GetPossibleLibraryPaths().ToList(); + + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); + if (dllPath == null) throw new RGBDeviceException($"Can't find the Logitech-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); + + if (!NativeLibrary.TryLoad(dllPath, out _handle)) +#if NET6_0 + throw new RGBDeviceException($"Logitech LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}"); +#else + throw new RGBDeviceException($"Logitech LoadLibrary failed with error code {Marshal.GetLastWin32Error()}"); +#endif + + if (!NativeLibrary.TryGetExport(_handle, "LogiLedInit", out _logiLedInitPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedInit'"); + if (!NativeLibrary.TryGetExport(_handle, "LogiLedShutdown", out _logiLedShutdownPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedShutdown'"); + if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetTargetDevice", out _logiLedSetTargetDevicePointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetTargetDevice'"); + if (!NativeLibrary.TryGetExport(_handle, "LogiLedGetSdkVersion", out _logiLedGetSdkVersionPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedGetSdkVersion'"); + if (!NativeLibrary.TryGetExport(_handle, "LogiLedSaveCurrentLighting", out _lgiLedSaveCurrentLightingPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSaveCurrentLighting'"); + if (!NativeLibrary.TryGetExport(_handle, "LogiLedRestoreLighting", out _logiLedRestoreLightingPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedRestoreLighting'"); + if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetLighting", out _logiLedSetLightingPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetLighting'"); + if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetLightingForKeyWithKeyName", out _logiLedSetLightingForKeyWithKeyNamePointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetLightingForKeyWithKeyName'"); + if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetLightingFromBitmap", out _logiLedSetLightingFromBitmapPointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetLightingFromBitmap'"); + if (!NativeLibrary.TryGetExport(_handle, "LogiLedSetLightingForTargetZone", out _logiLedSetLightingForTargetZonePointer)) throw new RGBDeviceException("Failed to load Logitech function 'LogiLedSetLightingForTargetZone'"); + } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool LogiLedSaveCurrentLightingPointer(); + private static IEnumerable GetPossibleLibraryPaths() + { + IEnumerable possibleLibraryPaths; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool LogiLedRestoreLightingPointer(); + if (OperatingSystem.IsWindows()) + possibleLibraryPaths = Environment.Is64BitProcess ? LogitechDeviceProvider.PossibleX64NativePaths : LogitechDeviceProvider.PossibleX86NativePaths; + else + possibleLibraryPaths = Enumerable.Empty(); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool LogiLedSetLightingPointer(int redPercentage, int greenPercentage, int bluePercentage); + return possibleLibraryPaths.Select(Environment.ExpandEnvironmentVariables); + } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool LogiLedSetLightingForKeyWithKeyNamePointer(int keyCode, int redPercentage, int greenPercentage, int bluePercentage); + internal static void UnloadLogitechGSDK() + { + if (_handle == IntPtr.Zero) return; + + _logiLedInitPointer = IntPtr.Zero; + _logiLedShutdownPointer = IntPtr.Zero; + _logiLedSetTargetDevicePointer = IntPtr.Zero; + _logiLedGetSdkVersionPointer = IntPtr.Zero; + _lgiLedSaveCurrentLightingPointer = IntPtr.Zero; + _logiLedRestoreLightingPointer = IntPtr.Zero; + _logiLedSetLightingPointer = IntPtr.Zero; + _logiLedSetLightingForKeyWithKeyNamePointer = IntPtr.Zero; + _logiLedSetLightingFromBitmapPointer = IntPtr.Zero; + _logiLedSetLightingForTargetZonePointer = IntPtr.Zero; + + NativeLibrary.Free(_handle); + _handle = IntPtr.Zero; + } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool LogiLedSetLightingFromBitmapPointer(byte[] bitmap); + #endregion - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool LogiLedSetLightingForTargetZonePointer(LogitechDeviceType deviceType, int zone, int redPercentage, int greenPercentage, int bluePercentage); + #region SDK-METHODS - #endregion + #region Pointers - // ReSharper disable EventExceptionNotDocumented + private static IntPtr _logiLedInitPointer; + private static IntPtr _logiLedShutdownPointer; + private static IntPtr _logiLedSetTargetDevicePointer; + private static IntPtr _logiLedGetSdkVersionPointer; + private static IntPtr _lgiLedSaveCurrentLightingPointer; + private static IntPtr _logiLedRestoreLightingPointer; + private static IntPtr _logiLedSetLightingPointer; + private static IntPtr _logiLedSetLightingForKeyWithKeyNamePointer; + private static IntPtr _logiLedSetLightingFromBitmapPointer; + private static IntPtr _logiLedSetLightingForTargetZonePointer; - internal static bool LogiLedInit() => _logiLedInitPointer(); + #endregion - internal static void LogiLedShutdown() => _logiLedShutdownPointer(); + internal static unsafe bool LogiLedInit() + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_logiLedInitPointer))(); - internal static bool LogiLedSetTargetDevice(LogitechDeviceCaps targetDevice) => _logiLedSetTargetDevicePointer((int)targetDevice); + internal static unsafe void LogiLedShutdown() + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_logiLedShutdownPointer))(); - internal static string LogiLedGetSdkVersion() - { - int major = 0; - int minor = 0; - int build = 0; - LogiLedGetSdkVersion(ref major, ref minor, ref build); + internal static unsafe bool LogiLedSetTargetDevice(LogitechDeviceCaps targetDevice) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_logiLedSetTargetDevicePointer))((int)targetDevice); - return $"{major}.{minor}.{build}"; - } + internal static string LogiLedGetSdkVersion() + { + int major = 0; + int minor = 0; + int build = 0; + LogiLedGetSdkVersion(ref major, ref minor, ref build); - internal static bool LogiLedGetSdkVersion(ref int majorNum, ref int minorNum, ref int buildNum) => _logiLedGetSdkVersionPointer(ref majorNum, ref minorNum, ref buildNum); + return $"{major}.{minor}.{build}"; + } - internal static bool LogiLedSaveCurrentLighting() => _lgiLedSaveCurrentLightingPointer(); + internal static unsafe bool LogiLedGetSdkVersion(ref int majorNum, ref int minorNum, ref int buildNum) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_logiLedGetSdkVersionPointer))(ref majorNum, ref minorNum, ref buildNum); - internal static bool LogiLedRestoreLighting() => _logiLedRestoreLightingPointer(); + internal static unsafe bool LogiLedSaveCurrentLighting() + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_lgiLedSaveCurrentLightingPointer))(); - internal static bool LogiLedSetLighting(int redPercentage, int greenPercentage, int bluePercentage) => _logiLedSetLightingPointer(redPercentage, greenPercentage, bluePercentage); + internal static unsafe bool LogiLedRestoreLighting() + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_logiLedRestoreLightingPointer))(); - internal static bool LogiLedSetLightingForKeyWithKeyName(int keyCode, int redPercentage, int greenPercentage, int bluePercentage) - => _logiLedSetLightingForKeyWithKeyNamePointer(keyCode, redPercentage, greenPercentage, bluePercentage); + internal static unsafe bool LogiLedSetLighting(int redPercentage, int greenPercentage, int bluePercentage) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_logiLedSetLightingPointer))(redPercentage, greenPercentage, bluePercentage); - internal static bool LogiLedSetLightingFromBitmap(byte[] bitmap) => _logiLedSetLightingFromBitmapPointer(bitmap); + internal static unsafe bool LogiLedSetLightingForKeyWithKeyName(int keyCode, int redPercentage, int greenPercentage, int bluePercentage) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_logiLedSetLightingForKeyWithKeyNamePointer))(keyCode, redPercentage, greenPercentage, bluePercentage); - internal static bool LogiLedSetLightingForTargetZone(LogitechDeviceType deviceType, int zone, int redPercentage, int greenPercentage, int bluePercentage) - => _logiLedSetLightingForTargetZonePointer(deviceType, zone, redPercentage, greenPercentage, bluePercentage); + internal static unsafe bool LogiLedSetLightingFromBitmap(byte[] bitmap) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_logiLedSetLightingFromBitmapPointer))(bitmap); - // ReSharper restore EventExceptionNotDocumented + internal static unsafe bool LogiLedSetLightingForTargetZone(LogitechDeviceType deviceType, int zone, int redPercentage, int greenPercentage, int bluePercentage) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_logiLedSetLightingForTargetZonePointer))(deviceType, zone, redPercentage, greenPercentage, bluePercentage); - #endregion + private static IntPtr ThrowIfZero(IntPtr ptr) + { + if (ptr == IntPtr.Zero) throw new RGBDeviceException("The Logitech-SDK is not initialized."); + return ptr; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs index 42ff262d..9fdbc79b 100644 --- a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceRGBDevice.cs @@ -2,44 +2,48 @@ using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.Logitech +namespace RGB.NET.Devices.Logitech; + +/// +/// +/// Represents a logitech per-device-lightable device. +/// +public class LogitechPerDeviceRGBDevice : LogitechRGBDevice, IUnknownDevice //TODO DarthAffe 18.04.2020: It's know which kind of device this is, but they would need to be separated { - /// + #region Properties & Fields + + private readonly LedMapping _ledMapping; + + #endregion + + #region Constructors + + /// /// - /// Represents a logitech per-device-lightable device. + /// Initializes a new instance of the class. /// - public class LogitechPerDeviceRGBDevice : LogitechRGBDevice, IUnknownDevice //TODO DarthAffe 18.04.2020: It's know which kind of device this is, but they would need to be separated + internal LogitechPerDeviceRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue, LedMapping ledMapping) + : base(info, updateQueue) { - #region Constructors + this._ledMapping = ledMapping; - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by logitech for the per-device-lightable device - internal LogitechPerDeviceRGBDevice(LogitechRGBDeviceInfo info) - : base(info) - { } - - #endregion + InitializeLayout(); + } - #region Methods + #endregion - /// - protected override void InitializeLayout() - { - base.InitializeLayout(); + #region Methods - if (LedMapping.Count == 0) - InitializeLed(LedId.Custom1, new Rectangle(0, 0, 10, 10)); - } + private void InitializeLayout() + { + AddLed(LedId.Custom1, new Point(0, 0), new Size(10, 10)); + } - /// - protected override object CreateLedCustomData(LedId ledId) => (ledId, LogitechLedId.DEVICE); + /// + protected override object GetLedCustomData(LedId ledId) => _ledMapping[ledId]; - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0).Take(1)); + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate.Take(1))); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs index 8ea4c6aa..a3e88017 100644 --- a/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs +++ b/RGB.NET.Devices.Logitech/PerDevice/LogitechPerDeviceUpdateQueue.cs @@ -1,42 +1,39 @@ using System; -using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.Logitech.Native; -namespace RGB.NET.Devices.Logitech +namespace RGB.NET.Devices.Logitech; + +/// +/// +/// Represents the update-queue performing updates for logitech per-device devices. +/// +public class LogitechPerDeviceUpdateQueue : UpdateQueue { - /// + #region Constructors + /// - /// Represents the update-queue performing updates for logitech per-device devices. + /// Initializes a new instance of the class. /// - public class LogitechPerDeviceUpdateQueue : UpdateQueue - { - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - public LogitechPerDeviceUpdateQueue(IDeviceUpdateTrigger updateTrigger) - : base(updateTrigger) - { } + /// The update trigger used by this queue. + public LogitechPerDeviceUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void Update(Dictionary dataSet) - { - Color color = dataSet.Values.First(); - - _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.DeviceRGB); - _LogitechGSDK.LogiLedSetLighting((int)Math.Round(color.R * 100), - (int)Math.Round(color.G * 100), - (int)Math.Round(color.B * 100)); - } + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + Color color = dataSet[0].color; - #endregion + _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.DeviceRGB); + _LogitechGSDK.LogiLedSetLighting((int)Math.Round(color.R * 100), + (int)Math.Round(color.G * 100), + (int)Math.Round(color.B * 100)); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs b/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs deleted file mode 100644 index 9bd9a6e8..00000000 --- a/RGB.NET.Devices.Logitech/PerKey/BitmapMapping.cs +++ /dev/null @@ -1,169 +0,0 @@ -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Logitech -{ - internal static class BitmapMapping - { - #region Constants - - private const int BITMAP_SIZE = 21 * 6 * 4; - - #endregion - - #region Properties & Fields - - internal static Dictionary BitmapOffset { get; } = new Dictionary - { - { LedId.Keyboard_Escape, 0 }, - { LedId.Keyboard_F1, 4 }, - { LedId.Keyboard_F2, 8 }, - { LedId.Keyboard_F3, 12 }, - { LedId.Keyboard_F4, 16 }, - { LedId.Keyboard_F5, 20 }, - { LedId.Keyboard_F6, 24 }, - { LedId.Keyboard_F7, 28 }, - { LedId.Keyboard_F8, 32 }, - { LedId.Keyboard_F9, 36 }, - { LedId.Keyboard_F10, 40 }, - { LedId.Keyboard_F11, 44 }, - { LedId.Keyboard_F12, 48 }, - { LedId.Keyboard_PrintScreen, 52 }, - { LedId.Keyboard_ScrollLock, 56 }, - { LedId.Keyboard_PauseBreak, 60 }, - // { LedId.Keyboard_?, 64 }, - // { LedId.Keyboard_?, 68 }, - // { LedId.Keyboard_?, 72 }, - // { LedId.Keyboard_?, 76 }, - // { LedId.Keyboard_?, 80 }, - - { LedId.Keyboard_GraveAccentAndTilde, 84 }, - { LedId.Keyboard_1, 88 }, - { LedId.Keyboard_2, 92 }, - { LedId.Keyboard_3, 96 }, - { LedId.Keyboard_4, 100 }, - { LedId.Keyboard_5, 104 }, - { LedId.Keyboard_6, 108 }, - { LedId.Keyboard_7, 112 }, - { LedId.Keyboard_8, 116 }, - { LedId.Keyboard_9, 120 }, - { LedId.Keyboard_0, 124 }, - { LedId.Keyboard_MinusAndUnderscore, 128 }, - { LedId.Keyboard_EqualsAndPlus, 132 }, - { LedId.Keyboard_Backspace, 136 }, - { LedId.Keyboard_Insert, 140 }, - { LedId.Keyboard_Home, 144 }, - { LedId.Keyboard_PageUp, 148 }, - { LedId.Keyboard_NumLock, 152 }, - { LedId.Keyboard_NumSlash, 156 }, - { LedId.Keyboard_NumAsterisk, 160 }, - { LedId.Keyboard_NumMinus, 164 }, - - { LedId.Keyboard_Tab, 168 }, - { LedId.Keyboard_Q, 172 }, - { LedId.Keyboard_W, 176 }, - { LedId.Keyboard_E, 180 }, - { LedId.Keyboard_R, 184 }, - { LedId.Keyboard_T, 188 }, - { LedId.Keyboard_Y, 192 }, - { LedId.Keyboard_U, 196 }, - { LedId.Keyboard_I, 200 }, - { LedId.Keyboard_O, 204 }, - { LedId.Keyboard_P, 208 }, - { LedId.Keyboard_BracketLeft, 212 }, - { LedId.Keyboard_BracketRight, 216 }, - // { LedId.Keyboard_?, 220 }, - { LedId.Keyboard_Delete, 224 }, - { LedId.Keyboard_End, 228 }, - { LedId.Keyboard_PageDown, 232 }, - { LedId.Keyboard_Num7, 236 }, - { LedId.Keyboard_Num8, 240 }, - { LedId.Keyboard_Num9, 244 }, - { LedId.Keyboard_NumPlus, 248 }, - - { LedId.Keyboard_CapsLock, 252 }, - { LedId.Keyboard_A, 256 }, - { LedId.Keyboard_S, 260 }, - { LedId.Keyboard_D, 264 }, - { LedId.Keyboard_F, 268 }, - { LedId.Keyboard_G, 272 }, - { LedId.Keyboard_H, 276 }, - { LedId.Keyboard_J, 280 }, - { LedId.Keyboard_K, 284 }, - { LedId.Keyboard_L, 288 }, - { LedId.Keyboard_SemicolonAndColon, 292 }, - { LedId.Keyboard_ApostropheAndDoubleQuote, 296 }, - { LedId.Keyboard_NonUsTilde, 300 }, //TODO DarthAffe 26.03.2017: Find the real ID/Name of this key - it's not documented ... - { LedId.Keyboard_Enter, 304 }, - // { LedId.Keyboard_?, 308 }, - // { LedId.Keyboard_?, 312 }, - // { LedId.Keyboard_?, 316 }, - { LedId.Keyboard_Num4, 320 }, - { LedId.Keyboard_Num5, 324 }, - { LedId.Keyboard_Num6, 328 }, - // { LedId.Keyboard_?, 332 }, - - { LedId.Keyboard_LeftShift, 336 }, - { LedId.Keyboard_Backslash, 340 }, - { LedId.Keyboard_Z, 344 }, - { LedId.Keyboard_X, 348 }, - { LedId.Keyboard_C, 352 }, - { LedId.Keyboard_V, 356 }, - { LedId.Keyboard_B, 360 }, - { LedId.Keyboard_N, 364 }, - { LedId.Keyboard_M, 368 }, - { LedId.Keyboard_CommaAndLessThan, 372 }, - { LedId.Keyboard_PeriodAndBiggerThan, 376 }, - { LedId.Keyboard_SlashAndQuestionMark, 380 }, - { LedId.Keyboard_RightShift, 388 }, - // { LedId.Keyboard_?, 392 }, - { LedId.Keyboard_ArrowUp, 396 }, - // { LedId.Keyboard_?, 400 }, - { LedId.Keyboard_Num1, 404 }, - { LedId.Keyboard_Num2, 408 }, - { LedId.Keyboard_Num3, 412 }, - { LedId.Keyboard_NumEnter, 416 }, - - { LedId.Keyboard_LeftCtrl, 420 }, - { LedId.Keyboard_LeftGui, 424 }, - { LedId.Keyboard_LeftAlt, 428 }, - // { LedId.Keyboard_?, 432 }, - // { LedId.Keyboard_?, 436 }, - { LedId.Keyboard_Space, 440 }, - // { LedId.Keyboard_?, 444 }, - // { LedId.Keyboard_?, 448 }, - // { LedId.Keyboard_?, 452 }, - // { LedId.Keyboard_?, 456 }, - // { LedId.Keyboard_?, 460 }, - { LedId.Keyboard_RightAlt, 464 }, - { LedId.Keyboard_RightGui, 468 }, - { LedId.Keyboard_Application, 472 }, - { LedId.Keyboard_RightCtrl, 476 }, - { LedId.Keyboard_ArrowLeft, 480 }, - { LedId.Keyboard_ArrowDown, 484 }, - { LedId.Keyboard_ArrowRight, 488 }, - { LedId.Keyboard_Num0, 492 }, - { LedId.Keyboard_NumPeriodAndDelete, 496 }, - // { LedId.Keyboard_?, 500 }, - }; - - #endregion - - #region Methods - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static byte[] CreateBitmap() => new byte[BITMAP_SIZE]; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static void SetColor(byte[] bitmap, int offset, Color color) - { - bitmap[offset] = color.GetB(); - bitmap[offset + 1] = color.GetG(); - bitmap[offset + 2] = color.GetR(); - bitmap[offset + 3] = color.GetA(); - } - - #endregion - } -} diff --git a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs index e5e3f404..933603ff 100644 --- a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyRGBDevice.cs @@ -1,36 +1,41 @@ using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.Logitech +namespace RGB.NET.Devices.Logitech; + +/// +/// +/// Represents a logitech per-key-lightable device. +/// +public class LogitechPerKeyRGBDevice : LogitechRGBDevice, IUnknownDevice //TODO DarthAffe 18.04.2020: It's know which kind of device this is, but they would need to be separated { - /// + #region Properties & Fields + + private readonly LedMapping _ledMapping; + + #endregion + + #region Constructors + + /// /// - /// Represents a logitech per-key-lightable device. + /// Initializes a new instance of the class. /// - public class LogitechPerKeyRGBDevice : LogitechRGBDevice, IUnknownDevice //TODO DarthAffe 18.04.2020: It's know which kind of device this is, but they would need to be separated + internal LogitechPerKeyRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue, LedMapping ledMapping) + : base(info, updateQueue) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by logitech for the per-key-lightable device - internal LogitechPerKeyRGBDevice(LogitechRGBDeviceInfo info) - : base(info) - { } + this._ledMapping = ledMapping; + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override object CreateLedCustomData(LedId ledId) => (ledId, PerKeyIdMapping.DEFAULT.TryGetValue(ledId, out LogitechLedId logitechLedId) ? logitechLedId : LogitechLedId.Invalid); + /// + protected override object GetLedCustomData(LedId ledId) => _ledMapping.TryGetValue(ledId, out LogitechLedId logitechLedId) ? logitechLedId : -1; - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs index a166a3a8..3b75a3b0 100644 --- a/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs +++ b/RGB.NET.Devices.Logitech/PerKey/LogitechPerKeyUpdateQueue.cs @@ -1,65 +1,44 @@ using System; -using System.Collections.Generic; using RGB.NET.Core; using RGB.NET.Devices.Logitech.Native; -namespace RGB.NET.Devices.Logitech +namespace RGB.NET.Devices.Logitech; + +/// +/// Represents the update-queue performing updates for logitech per-key devices. +/// +public class LogitechPerKeyUpdateQueue : UpdateQueue { + #region Constructors + /// - /// Represents the update-queue performing updates for logitech per-key devices. + /// Initializes a new instance of the class. /// - public class LogitechPerKeyUpdateQueue : UpdateQueue + /// The update trigger used by this queue. + public LogitechPerKeyUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) { - #region Properties & Fields - - private readonly byte[] _bitmap; - - #endregion - - #region Constructors + } - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - public LogitechPerKeyUpdateQueue(IDeviceUpdateTrigger updateTrigger) - : base(updateTrigger) - { - _bitmap = BitmapMapping.CreateBitmap(); - } + #endregion - #endregion + #region Methods - #region Methods + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.PerKeyRGB); - /// - protected override void Update(Dictionary dataSet) + foreach ((object key, Color color) in dataSet) { - _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.PerKeyRGB); - - Array.Clear(_bitmap, 0, _bitmap.Length); - bool usesBitmap = false; - foreach (KeyValuePair data in dataSet) - { - (LedId id, LogitechLedId customData) = ((LedId, LogitechLedId))data.Key; - - // DarthAffe 26.03.2017: This is only needed since update by name doesn't work as expected for all keys ... - if (BitmapMapping.BitmapOffset.TryGetValue(id, out int bitmapOffset)) - { - BitmapMapping.SetColor(_bitmap, bitmapOffset, data.Value); - usesBitmap = true; - } - else - _LogitechGSDK.LogiLedSetLightingForKeyWithKeyName((int)customData, - (int)Math.Round(data.Value.R * 100), - (int)Math.Round(data.Value.G * 100), - (int)Math.Round(data.Value.B * 100)); - } - - if (usesBitmap) - _LogitechGSDK.LogiLedSetLightingFromBitmap(_bitmap); + // These will be LogitechLedId but the SDK expects an int and doesn't care about invalid values + int keyName = (int)key; + _LogitechGSDK.LogiLedSetLightingForKeyWithKeyName(keyName, + (int)MathF.Round(color.R * 100), + (int)MathF.Round(color.G * 100), + (int)MathF.Round(color.B * 100)); } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/PerKey/PerKeyIdMapping.cs b/RGB.NET.Devices.Logitech/PerKey/PerKeyIdMapping.cs deleted file mode 100644 index 68d2cf4f..00000000 --- a/RGB.NET.Devices.Logitech/PerKey/PerKeyIdMapping.cs +++ /dev/null @@ -1,129 +0,0 @@ -using System.Collections.Generic; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Logitech -{ - internal static class PerKeyIdMapping - { - internal static readonly Dictionary DEFAULT = new Dictionary - { - { LedId.Invalid, LogitechLedId.Invalid }, - { LedId.Keyboard_Escape, LogitechLedId.ESC }, - { LedId.Keyboard_F1, LogitechLedId.F1 }, - { LedId.Keyboard_F2, LogitechLedId.F2 }, - { LedId.Keyboard_F3, LogitechLedId.F3 }, - { LedId.Keyboard_F4, LogitechLedId.F4 }, - { LedId.Keyboard_F5, LogitechLedId.F5 }, - { LedId.Keyboard_F6, LogitechLedId.F6 }, - { LedId.Keyboard_F7, LogitechLedId.F7 }, - { LedId.Keyboard_F8, LogitechLedId.F8 }, - { LedId.Keyboard_F9, LogitechLedId.F9 }, - { LedId.Keyboard_F10, LogitechLedId.F10 }, - { LedId.Keyboard_F11, LogitechLedId.F11 }, - { LedId.Keyboard_GraveAccentAndTilde, LogitechLedId.TILDE }, - { LedId.Keyboard_1, LogitechLedId.ONE }, - { LedId.Keyboard_2, LogitechLedId.TWO }, - { LedId.Keyboard_3, LogitechLedId.THREE }, - { LedId.Keyboard_4, LogitechLedId.FOUR }, - { LedId.Keyboard_5, LogitechLedId.FIVE }, - { LedId.Keyboard_6, LogitechLedId.SIX }, - { LedId.Keyboard_7, LogitechLedId.SEVEN }, - { LedId.Keyboard_8, LogitechLedId.EIGHT }, - { LedId.Keyboard_9, LogitechLedId.NINE }, - { LedId.Keyboard_0, LogitechLedId.ZERO }, - { LedId.Keyboard_MinusAndUnderscore, LogitechLedId.MINUS }, - { LedId.Keyboard_Tab, LogitechLedId.TAB }, - { LedId.Keyboard_Q, LogitechLedId.Q }, - { LedId.Keyboard_W, LogitechLedId.W }, - { LedId.Keyboard_E, LogitechLedId.E }, - { LedId.Keyboard_R, LogitechLedId.R }, - { LedId.Keyboard_T, LogitechLedId.T }, - { LedId.Keyboard_Y, LogitechLedId.Y }, - { LedId.Keyboard_U, LogitechLedId.U }, - { LedId.Keyboard_I, LogitechLedId.I }, - { LedId.Keyboard_O, LogitechLedId.O }, - { LedId.Keyboard_P, LogitechLedId.P }, - { LedId.Keyboard_BracketLeft, LogitechLedId.OPEN_BRACKET }, - { LedId.Keyboard_CapsLock, LogitechLedId.CAPS_LOCK }, - { LedId.Keyboard_A, LogitechLedId.A }, - { LedId.Keyboard_S, LogitechLedId.S }, - { LedId.Keyboard_D, LogitechLedId.D }, - { LedId.Keyboard_F, LogitechLedId.F }, - { LedId.Keyboard_G, LogitechLedId.G }, - { LedId.Keyboard_H, LogitechLedId.H }, - { LedId.Keyboard_J, LogitechLedId.J }, - { LedId.Keyboard_K, LogitechLedId.K }, - { LedId.Keyboard_L, LogitechLedId.L }, - { LedId.Keyboard_SemicolonAndColon, LogitechLedId.SEMICOLON }, - { LedId.Keyboard_ApostropheAndDoubleQuote, LogitechLedId.APOSTROPHE }, - { LedId.Keyboard_LeftShift, LogitechLedId.LEFT_SHIFT }, - { LedId.Keyboard_Z, LogitechLedId.Z }, - { LedId.Keyboard_X, LogitechLedId.X }, - { LedId.Keyboard_C, LogitechLedId.C }, - { LedId.Keyboard_V, LogitechLedId.V }, - { LedId.Keyboard_B, LogitechLedId.B }, - { LedId.Keyboard_N, LogitechLedId.N }, - { LedId.Keyboard_M, LogitechLedId.M }, - { LedId.Keyboard_CommaAndLessThan, LogitechLedId.COMMA }, - { LedId.Keyboard_PeriodAndBiggerThan, LogitechLedId.PERIOD }, - { LedId.Keyboard_SlashAndQuestionMark, LogitechLedId.FORWARD_SLASH }, - { LedId.Keyboard_LeftCtrl, LogitechLedId.LEFT_CONTROL }, - { LedId.Keyboard_LeftGui, LogitechLedId.LEFT_WINDOWS }, - { LedId.Keyboard_LeftAlt, LogitechLedId.LEFT_ALT }, - { LedId.Keyboard_Space, LogitechLedId.SPACE }, - { LedId.Keyboard_RightAlt, LogitechLedId.RIGHT_ALT }, - { LedId.Keyboard_RightGui, LogitechLedId.RIGHT_WINDOWS }, - { LedId.Keyboard_Application, LogitechLedId.APPLICATION_SELECT }, - { LedId.Keyboard_F12, LogitechLedId.F12 }, - { LedId.Keyboard_PrintScreen, LogitechLedId.PRINT_SCREEN }, - { LedId.Keyboard_ScrollLock, LogitechLedId.SCROLL_LOCK }, - { LedId.Keyboard_PauseBreak, LogitechLedId.PAUSE_BREAK }, - { LedId.Keyboard_Insert, LogitechLedId.INSERT }, - { LedId.Keyboard_Home, LogitechLedId.HOME }, - { LedId.Keyboard_PageUp, LogitechLedId.PAGE_UP }, - { LedId.Keyboard_BracketRight, LogitechLedId.CLOSE_BRACKET }, - { LedId.Keyboard_Backslash, LogitechLedId.BACKSLASH }, - { LedId.Keyboard_NonUsTilde, LogitechLedId.NonUsTilde }, - { LedId.Keyboard_Enter, LogitechLedId.ENTER }, - { LedId.Keyboard_EqualsAndPlus, LogitechLedId.EQUALS }, - { LedId.Keyboard_Backspace, LogitechLedId.BACKSPACE }, - { LedId.Keyboard_Delete, LogitechLedId.KEYBOARD_DELETE }, - { LedId.Keyboard_End, LogitechLedId.END }, - { LedId.Keyboard_PageDown, LogitechLedId.PAGE_DOWN }, - { LedId.Keyboard_RightShift, LogitechLedId.RIGHT_SHIFT }, - { LedId.Keyboard_RightCtrl, LogitechLedId.RIGHT_CONTROL }, - { LedId.Keyboard_ArrowUp, LogitechLedId.ARROW_UP }, - { LedId.Keyboard_ArrowLeft, LogitechLedId.ARROW_LEFT }, - { LedId.Keyboard_ArrowDown, LogitechLedId.ARROW_DOWN }, - { LedId.Keyboard_ArrowRight, LogitechLedId.ARROW_RIGHT }, - { LedId.Keyboard_NumLock, LogitechLedId.NUM_LOCK }, - { LedId.Keyboard_NumSlash, LogitechLedId.NUM_SLASH }, - { LedId.Keyboard_NumAsterisk, LogitechLedId.NUM_ASTERISK }, - { LedId.Keyboard_NumMinus, LogitechLedId.NUM_MINUS }, - { LedId.Keyboard_NumPlus, LogitechLedId.NUM_PLUS }, - { LedId.Keyboard_NumEnter, LogitechLedId.NUM_ENTER }, - { LedId.Keyboard_Num7, LogitechLedId.NUM_SEVEN }, - { LedId.Keyboard_Num8, LogitechLedId.NUM_EIGHT }, - { LedId.Keyboard_Num9, LogitechLedId.NUM_NINE }, - { LedId.Keyboard_Num4, LogitechLedId.NUM_FOUR }, - { LedId.Keyboard_Num5, LogitechLedId.NUM_FIVE }, - { LedId.Keyboard_Num6, LogitechLedId.NUM_SIX }, - { LedId.Keyboard_Num1, LogitechLedId.NUM_ONE }, - { LedId.Keyboard_Num2, LogitechLedId.NUM_TWO }, - { LedId.Keyboard_Num3, LogitechLedId.NUM_THREE }, - { LedId.Keyboard_Num0, LogitechLedId.NUM_ZERO }, - { LedId.Keyboard_NumPeriodAndDelete, LogitechLedId.NUM_PERIOD }, - { LedId.Keyboard_Programmable1, LogitechLedId.G_1 }, - { LedId.Keyboard_Programmable2, LogitechLedId.G_2 }, - { LedId.Keyboard_Programmable3, LogitechLedId.G_3 }, - { LedId.Keyboard_Programmable4, LogitechLedId.G_4 }, - { LedId.Keyboard_Programmable5, LogitechLedId.G_5 }, - { LedId.Keyboard_Programmable6, LogitechLedId.G_6 }, - { LedId.Keyboard_Programmable7, LogitechLedId.G_7 }, - { LedId.Keyboard_Programmable8, LogitechLedId.G_8 }, - { LedId.Keyboard_Programmable9, LogitechLedId.G_9 }, - { LedId.Logo, LogitechLedId.G_LOGO }, - { LedId.Keyboard_Custom1, LogitechLedId.G_BADGE }, - }; - } -} diff --git a/RGB.NET.Devices.Logitech/README.md b/RGB.NET.Devices.Logitech/README.md new file mode 100644 index 00000000..67cc2d76 --- /dev/null +++ b/RGB.NET.Devices.Logitech/README.md @@ -0,0 +1,27 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for Logitech-Devices. + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(LogitechDeviceProvider.Instance); +``` + +Since the logitech SDK does not provide device information only known devices will work. +You can add detection for additional devices by adding entires for them to the respective static `DeviceDefinitions` on the `LogitechDeviceProvider`. + +# Required SDK +This providers requires native SDK-dlls. +You can get them directly from Logitech at [https://www.logitechg.com/en-us/innovation/developer-lab.html](https://www.logitechg.com/en-us/innovation/developer-lab.html) (Direct Link: [https://www.logitechg.com/sdk/LED_SDK_9.00.zip](https://www.logitechg.com/sdk/LED_SDK_9.00.zip)) + +Since the SDK-dlls are native it's important to use the correct architecture you're building your application for. (If in doubt you can always include both.) + +### x64 +`Lib\LogitechLedEnginesWrapper\x64\LogitechLedEnginesWrapper.dll` from the SDK-zip needs to be distributed as `\x64\LogitechLedEnginesWrapper.dll` + +You can use other, custom paths by adding them to `LogitechDeviceProvider.PossibleX64NativePaths`. + +### x86 +`Lib\LogitechLedEnginesWrapper\x86\LogitechLedEnginesWrapper.dll` from the SDK-zip needs to be distributed as `\x86\LogitechLedEnginesWrapper.dll` + +You can use other, custom paths by adding them to `LogitechDeviceProvider.PossibleX86NativePaths`. diff --git a/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj b/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj index 220b2052..7ee22dd4 100644 --- a/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj +++ b/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.Logitech Logitech-Device-Implementations of RGB.NET Logitech-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,37 +35,30 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg + true $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - - + + - - + + + \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj.DotSettings b/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj.DotSettings index e94069e2..cb84f1e6 100644 --- a/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj.DotSettings +++ b/RGB.NET.Devices.Logitech/RGB.NET.Devices.Logitech.csproj.DotSettings @@ -6,4 +6,5 @@ True True True - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs b/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs index 419e796d..88208349 100644 --- a/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs +++ b/RGB.NET.Devices.Logitech/Zone/LogitechZoneRGBDevice.cs @@ -1,66 +1,48 @@ using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.Logitech -{ - /// - /// - /// Represents a logitech zone-lightable device. - /// - public class LogitechZoneRGBDevice : LogitechRGBDevice, IUnknownDevice //TODO DarthAffe 18.04.2020: It's know which kind of device this is, but they would need to be separated - { - #region Constants +namespace RGB.NET.Devices.Logitech; - private static readonly Dictionary BASE_LED_MAPPING = new Dictionary - { - {RGBDeviceType.Keyboard, LedId.Keyboard_Programmable1}, - {RGBDeviceType.Mouse, LedId.Mouse1}, - {RGBDeviceType.Headset, LedId.Headset1}, - {RGBDeviceType.Mousepad, LedId.Mousepad1}, - {RGBDeviceType.Speaker, LedId.Speaker1} - }; - - #endregion - - #region Properties & Fields - - private LedId _baseLedId; +/// +/// +/// Represents a logitech zone-lightable device. +/// +public class LogitechZoneRGBDevice : LogitechRGBDevice, IUnknownDevice //TODO DarthAffe 18.04.2020: It's know which kind of device this is, but they would need to be separated +{ + #region Properties & Fields - #endregion + private readonly LedMapping _ledMapping; - #region Constructors + #endregion - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by logitech for the zone-lightable device - internal LogitechZoneRGBDevice(LogitechRGBDeviceInfo info) - : base(info) - { - _baseLedId = BASE_LED_MAPPING.TryGetValue(info.DeviceType, out LedId id) ? id : LedId.Custom1; - } + #region Constructors - #endregion + /// + /// + /// Initializes a new instance of the class. + /// + internal LogitechZoneRGBDevice(LogitechRGBDeviceInfo info, IUpdateQueue updateQueue, LedMapping ledMapping) + : base(info, updateQueue) + { + this._ledMapping = ledMapping; - #region Methods + InitializeLayout(); + } - /// - protected override void InitializeLayout() - { - for (int i = 0; i < DeviceInfo.Zones; i++) - InitializeLed(_baseLedId + i, new Rectangle(i * 10, 0, 10, 10)); + #endregion - base.InitializeLayout(); - } + #region Methods + private void InitializeLayout() + { + for (int i = DeviceInfo.ZoneOffset; i < (DeviceInfo.ZoneOffset + DeviceInfo.Zones); i++) + AddLed(_ledMapping[i], new Point(i * 10, 0), new Size(10, 10)); + } - /// - protected override object CreateLedCustomData(LedId ledId) => (int)(ledId - _baseLedId); + /// + protected override object GetLedCustomData(LedId ledId) => _ledMapping[ledId]; - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs b/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs index a95ca988..a76d5c50 100644 --- a/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs +++ b/RGB.NET.Devices.Logitech/Zone/LogitechZoneUpdateQueue.cs @@ -1,67 +1,51 @@ using System; -using System.Collections.Generic; using RGB.NET.Core; using RGB.NET.Devices.Logitech.Native; -namespace RGB.NET.Devices.Logitech -{ - /// - /// Represents the update-queue performing updates for logitech zone devices. - /// - public class LogitechZoneUpdateQueue : UpdateQueue - { - #region Constants +namespace RGB.NET.Devices.Logitech; - private static readonly Dictionary DEVICE_TYPE_MAPPING = new Dictionary - { - {RGBDeviceType.Keyboard, LogitechDeviceType.Keyboard}, - {RGBDeviceType.Mouse, LogitechDeviceType.Mouse}, - {RGBDeviceType.Headset, LogitechDeviceType.Headset}, - {RGBDeviceType.Mousepad, LogitechDeviceType.Mousemat}, - {RGBDeviceType.Speaker, LogitechDeviceType.Speaker} - }; - - #endregion +/// +/// Represents the update-queue performing updates for logitech zone devices. +/// +public class LogitechZoneUpdateQueue : UpdateQueue +{ + #region Properties & Fields - #region Properties & Fields + private readonly LogitechDeviceType _deviceType; - private readonly LogitechDeviceType _deviceType; + #endregion - #endregion + #region Constructors - #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The tpye of the device this queue is updating. + public LogitechZoneUpdateQueue(IDeviceUpdateTrigger updateTrigger, LogitechDeviceType deviceType) + : base(updateTrigger) + { + this._deviceType = deviceType; + } - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The tpye of the device this queue is updating. - public LogitechZoneUpdateQueue(IDeviceUpdateTrigger updateTrigger, RGBDeviceType deviceType) - : base(updateTrigger) - { - if (!DEVICE_TYPE_MAPPING.TryGetValue(deviceType, out _deviceType)) - throw new ArgumentException($"Invalid type '{deviceType.ToString()}'", nameof(deviceType)); - } + #endregion - #endregion + #region Methods - #region Methods + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.All); - /// - protected override void Update(Dictionary dataSet) + foreach ((object key, Color color) in dataSet) { - _LogitechGSDK.LogiLedSetTargetDevice(LogitechDeviceCaps.All); - - foreach (KeyValuePair data in dataSet) - { - int zone = (int)data.Key; - _LogitechGSDK.LogiLedSetLightingForTargetZone(_deviceType, zone, - (int)Math.Round(data.Value.R * 100), - (int)Math.Round(data.Value.G * 100), - (int)Math.Round(data.Value.B * 100)); - } + int zone = (int)key; + _LogitechGSDK.LogiLedSetLightingForTargetZone(_deviceType, zone, + (int)MathF.Round(color.R * 100), + (int)MathF.Round(color.G * 100), + (int)MathF.Round(color.B * 100)); } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/Exceptions/MysticLightException.cs b/RGB.NET.Devices.Msi/Exceptions/MysticLightException.cs index 0b125823..cf688e13 100644 --- a/RGB.NET.Devices.Msi/Exceptions/MysticLightException.cs +++ b/RGB.NET.Devices.Msi/Exceptions/MysticLightException.cs @@ -3,43 +3,42 @@ using System; -namespace RGB.NET.Devices.Msi.Exceptions +namespace RGB.NET.Devices.Msi.Exceptions; + +/// +/// +/// Represents an exception thrown by the MysticLight-SDK. +/// +public class MysticLightException : ApplicationException { + #region Properties & Fields + + /// + /// Gets the raw error code provided by the SDK. + /// + public int ErrorCode { get; } + + /// + /// Gets the text-description the resolves too. + /// + public string Description { get; } + + #endregion + + #region Constructors + /// /// - /// Represents an exception thrown by the MysticLight-SDK. + /// Initializes a new instance of the class. /// - public class MysticLightException : ApplicationException + /// The raw error code provided by the SDK. + /// The text-description of the error. + public MysticLightException(int errorCode, string description) + : base($"MSI error code {errorCode} ({description})") { - #region Properties & Fields - - /// - /// Gets the raw error code provided by the SDK. - /// - public int ErrorCode { get; } - - /// - /// Gets the text-description the resolves too. - /// - public string Description { get; } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The raw error code provided by the SDK. - /// The text-description of the error. - public MysticLightException(int errorCode, string description) - : base($"MSI error code {errorCode} ({description})") - { - this.ErrorCode = errorCode; - this.Description = description; - } - - #endregion + this.ErrorCode = errorCode; + this.Description = description; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs index cd09af00..b8807531 100644 --- a/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/IMsiRGBDevice.cs @@ -1,12 +1,9 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Msi -{ - /// - /// Represents a MSI RGB-device. - /// - internal interface IMsiRGBDevice : IRGBDevice - { - void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount); - } -} +namespace RGB.NET.Devices.Msi; + +/// +/// Represents a MSI RGB-device. +/// +public interface IMsiRGBDevice : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs b/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs index b2dffc01..d503148c 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiDeviceUpdateQueue.cs @@ -1,45 +1,44 @@ -using System.Collections.Generic; +using System; using RGB.NET.Core; using RGB.NET.Devices.Msi.Native; -namespace RGB.NET.Devices.Msi -{ - /// - /// - /// Represents the update-queue performing updates for MSI devices. - /// - public class MsiDeviceUpdateQueue : UpdateQueue - { - #region Properties & Fields +namespace RGB.NET.Devices.Msi; - private string _deviceType; +/// +/// +/// Represents the update-queue performing updates for MSI devices. +/// +public class MsiDeviceUpdateQueue : UpdateQueue +{ + #region Properties & Fields - #endregion + private string _deviceType; - #region Constructors + #endregion - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The device-type used to identify the device. - public MsiDeviceUpdateQueue(IDeviceUpdateTrigger updateTrigger, string deviceType) - : base(updateTrigger) - { - this._deviceType = deviceType; - } + #region Constructors - #endregion + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The device-type used to identify the device. + public MsiDeviceUpdateQueue(IDeviceUpdateTrigger updateTrigger, string deviceType) + : base(updateTrigger) + { + this._deviceType = deviceType; + } - #region Methods + #endregion - /// - protected override void Update(Dictionary dataSet) - { - foreach (KeyValuePair data in dataSet) - _MsiSDK.SetLedColor(_deviceType, (int)data.Key, data.Value.GetR(), data.Value.GetG(), data.Value.GetB()); - } + #region Methods - #endregion + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + foreach ((object key, Color color) in dataSet) + _MsiSDK.SetLedColor(_deviceType, (int)key, color.GetR(), color.GetG(), color.GetB()); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs index 258bf847..afe1d79a 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDevice.cs @@ -1,82 +1,24 @@ -using System.Collections.Generic; -using System.Linq; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Msi +namespace RGB.NET.Devices.Msi; + +/// +/// +/// Represents a generic MSI-device. (keyboard, mouse, headset, mousepad). +/// +public abstract class MsiRGBDevice : AbstractRGBDevice, IMsiRGBDevice + where TDeviceInfo : MsiRGBDeviceInfo { - /// - /// + #region Constructors + /// - /// Represents a generic MSI-device. (keyboard, mouse, headset, mousepad). + /// Initializes a new instance of the class. /// - public abstract class MsiRGBDevice : AbstractRGBDevice, IMsiRGBDevice - where TDeviceInfo : MsiRGBDeviceInfo - { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected MsiDeviceUpdateQueue DeviceUpdateQueue { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by MSI for the device. - protected MsiRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(MsiDeviceUpdateQueue updateQueue, int ledCount) - { - DeviceUpdateQueue = updateQueue; - - InitializeLayout(ledCount); - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(int ledCount); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) - => DeviceUpdateQueue.SetData(ledsToUpdate.Where(x => (x.Color.A > 0) && (x.CustomData is int))); - - /// - public override void Dispose() - { - try { DeviceUpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } - - #endregion - } -} + /// The generic information provided by MSI for the device. + /// The update trigger used to update this device. + protected MsiRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new MsiDeviceUpdateQueue(updateTrigger, info.MsiDeviceType)) + { } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs b/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs index 269d34e8..d1d490d3 100644 --- a/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Msi/Generic/MsiRGBDeviceInfo.cs @@ -1,63 +1,55 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Msi +namespace RGB.NET.Devices.Msi; + +/// +/// +/// Represents a generic information for a MSI-. +/// +public class MsiRGBDeviceInfo : IRGBDeviceInfo { + #region Properties & Fields + /// + public RGBDeviceType DeviceType { get; } + /// - /// Represents a generic information for a MSI-. + /// Gets the internal type of the . /// - public class MsiRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields - - /// - public RGBDeviceType DeviceType { get; } - - /// - /// Gets the internal type of the . - /// - public string MsiDeviceType { get; } - - /// - public string DeviceName { get; } - - /// - public string Manufacturer { get; } - - /// - public string Model { get; } + public string MsiDeviceType { get; } - /// - public Uri Image { get; set; } + /// + public string DeviceName { get; } - /// - public bool SupportsSyncBack => false; + /// + public string Manufacturer { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public string Model { get; } - #endregion + /// + public object? LayoutMetadata { get; set; } - #region Constructors + #endregion - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The internal type of the . - /// The manufacturer-name of the . - /// The model-name of the . - internal MsiRGBDeviceInfo(RGBDeviceType deviceType, string msiDeviceType, string manufacturer = "MSI", string model = "Generic Msi-Device") - { - this.DeviceType = deviceType; - this.MsiDeviceType = msiDeviceType; - this.Manufacturer = manufacturer; - this.Model = model; + #region Constructors - DeviceName = $"{Manufacturer} {Model}"; - } + /// + /// Internal constructor of managed . + /// + /// The type of the . + /// The internal type of the . + /// The manufacturer-name of the . + /// The model-name of the . + internal MsiRGBDeviceInfo(RGBDeviceType deviceType, string msiDeviceType, string manufacturer = "MSI", string model = "Generic Msi-Device") + { + this.DeviceType = deviceType; + this.MsiDeviceType = msiDeviceType; + this.Manufacturer = manufacturer; + this.Model = model; - #endregion + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs index 74bd6737..a4d72f15 100644 --- a/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs +++ b/RGB.NET.Devices.Msi/GraphicsCard/MsiGraphicsCardRGBDevice.cs @@ -1,56 +1,51 @@ using RGB.NET.Core; using RGB.NET.Devices.Msi.Native; -namespace RGB.NET.Devices.Msi +namespace RGB.NET.Devices.Msi; + +/// +/// +/// Represents MSI VGA adapters. +/// +public class MsiGraphicsCardRGBDevice : MsiRGBDevice, IGraphicsCard { - /// + #region Constructors + + /// /// - /// Represents MSI VGA adapters. + /// Initializes a new instance of the class. /// - public class MsiGraphicsCardRGBDevice : MsiRGBDevice, IGraphicsCard + /// The specific information provided by MSI for graphics cards. + /// The amount of leds on this device. + /// The update trigger used to update this device. + internal MsiGraphicsCardRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by MSI for graphics cards. - internal MsiGraphicsCardRGBDevice(MsiRGBDeviceInfo info) - : base(info) - { } + InitializeLayout(ledCount); + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void InitializeLayout(int ledCount) + private void InitializeLayout(int ledCount) + { + for (int i = 0; i < ledCount; i++) { - for (int i = 0; i < ledCount; i++) - { - //Hex3l: Should it be configurable in order to provide style access? - //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color - //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present - const string LED_STYLE = "Steady"; + //Hex3l: Should it be configurable in order to provide style access? + //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color + //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present + const string LED_STYLE = "Steady"; - //Hex3l: Every led is a video card adapter. + //Hex3l: Every led is a video card adapter. - _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); - InitializeLed(LedId.GraphicsCard1 + i, new Rectangle(i * 10, 0, 10, 10)); - } - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\MSI\GraphicsCard\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); + _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); + AddLed(LedId.GraphicsCard1 + i, new Point(i * 10, 0), new Size(10, 10)); } + } - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; - - /// - public override void SyncBack() - { } + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.GraphicsCard1; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs index 455e63a7..113d364a 100644 --- a/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Mainboard/MsiMainboardRGBDevice.cs @@ -1,54 +1,49 @@ using RGB.NET.Core; using RGB.NET.Devices.Msi.Native; -namespace RGB.NET.Devices.Msi +namespace RGB.NET.Devices.Msi; + +/// +/// +/// Represents a MSI mainboard. +/// +public class MsiMainboardRGBDevice : MsiRGBDevice, IMainboard { - /// + #region Constructors + + /// /// - /// Represents a MSI mainboard. + /// Initializes a new instance of the class. /// - public class MsiMainboardRGBDevice : MsiRGBDevice, IMainboard + /// The specific information provided by MSI for the mainboard. + /// The amount of leds on this device. + /// The update trigger used to update this device. + internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by MSI for the mainboard. - internal MsiMainboardRGBDevice(MsiRGBDeviceInfo info) - : base(info) - { } + InitializeLayout(ledCount); + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void InitializeLayout(int ledCount) + private void InitializeLayout(int ledCount) + { + for (int i = 0; i < ledCount; i++) { - for (int i = 0; i < ledCount; i++) - { - //Hex3l: Should it be configurable in order to provide style access? - //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color - //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present - const string LED_STYLE = "Steady"; - - _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); - InitializeLed(LedId.Mainboard1 + i, new Rectangle(i * 40, 0, 40, 8)); - } - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\MSI\Mainboards\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } + //Hex3l: Should it be configurable in order to provide style access? + //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color + //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present + const string LED_STYLE = "Steady"; - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; + _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); + AddLed(LedId.Mainboard1 + i, new Point(i * 40, 0), new Size(40, 8)); + } + } - /// - public override void SyncBack() - { } + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mainboard1; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs b/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs index bbcbd570..fc9adc87 100644 --- a/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs +++ b/RGB.NET.Devices.Msi/Mouse/MsiMouseRGBDevice.cs @@ -1,54 +1,49 @@ using RGB.NET.Core; using RGB.NET.Devices.Msi.Native; -namespace RGB.NET.Devices.Msi +namespace RGB.NET.Devices.Msi; + +/// +/// +/// Represents a MSI mouse. +/// +public class MsiMouseRGBDevice : MsiRGBDevice { + #region Constructors + /// /// - /// Represents a MSI mouse. + /// Initializes a new instance of the class. /// - public class MsiMouseRGBDevice : MsiRGBDevice + /// The specific information provided by MSI for the mouse. + /// The amount of leds on this device. + /// The update trigger used to update this device. + internal MsiMouseRGBDevice(MsiRGBDeviceInfo info, int ledCount, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by MSI for the mouse. - internal MsiMouseRGBDevice(MsiRGBDeviceInfo info) - : base(info) - { } + InitializeLayout(ledCount); + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void InitializeLayout(int ledCount) + private void InitializeLayout(int ledCount) + { + for (int i = 0; i < ledCount; i++) { - for (int i = 0; i < ledCount; i++) - { - //Hex3l: Should it be configurable in order to provide style access? - //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color - //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present - const string LED_STYLE = "Steady"; - - _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); - InitializeLed(LedId.Mouse1 + i, new Rectangle(i * 10, 0, 10, 10)); - } - - //TODO DarthAffe 07.10.2017: We don't know the model, how to save layouts and images? - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\MSI\Mouses\{DeviceInfo.Model.Replace(" ", string.Empty).ToUpper()}.xml"), null); - } + //Hex3l: Should it be configurable in order to provide style access? + //Hex3l: Sets led style to "Steady" in order to have a solid color output therefore a controllable led color + //Hex3l: This is a string defined by the output of _MsiSDK.GetLedStyle, "Steady" should be always present + const string LED_STYLE = "Steady"; - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; + _MsiSDK.SetLedStyle(DeviceInfo.MsiDeviceType, i, LED_STYLE); + AddLed(LedId.Mouse1 + i, new Point(i * 10, 0), new Size(10, 10)); + } + } - /// - public override void SyncBack() - { } + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs index ffc9506a..3d1591ae 100644 --- a/RGB.NET.Devices.Msi/MsiDeviceProvider.cs +++ b/RGB.NET.Devices.Msi/MsiDeviceProvider.cs @@ -3,184 +3,108 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; using RGB.NET.Core; using RGB.NET.Devices.Msi.Exceptions; using RGB.NET.Devices.Msi.Native; -namespace RGB.NET.Devices.Msi +namespace RGB.NET.Devices.Msi; + +/// +/// +/// Represents a device provider responsible for MSI devices. +/// +public class MsiDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static MsiDeviceProvider? _instance; + /// + /// Gets the singleton instance. + /// + public static MsiDeviceProvider Instance => _instance ?? new MsiDeviceProvider(); + /// - /// Represents a device provider responsible for MSI devices. + /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. + /// The first match will be used. /// - public class MsiDeviceProvider : IRGBDeviceProvider + public static List PossibleX86NativePaths { get; } = new() { "x86/MysticLight_SDK.dll" }; + + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. + /// The first match will be used. + /// + public static List PossibleX64NativePaths { get; } = new() { "x64/MysticLight_SDK.dll" }; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public MsiDeviceProvider() { - #region Properties & Fields - - private static MsiDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static MsiDeviceProvider Instance => _instance ?? new MsiDeviceProvider(); - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. - /// The first match will be used. - /// - public static List PossibleX86NativePaths { get; } = new List { "x86/MysticLight_SDK.dll" }; - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. - /// The first match will be used. - /// - public static List PossibleX64NativePaths { get; } = new List { "x64/MysticLight_SDK.dll" }; - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _MsiSDK.LoadedArchitecture; - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; - - /// - /// The used to trigger the updates for corsair devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public MsiDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(MsiDeviceProvider)}"); - _instance = this; + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(MsiDeviceProvider)}"); + _instance = this; + } - UpdateTrigger = new DeviceUpdateTrigger(); - } + #endregion - #endregion + #region Methods - #region Methods + /// + protected override void InitializeSDK() + { + _MsiSDK.Reload(); - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + int errorCode; + if ((errorCode = _MsiSDK.Initialize()) != 0) + ThrowMsiError(errorCode, true); + } + + /// + protected override IEnumerable LoadDevices() + { + int errorCode; + if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts)) != 0) + ThrowMsiError(errorCode, true); + + for (int i = 0; i < deviceTypes.Length; i++) { - IsInitialized = false; + string deviceType = deviceTypes[i]; + int ledCount = ledCounts[i]; - try + if (deviceType.Equals("MSI_MB")) { - UpdateTrigger?.Stop(); - - _MsiSDK.Reload(); - - IList devices = new List(); - - int errorCode; - if ((errorCode = _MsiSDK.Initialize()) != 0) - ThrowMsiError(errorCode); - - if ((errorCode = _MsiSDK.GetDeviceInfo(out string[] deviceTypes, out int[] ledCounts)) != 0) - ThrowMsiError(errorCode); - - for (int i = 0; i < deviceTypes.Length; i++) - { - try - { - string deviceType = deviceTypes[i]; - int ledCount = ledCounts[i]; - - //Hex3l: MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify) - if (deviceType.Equals("MSI_MB")) - { - MsiDeviceUpdateQueue updateQueue = new MsiDeviceUpdateQueue(UpdateTrigger, deviceType); - IMsiRGBDevice motherboard = new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceType, "MSI", "Motherboard")); - motherboard.Initialize(updateQueue, ledCount); - devices.Add(motherboard); - } - else if (deviceType.Equals("MSI_VGA")) - { - //Hex3l: Every led under MSI_VGA should be a different graphics card. Handling all the cards together seems a good way to avoid overlapping of leds - //Hex3l: The led name is the name of the card (e.g. NVIDIA GeForce RTX 2080 Ti) we could provide it in device info. - - MsiDeviceUpdateQueue updateQueue = new MsiDeviceUpdateQueue(UpdateTrigger, deviceType); - IMsiRGBDevice graphicscard = new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "MSI", "GraphicsCard")); - graphicscard.Initialize(updateQueue, ledCount); - devices.Add(graphicscard); - } - else if (deviceType.Equals("MSI_MOUSE")) - { - //Hex3l: Every led under MSI_MOUSE should be a different mouse. Handling all the mouses together seems a good way to avoid overlapping of leds - //Hex3l: The led name is the name of the mouse (e.g. msi CLUTCH GM11) we could provide it in device info. - - MsiDeviceUpdateQueue updateQueue = new MsiDeviceUpdateQueue(UpdateTrigger, deviceType); - IMsiRGBDevice mouses = new MsiMouseRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mouse, deviceType, "MSI", "Mouse")); - mouses.Initialize(updateQueue, ledCount); - devices.Add(mouses); - } - - //TODO DarthAffe 22.02.2020: Add other devices - } - catch { if (throwExceptions) throw; } - } - - UpdateTrigger?.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; + //Hex3l: MSI_MB provide access to the motherboard "leds" where a led must be intended as a led header (JRGB, JRAINBOW etc..) (Tested on MSI X570 Unify) + yield return new MsiMainboardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mainboard, deviceType, "MSI", "Motherboard"), ledCount, GetUpdateTrigger()); } - catch + else if (deviceType.Equals("MSI_VGA")) { - if (throwExceptions) - throw; - return false; + //Hex3l: Every led under MSI_VGA should be a different graphics card. Handling all the cards together seems a good way to avoid overlapping of leds + //Hex3l: The led name is the name of the card (e.g. NVIDIA GeForce RTX 2080 Ti) we could provide it in device info. + yield return new MsiGraphicsCardRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.GraphicsCard, deviceType, "MSI", "GraphicsCard"), ledCount, GetUpdateTrigger()); + } + else if (deviceType.Equals("MSI_MOUSE")) + { + //Hex3l: Every led under MSI_MOUSE should be a different mouse. Handling all the mouses together seems a good way to avoid overlapping of leds + //Hex3l: The led name is the name of the mouse (e.g. msi CLUTCH GM11) we could provide it in device info. + yield return new MsiMouseRGBDevice(new MsiRGBDeviceInfo(RGBDeviceType.Mouse, deviceType, "MSI", "Mouse"), ledCount, GetUpdateTrigger()); } - - return true; - } - - private void ThrowMsiError(int errorCode) => throw new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode)); - - /// - public void ResetDevices() - { - //TODO DarthAffe 11.11.2017: Implement } + } - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } + private void ThrowMsiError(int errorCode, bool isCritical = false) => Throw(new MysticLightException(errorCode, _MsiSDK.GetErrorMessage(errorCode)), isCritical); - try { _MsiSDK.UnloadMsiSDK(); } - catch { /* at least we tried */ } - } + /// + public override void Dispose() + { + base.Dispose(); - #endregion + try { _MsiSDK.UnloadMsiSDK(); } + catch { /* at least we tried */ } } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs b/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs deleted file mode 100644 index b059f858..00000000 --- a/RGB.NET.Devices.Msi/MsiDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Msi -{ - /// - /// Represents a device provider loaded used to dynamically load MSI devices into an application. - /// - public class MsiDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => MsiDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Msi/Native/_MsiSDK.cs b/RGB.NET.Devices.Msi/Native/_MsiSDK.cs index 930352f8..c13ef81f 100644 --- a/RGB.NET.Devices.Msi/Native/_MsiSDK.cs +++ b/RGB.NET.Devices.Msi/Native/_MsiSDK.cs @@ -1,4 +1,5 @@ -// ReSharper disable UnusedMethodReturnValue.Global +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable UnusedMethodReturnValue.Global // ReSharper disable UnusedMember.Global using System; @@ -8,221 +9,237 @@ using System.Runtime.InteropServices; using RGB.NET.Core; -namespace RGB.NET.Devices.Msi.Native +namespace RGB.NET.Devices.Msi.Native; + +// ReSharper disable once InconsistentNaming +internal static class _MsiSDK { - // ReSharper disable once InconsistentNaming - internal static class _MsiSDK + #region Libary Management + + private static IntPtr _handle = IntPtr.Zero; + + /// + /// Reloads the SDK. + /// + internal static void Reload() + { + UnloadMsiSDK(); + LoadMsiSDK(); + } + + private static void LoadMsiSDK() { - #region Libary Management - - private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - - /// - /// Reloads the SDK. - /// - internal static void Reload() - { - UnloadMsiSDK(); - LoadMsiSDK(); - } - - private static void LoadMsiSDK() - { - if (_dllHandle != IntPtr.Zero) return; - - // HACK: Load library at runtime to support both, x86 and x64 with one managed dll - List possiblePathList = Environment.Is64BitProcess ? MsiDeviceProvider.PossibleX64NativePaths : MsiDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); - if (dllPath == null) throw new RGBDeviceException($"Can't find the Msi-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - - SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))); - - _dllHandle = LoadLibrary(dllPath); - - _initializePointer = (InitializePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_Initialize"), typeof(InitializePointer)); - _getDeviceInfoPointer = (GetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetDeviceInfo"), typeof(GetDeviceInfoPointer)); - _getLedInfoPointer = (GetLedInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedInfo"), typeof(GetLedInfoPointer)); - _getLedColorPointer = (GetLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedColor"), typeof(GetLedColorPointer)); - _getLedStylePointer = (GetLedStylePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedStyle"), typeof(GetLedStylePointer)); - _getLedMaxBrightPointer = (GetLedMaxBrightPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedMaxBright"), typeof(GetLedMaxBrightPointer)); - _getLedBrightPointer = (GetLedBrightPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedBright"), typeof(GetLedBrightPointer)); - _getLedMaxSpeedPointer = (GetLedMaxSpeedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedMaxSpeed"), typeof(GetLedMaxSpeedPointer)); - _getLedSpeedPointer = (GetLedSpeedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetLedSpeed"), typeof(GetLedSpeedPointer)); - _setLedColorPointer = (SetLedColorPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_SetLedColor"), typeof(SetLedColorPointer)); - _setLedStylePointer = (SetLedStylePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_SetLedStyle"), typeof(SetLedStylePointer)); - _setLedBrightPointer = (SetLedBrightPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_SetLedBright"), typeof(SetLedBrightPointer)); - _setLedSpeedPointer = (SetLedSpeedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_SetLedSpeed"), typeof(SetLedSpeedPointer)); - _getErrorMessagePointer = (GetErrorMessagePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "MLAPI_GetErrorMessage"), typeof(GetErrorMessagePointer)); - } - - internal static void UnloadMsiSDK() - { - if (_dllHandle == IntPtr.Zero) return; - - // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 07.10.2017: We might need to reduce the internal reference counter more than once to set the library free - while (FreeLibrary(_dllHandle)) ; - _dllHandle = IntPtr.Zero; - } - - [DllImport("kernel32.dll")] - private static extern bool SetDllDirectory(string lpPathName); - - [DllImport("kernel32.dll")] - private static extern IntPtr LoadLibrary(string dllToLoad); - - [DllImport("kernel32.dll")] - private static extern bool FreeLibrary(IntPtr dllHandle); - - [DllImport("kernel32.dll")] - private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); - - #endregion - - #region SDK-METHODS - - #region Pointers - - private static InitializePointer _initializePointer; - private static GetDeviceInfoPointer _getDeviceInfoPointer; - private static GetLedInfoPointer _getLedInfoPointer; - private static GetLedColorPointer _getLedColorPointer; - private static GetLedStylePointer _getLedStylePointer; - private static GetLedMaxBrightPointer _getLedMaxBrightPointer; - private static GetLedBrightPointer _getLedBrightPointer; - private static GetLedMaxSpeedPointer _getLedMaxSpeedPointer; - private static GetLedSpeedPointer _getLedSpeedPointer; - private static SetLedColorPointer _setLedColorPointer; - private static SetLedStylePointer _setLedStylePointer; - private static SetLedBrightPointer _setLedBrightPointer; - private static SetLedSpeedPointer _setLedSpeedPointer; - private static GetErrorMessagePointer _getErrorMessagePointer; - - #endregion - - #region Delegates - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int InitializePointer(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetDeviceInfoPointer( - [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] pDevType, - [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] pLedCount); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedInfoPointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [Out, MarshalAs(UnmanagedType.BStr)] out string pName, - [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] pLedStyles); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedColorPointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [Out, MarshalAs(UnmanagedType.I4)] out int r, - [Out, MarshalAs(UnmanagedType.I4)] out int g, - [Out, MarshalAs(UnmanagedType.I4)] out int b); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedStylePointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [Out, MarshalAs(UnmanagedType.BStr)] out string style); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedMaxBrightPointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [Out, MarshalAs(UnmanagedType.I4)] out int maxLevel); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedBrightPointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [Out, MarshalAs(UnmanagedType.I4)] out int currentLevel); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedMaxSpeedPointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [Out, MarshalAs(UnmanagedType.I4)] out int maxSpeed); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetLedSpeedPointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [Out, MarshalAs(UnmanagedType.I4)] out int currentSpeed); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int SetLedColorPointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [In, MarshalAs(UnmanagedType.I4)] int r, - [In, MarshalAs(UnmanagedType.I4)] int g, - [In, MarshalAs(UnmanagedType.I4)] int b); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int SetLedStylePointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [In, MarshalAs(UnmanagedType.BStr)] string style); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int SetLedBrightPointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [In, MarshalAs(UnmanagedType.I4)] int level); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int SetLedSpeedPointer( - [In, MarshalAs(UnmanagedType.BStr)] string type, - [In, MarshalAs(UnmanagedType.I4)] int index, - [In, MarshalAs(UnmanagedType.I4)] int speed); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate int GetErrorMessagePointer( - [In, MarshalAs(UnmanagedType.I4)] int errorCode, - [Out, MarshalAs(UnmanagedType.BStr)] out string pDesc); - - #endregion - - internal static int Initialize() => _initializePointer(); - internal static int GetDeviceInfo(out string[] pDevType, out int[] pLedCount) - { - // HACK - SDK GetDeviceInfo returns a string[] for ledCount, so we'll parse that to int. - int result = _getDeviceInfoPointer(out pDevType, out string[] ledCount); - pLedCount = new int[ledCount.Length]; - - for (int i = 0; i < ledCount.Length; i++) - pLedCount[i] = int.Parse(ledCount[i]); - - return result; - } - - internal static int GetLedInfo(string type, int index, out string pName, out string[] pLedStyles) => _getLedInfoPointer(type, index, out pName, out pLedStyles); - internal static int GetLedColor(string type, int index, out int r, out int g, out int b) => _getLedColorPointer(type, index, out r, out g, out b); - internal static int GetLedStyle(string type, int index, out string style) => _getLedStylePointer(type, index, out style); - internal static int GetLedMaxBright(string type, int index, out int maxLevel) => _getLedMaxBrightPointer(type, index, out maxLevel); - internal static int GetLedBright(string type, int index, out int currentLevel) => _getLedBrightPointer(type, index, out currentLevel); - internal static int GetLedMaxSpeed(string type, int index, out int maxSpeed) => _getLedMaxSpeedPointer(type, index, out maxSpeed); - internal static int GetLedSpeed(string type, int index, out int currentSpeed) => _getLedSpeedPointer(type, index, out currentSpeed); - internal static int SetLedColor(string type, int index, int r, int g, int b) => _setLedColorPointer(type, index, r, g, b); - internal static int SetLedStyle(string type, int index, string style) => _setLedStylePointer(type, index, style); - internal static int SetLedBright(string type, int index, int level) => _setLedBrightPointer(type, index, level); - internal static int SetLedSpeed(string type, int index, int speed) => _setLedSpeedPointer(type, index, speed); - - internal static string GetErrorMessage(int errorCode) - { - _getErrorMessagePointer(errorCode, out string description); - return description; - } - - #endregion + if (_handle != IntPtr.Zero) return; + + List possiblePathList = GetPossibleLibraryPaths().ToList(); + + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); + if (dllPath == null) throw new RGBDeviceException($"Can't find the CUE-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); + + SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))!); + + if (!NativeLibrary.TryLoad(dllPath, out _handle)) +#if NET6_0 + throw new RGBDeviceException($"MSI LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}"); +#else + throw new RGBDeviceException($"MSI LoadLibrary failed with error code {Marshal.GetLastWin32Error()}"); +#endif + + _initializePointer = (InitializePointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_Initialize"), typeof(InitializePointer)); + _getDeviceInfoPointer = (GetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetDeviceInfo"), typeof(GetDeviceInfoPointer)); + _getLedInfoPointer = (GetLedInfoPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedInfo"), typeof(GetLedInfoPointer)); + _getLedColorPointer = (GetLedColorPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedColor"), typeof(GetLedColorPointer)); + _getLedStylePointer = (GetLedStylePointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedStyle"), typeof(GetLedStylePointer)); + _getLedMaxBrightPointer = (GetLedMaxBrightPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedMaxBright"), typeof(GetLedMaxBrightPointer)); + _getLedBrightPointer = (GetLedBrightPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedBright"), typeof(GetLedBrightPointer)); + _getLedMaxSpeedPointer = (GetLedMaxSpeedPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedMaxSpeed"), typeof(GetLedMaxSpeedPointer)); + _getLedSpeedPointer = (GetLedSpeedPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetLedSpeed"), typeof(GetLedSpeedPointer)); + _setLedColorPointer = (SetLedColorPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_SetLedColor"), typeof(SetLedColorPointer)); + _setLedStylePointer = (SetLedStylePointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_SetLedStyle"), typeof(SetLedStylePointer)); + _setLedBrightPointer = (SetLedBrightPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_SetLedBright"), typeof(SetLedBrightPointer)); + _setLedSpeedPointer = (SetLedSpeedPointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_SetLedSpeed"), typeof(SetLedSpeedPointer)); + _getErrorMessagePointer = (GetErrorMessagePointer)Marshal.GetDelegateForFunctionPointer(NativeLibrary.GetExport(_handle, "MLAPI_GetErrorMessage"), typeof(GetErrorMessagePointer)); } -} + + private static IEnumerable GetPossibleLibraryPaths() + { + IEnumerable possibleLibraryPaths; + + if (OperatingSystem.IsWindows()) + possibleLibraryPaths = Environment.Is64BitProcess ? MsiDeviceProvider.PossibleX64NativePaths : MsiDeviceProvider.PossibleX86NativePaths; + else + possibleLibraryPaths = Enumerable.Empty(); + + return possibleLibraryPaths.Select(Environment.ExpandEnvironmentVariables); + } + + internal static void UnloadMsiSDK() + { + if (_handle == IntPtr.Zero) return; + + _initializePointer = null; + _getDeviceInfoPointer = null; + _getLedColorPointer = null; + _getLedColorPointer = null; + _getLedStylePointer = null; + _getLedMaxBrightPointer = null; + _getLedBrightPointer = null; + _getLedMaxSpeedPointer = null; + _getLedSpeedPointer = null; + _setLedColorPointer = null; + _setLedStylePointer = null; + _setLedBrightPointer = null; + _setLedSpeedPointer = null; + _getErrorMessagePointer = null; + + NativeLibrary.Free(_handle); + _handle = IntPtr.Zero; + } + + [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] + private static extern bool SetDllDirectory(string lpPathName); + + #endregion + + #region SDK-METHODS + + #region Pointers + + private static InitializePointer? _initializePointer; + private static GetDeviceInfoPointer? _getDeviceInfoPointer; + private static GetLedInfoPointer? _getLedInfoPointer; + private static GetLedColorPointer? _getLedColorPointer; + private static GetLedStylePointer? _getLedStylePointer; + private static GetLedMaxBrightPointer? _getLedMaxBrightPointer; + private static GetLedBrightPointer? _getLedBrightPointer; + private static GetLedMaxSpeedPointer? _getLedMaxSpeedPointer; + private static GetLedSpeedPointer? _getLedSpeedPointer; + private static SetLedColorPointer? _setLedColorPointer; + private static SetLedStylePointer? _setLedStylePointer; + private static SetLedBrightPointer? _setLedBrightPointer; + private static SetLedSpeedPointer? _setLedSpeedPointer; + private static GetErrorMessagePointer? _getErrorMessagePointer; + + #endregion + + #region Delegates + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int InitializePointer(); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetDeviceInfoPointer( + [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] pDevType, + [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] pLedCount); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetLedInfoPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.BStr)] out string pName, + [Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] out string[] pLedStyles); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetLedColorPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int r, + [Out, MarshalAs(UnmanagedType.I4)] out int g, + [Out, MarshalAs(UnmanagedType.I4)] out int b); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetLedStylePointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.BStr)] out string style); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetLedMaxBrightPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int maxLevel); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetLedBrightPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int currentLevel); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetLedMaxSpeedPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int maxSpeed); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetLedSpeedPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [Out, MarshalAs(UnmanagedType.I4)] out int currentSpeed); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int SetLedColorPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [In, MarshalAs(UnmanagedType.I4)] int r, + [In, MarshalAs(UnmanagedType.I4)] int g, + [In, MarshalAs(UnmanagedType.I4)] int b); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int SetLedStylePointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [In, MarshalAs(UnmanagedType.BStr)] string style); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int SetLedBrightPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [In, MarshalAs(UnmanagedType.I4)] int level); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int SetLedSpeedPointer( + [In, MarshalAs(UnmanagedType.BStr)] string type, + [In, MarshalAs(UnmanagedType.I4)] int index, + [In, MarshalAs(UnmanagedType.I4)] int speed); + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + private delegate int GetErrorMessagePointer( + [In, MarshalAs(UnmanagedType.I4)] int errorCode, + [Out, MarshalAs(UnmanagedType.BStr)] out string pDesc); + + #endregion + + internal static int Initialize() => (_initializePointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(); + internal static int GetDeviceInfo(out string[] pDevType, out int[] pLedCount) + { + // HACK - SDK GetDeviceInfo returns a string[] for ledCount, so we'll parse that to int. + int result = (_getDeviceInfoPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(out pDevType, out string[] ledCount); + pLedCount = new int[ledCount.Length]; + + for (int i = 0; i < ledCount.Length; i++) + pLedCount[i] = int.Parse(ledCount[i]); + + return result; + } + + internal static int GetLedInfo(string type, int index, out string pName, out string[] pLedStyles) => (_getLedInfoPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out pName, out pLedStyles); + internal static int GetLedColor(string type, int index, out int r, out int g, out int b) => (_getLedColorPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out r, out g, out b); + internal static int GetLedStyle(string type, int index, out string style) => (_getLedStylePointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out style); + internal static int GetLedMaxBright(string type, int index, out int maxLevel) => (_getLedMaxBrightPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out maxLevel); + internal static int GetLedBright(string type, int index, out int currentLevel) => (_getLedBrightPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out currentLevel); + internal static int GetLedMaxSpeed(string type, int index, out int maxSpeed) => (_getLedMaxSpeedPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out maxSpeed); + internal static int GetLedSpeed(string type, int index, out int currentSpeed) => (_getLedSpeedPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, out currentSpeed); + internal static int SetLedColor(string type, int index, int r, int g, int b) => (_setLedColorPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, r, g, b); + internal static int SetLedStyle(string type, int index, string style) => (_setLedStylePointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, style); + internal static int SetLedBright(string type, int index, int level) => (_setLedBrightPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, level); + internal static int SetLedSpeed(string type, int index, int speed) => (_setLedSpeedPointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(type, index, speed); + + internal static string GetErrorMessage(int errorCode) + { + (_getErrorMessagePointer ?? throw new RGBDeviceException("The MSI-SDK is not initialized.")).Invoke(errorCode, out string description); + return description; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/README.md b/RGB.NET.Devices.Msi/README.md new file mode 100644 index 00000000..2cc69238 --- /dev/null +++ b/RGB.NET.Devices.Msi/README.md @@ -0,0 +1,24 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for msi-Devices. + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(MsiDeviceProvider.Instance); +``` + +# Required SDK +This providers requires native SDK-dlls. +You can get them directly from Msi at [https://de.msi.com/Landing/mystic-light-rgb-gaming-pc/download](https://de.msi.com/Landing/mystic-light-rgb-gaming-pc/download) (Direct Link: [https://download.msi.com/uti_exe/Mystic_light_SDK.zip](https://download.msi.com/uti_exe/Mystic_light_SDK.zip)) + +Since the SDK-dlls are native it's important to use the correct architecture you're building your application for. (If in doubt you can always include both.) + +### x64 +`MysticLight_SDK_x64.dll` from the SDK-zip needs to be distributed as `\x64\MysticLight_SDK.dll` + +You can use other, custom paths by adding them to `MsiDeviceProvider.PossibleX64NativePaths`. + +### x86 +`MysticLight_SDK.dll` from the SDK-zip needs to be distributed as `\x86\MysticLight_SDK.dll` + +You can use other, custom paths by adding them to `MsiDeviceProvider.PossibleX86NativePaths`. diff --git a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj index ba242908..c565c945 100644 --- a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj +++ b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.Msi Msi-Device-Implementations of RGB.NET Msi-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,36 +35,28 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + - - + + \ No newline at end of file diff --git a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings index 5db60736..d0b9b63c 100644 --- a/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings +++ b/RGB.NET.Devices.Msi/RGB.NET.Devices.Msi.csproj.DotSettings @@ -2,4 +2,6 @@ True True True - True \ No newline at end of file + True + True + \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Attributes/ColorCapabilityAttribute.cs b/RGB.NET.Devices.Novation/Attributes/ColorCapabilityAttribute.cs index 8a9a7d7e..d2c0a002 100644 --- a/RGB.NET.Devices.Novation/Attributes/ColorCapabilityAttribute.cs +++ b/RGB.NET.Devices.Novation/Attributes/ColorCapabilityAttribute.cs @@ -1,35 +1,34 @@ using System; -namespace RGB.NET.Devices.Novation.Attributes +namespace RGB.NET.Devices.Novation.Attributes; + +/// +/// +/// Specifies the color-capability of a field. +/// +[AttributeUsage(AttributeTargets.Field)] +public class ColorCapabilityAttribute : Attribute { - /// + #region Properties & Fields + /// - /// Specifies the color-capability of a field. + /// Gets the Id. /// - [AttributeUsage(AttributeTargets.Field)] - public class ColorCapabilityAttribute : Attribute - { - #region Properties & Fields - - /// - /// Gets the Id. - /// - public NovationColorCapabilities Capability { get; } - - #endregion + public NovationColorCapabilities Capability { get; } - #region Constructors + #endregion - /// - /// - /// Initializes a new instance of the class. - /// - /// The capability. - public ColorCapabilityAttribute(NovationColorCapabilities capability) - { - this.Capability = capability; - } + #region Constructors - #endregion + /// + /// + /// Initializes a new instance of the class. + /// + /// The capability. + public ColorCapabilityAttribute(NovationColorCapabilities capability) + { + this.Capability = capability; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Attributes/DeviceIdAttribute.cs b/RGB.NET.Devices.Novation/Attributes/DeviceIdAttribute.cs index 5caaca93..34c8b2e1 100644 --- a/RGB.NET.Devices.Novation/Attributes/DeviceIdAttribute.cs +++ b/RGB.NET.Devices.Novation/Attributes/DeviceIdAttribute.cs @@ -1,35 +1,34 @@ using System; -namespace RGB.NET.Devices.Novation.Attributes +namespace RGB.NET.Devices.Novation.Attributes; + +/// +/// +/// Specifies the device-id of a field. +/// +[AttributeUsage(AttributeTargets.Field)] +public class DeviceIdAttribute : Attribute { - /// + #region Properties & Fields + /// - /// Specifies the device-id of a field. + /// Gets the Id. /// - [AttributeUsage(AttributeTargets.Field)] - public class DeviceIdAttribute : Attribute - { - #region Properties & Fields - - /// - /// Gets the Id. - /// - public string Id { get; } - - #endregion + public string Id { get; } - #region Constructors + #endregion - /// - /// - /// Initializes a new instance of the class. - /// - /// The id. - public DeviceIdAttribute(string id) - { - this.Id = id; - } + #region Constructors - #endregion + /// + /// + /// Initializes a new instance of the class. + /// + /// The id. + public DeviceIdAttribute(string id) + { + this.Id = id; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Attributes/LedIdMappingAttribute.cs b/RGB.NET.Devices.Novation/Attributes/LedIdMappingAttribute.cs index 3cda1aa9..1e5ac21b 100644 --- a/RGB.NET.Devices.Novation/Attributes/LedIdMappingAttribute.cs +++ b/RGB.NET.Devices.Novation/Attributes/LedIdMappingAttribute.cs @@ -1,35 +1,34 @@ using System; -namespace RGB.NET.Devices.Novation.Attributes +namespace RGB.NET.Devices.Novation.Attributes; + +/// +/// +/// Specifies the led id mapping of a field. +/// +[AttributeUsage(AttributeTargets.Field)] +internal class LedIdMappingAttribute : Attribute { - /// + #region Properties & Fields + /// - /// Specifies the led id mapping of a field. + /// Gets the led id mapping. /// - [AttributeUsage(AttributeTargets.Field)] - internal class LedIdMappingAttribute : Attribute - { - #region Properties & Fields - - /// - /// Gets the led id mapping. - /// - internal LedIdMappings LedIdMapping { get; } - - #endregion + internal LedIdMappings LedIdMapping { get; } - #region Constructors + #endregion - /// - /// - /// Initializes a new instance of the class. - /// - /// The led id mapping. - internal LedIdMappingAttribute(LedIdMappings ledIdMapping) - { - this.LedIdMapping = ledIdMapping; - } + #region Constructors - #endregion + /// + /// + /// Initializes a new instance of the class. + /// + /// The led id mapping. + internal LedIdMappingAttribute(LedIdMappings ledIdMapping) + { + this.LedIdMapping = ledIdMapping; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Enum/NovationColorCapabilities.cs b/RGB.NET.Devices.Novation/Enum/NovationColorCapabilities.cs index 9f7091a8..344a6846 100644 --- a/RGB.NET.Devices.Novation/Enum/NovationColorCapabilities.cs +++ b/RGB.NET.Devices.Novation/Enum/NovationColorCapabilities.cs @@ -2,15 +2,14 @@ // ReSharper disable InconsistentNaming // ReSharper disable UnusedMember.Global -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +/// +/// Represents the color-capabilities of a novation device. +/// +public enum NovationColorCapabilities { - /// - /// Represents the color-capabilities of a novation device. - /// - public enum NovationColorCapabilities - { - None, - RGB, - LimitedRG - } -} + None, + RGB, + LimitedRG +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Enum/NovationDevices.cs b/RGB.NET.Devices.Novation/Enum/NovationDevices.cs index f1afa2cf..11ae6e0b 100644 --- a/RGB.NET.Devices.Novation/Enum/NovationDevices.cs +++ b/RGB.NET.Devices.Novation/Enum/NovationDevices.cs @@ -4,26 +4,35 @@ using RGB.NET.Devices.Novation.Attributes; -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +/// +/// Represents a specific novation device. +/// +public enum NovationDevices { - /// - /// Represents a specific novation device. - /// - public enum NovationDevices - { - [DeviceId("Launchpad S")] - [ColorCapability(NovationColorCapabilities.LimitedRG)] - [LedIdMapping(LedIdMappings.Legacy)] - LaunchpadS, + [DeviceId("Launchpad S")] + [ColorCapability(NovationColorCapabilities.LimitedRG)] + [LedIdMapping(LedIdMappings.Legacy)] + LaunchpadS, + + [DeviceId("Launchpad Mini")] + [ColorCapability(NovationColorCapabilities.LimitedRG)] + [LedIdMapping(LedIdMappings.Legacy)] + LaunchpadMini, + + [DeviceId("Launchpad MK2")] + [ColorCapability(NovationColorCapabilities.RGB)] + [LedIdMapping(LedIdMappings.Current)] + LaunchpadMK2, - [DeviceId("Launchpad Mini")] - [ColorCapability(NovationColorCapabilities.LimitedRG)] - [LedIdMapping(LedIdMappings.Legacy)] - LaunchpadMini, + [DeviceId("Launchpad Pro")] + [ColorCapability(NovationColorCapabilities.RGB)] + [LedIdMapping(LedIdMappings.Pro)] + LaunchpadPro, - [DeviceId("Launchpad MK2")] - [ColorCapability(NovationColorCapabilities.RGB)] - [LedIdMapping(LedIdMappings.Current)] - LaunchpadMK2 - } -} + [DeviceId("Launchpad Open")] + [ColorCapability(NovationColorCapabilities.RGB)] + [LedIdMapping(LedIdMappings.Pro)] + LaunchpadCustomFirmware +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs b/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs index 544df33b..6b8e05ca 100644 --- a/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Generic/INovationRGBDevice.cs @@ -1,12 +1,9 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Novation -{ - /// - /// Represents a novation RGB-device. - /// - internal interface INovationRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } -} +namespace RGB.NET.Devices.Novation; + +/// +/// Represents a novation RGB-device. +/// +public interface INovationRGBDevice : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs b/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs index 588e359c..9bb0bbe9 100644 --- a/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs +++ b/RGB.NET.Devices.Novation/Generic/LimitedColorUpdateQueue.cs @@ -1,66 +1,61 @@ using System; -using System.Collections.Generic; using RGB.NET.Core; using Sanford.Multimedia.Midi; -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +/// +/// Represents the update-queue performing updates for a limited-color novation device. +/// +public class LimitedColorUpdateQueue : MidiUpdateQueue { + #region Constructors + /// - /// Represents the update-queue performing updates for a limited-color novation device. + /// Initializes a new instance of the class. /// - public class LimitedColorUpdateQueue : MidiUpdateQueue - { - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The device-id of the device this queue is performing updates for. - public LimitedColorUpdateQueue(IDeviceUpdateTrigger updateTrigger, int deviceId) - : base(updateTrigger, deviceId) - { } - - #endregion - - #region Methods - - /// - protected override ShortMessage CreateMessage(KeyValuePair data) - { - (byte mode, byte id) = ((byte, byte))data.Key; - return new ShortMessage(mode, id, Convert.ToByte(ConvertColor(data.Value))); - } - - /// - /// Convert a to its novation-representation depending on the of the . - /// The conversion uses only a limited amount of colors (3 red, 3 yellow, 3 green). - /// - /// The to convert. - /// The novation-representation of the . - protected virtual int ConvertColor(Color color) - { - (double hue, double saturation, double value) = color.GetHSV(); + /// The update trigger used by this queue. + /// The device-id of the device this queue is performing updates for. + public LimitedColorUpdateQueue(IDeviceUpdateTrigger updateTrigger, int deviceId) + : base(updateTrigger, deviceId) + { } - if ((hue >= 330) || (hue < 30)) - return (int)Math.Ceiling(value * 3); // red with brightness 1, 2 or 3 + #endregion - if ((hue >= 30) && (hue < 90)) // yellow with brightness 17, 34 or 51 - return (int)Math.Ceiling(value * 3) * 17; + #region Methods - if ((hue >= 90) && (hue < 150)) // green with brightness 16, 32 or 48 - return (int)Math.Ceiling(value * 3) * 16; + /// + protected override ShortMessage CreateMessage(object key, in Color color) + { + (byte mode, byte id) = ((byte, byte))key; + return new ShortMessage(mode, id, Convert.ToByte(ConvertColor(color))); + } - return 0; - } + /// + /// Convert a to its novation-representation depending on the of the . + /// The conversion uses only a limited amount of colors (3 red, 3 yellow, 3 green). + /// + /// The to convert. + /// The novation-representation of the . + protected virtual int ConvertColor(in Color color) + { + (double hue, double _, double value) = color.GetHSV(); - /// - public override void Reset() + return hue switch { - base.Reset(); - SendMessage(new ShortMessage(Convert.ToByte(0xB0), Convert.ToByte(0), Convert.ToByte(0))); - } + >= 330 or < 30 => (int)Math.Ceiling(value * 3), // red with brightness 1, 2 or 3 + >= 30 and < 90 => (int)Math.Ceiling(value * 3) * 17, // yellow with brightness 17, 34 or 51 + >= 90 and < 150 => (int)Math.Ceiling(value * 3) * 16, // green with brightness 16, 32 or 48 + _ => 0 + }; + } - #endregion + /// + public override void Reset() + { + base.Reset(); + SendMessage(new ShortMessage(Convert.ToByte(0xB0), Convert.ToByte(0), Convert.ToByte(0))); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs b/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs index 6e34359c..dc21766e 100644 --- a/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs +++ b/RGB.NET.Devices.Novation/Generic/MidiUpdateQueue.cs @@ -1,74 +1,73 @@ using System; -using System.Collections.Generic; using RGB.NET.Core; using Sanford.Multimedia.Midi; -namespace RGB.NET.Devices.Novation -{ - /// - /// - /// - /// Represents the update-queue performing updates for midi devices. - /// - public abstract class MidiUpdateQueue : UpdateQueue, IDisposable - { - #region Properties & Fields +namespace RGB.NET.Devices.Novation; - private readonly OutputDevice _outputDevice; +/// +/// +/// Represents the update-queue performing updates for midi devices. +/// +public abstract class MidiUpdateQueue : UpdateQueue +{ + #region Properties & Fields - #endregion + private readonly OutputDevice _outputDevice; - #region Constructors + #endregion - /// - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The id of the device this queue is performing updates for. - protected MidiUpdateQueue(IDeviceUpdateTrigger updateTrigger, int deviceId) - : base(updateTrigger) - { - _outputDevice = new OutputDevice(deviceId); - } + #region Constructors - #endregion + /// + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The id of the device this queue is performing updates for. + protected MidiUpdateQueue(IDeviceUpdateTrigger updateTrigger, int deviceId) + : base(updateTrigger) + { + _outputDevice = new OutputDevice(deviceId); + } - #region Methods + #endregion - /// - protected override void Update(Dictionary dataSet) - { - foreach (KeyValuePair data in dataSet) - SendMessage(CreateMessage(data)); - } + #region Methods - /// - /// Sends the specified message to the device this queue is performing updates for. - /// - /// The message to send. - protected virtual void SendMessage(ShortMessage message) - { - if (message != null) - _outputDevice.SendShort(message.Message); - } + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + foreach ((object key, Color color) in dataSet) + SendMessage(CreateMessage(key, color)); + } + /// + /// Sends the specified message to the device this queue is performing updates for. + /// + /// The message to send. + protected virtual void SendMessage(ShortMessage? message) + { + if (message != null) + _outputDevice.SendShort(message.Message); + } - /// - /// Creates a update-message out of a given data set. - /// - /// The data set to create the message from. - /// The message created out of the data set. - protected abstract ShortMessage CreateMessage(KeyValuePair data); + /// + /// Creates a update-message out of a specified data set. + /// + /// The key used to identify the LED to update. + /// The color to send. + /// The message created out of the data set. + protected abstract ShortMessage? CreateMessage(object key, in Color color); - /// - public override void Dispose() - { - base.Dispose(); + /// + public override void Dispose() + { + base.Dispose(); - _outputDevice.Dispose(); - } + _outputDevice.Dispose(); - #endregion + GC.SuppressFinalize(this); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs index d1f76795..5480370f 100644 --- a/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Generic/NovationRGBDevice.cs @@ -1,95 +1,55 @@ using System; using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +/// +/// +/// Represents a generic Novation-device. (launchpad). +/// +public abstract class NovationRGBDevice : AbstractRGBDevice, INovationRGBDevice + where TDeviceInfo : NovationRGBDeviceInfo { - /// - /// + #region Constructors + /// - /// Represents a generic Novation-device. (launchpad). + /// Initializes a new instance of the class. /// - public abstract class NovationRGBDevice : AbstractRGBDevice, INovationRGBDevice - where TDeviceInfo : NovationRGBDeviceInfo - { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// The used to update this . - /// - // ReSharper disable once MemberCanBePrivate.Global - protected MidiUpdateQueue UpdateQueue { get; set; } + /// The generic information provided by Novation for the device. + /// The update trigger used to update this device. + protected NovationRGBDevice(TDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, GetUpdateQueue(updateTrigger, info)) + { } - #endregion + #endregion - #region Constructors + #region Methods - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by Novation for the device. - protected NovationRGBDevice(TDeviceInfo info) + private static UpdateQueue GetUpdateQueue(IDeviceUpdateTrigger updateTrigger, TDeviceInfo info) => + info.ColorCapabilities switch { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } + NovationColorCapabilities.LimitedRG => new LimitedColorUpdateQueue(updateTrigger, info.DeviceId), + NovationColorCapabilities.RGB => new RGBColorUpdateQueue(updateTrigger, info.DeviceId), + _ => throw new ArgumentOutOfRangeException() + }; - UpdateQueue = DeviceInfo.ColorCapabilities switch - { - NovationColorCapabilities.LimitedRG => new LimitedColorUpdateQueue(updateTrigger, DeviceInfo.DeviceId), - NovationColorCapabilities.RGB => new RGBColorUpdateQueue(updateTrigger, DeviceInfo.DeviceId), - _ => throw new ArgumentOutOfRangeException() - }; - } + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); - - /// - /// Resets the back to default. - /// - public virtual void Reset() => UpdateQueue.Reset(); - - /// - /// - public override void Dispose() - { - Reset(); - - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } + /// + /// Resets the back to default. + /// + public virtual void Reset() => UpdateQueue.Reset(); - base.Dispose(); - } + /// + /// + public override void Dispose() + { + Reset(); - #endregion + base.Dispose(); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs b/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs index 22405008..07bf7aab 100644 --- a/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Novation/Generic/NovationRGBDeviceInfo.cs @@ -1,68 +1,60 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Novation -{ - /// - /// - /// Represents a generic information for a Corsair-. - /// - public class NovationRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields - - /// - public RGBDeviceType DeviceType { get; } +namespace RGB.NET.Devices.Novation; - /// - public string DeviceName { get; } - - /// - public string Manufacturer => "Novation"; +/// +/// +/// Represents a generic information for a Corsair-. +/// +public class NovationRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public string Model { get; } + /// + public RGBDeviceType DeviceType { get; } - /// - public Uri Image { get; set; } + /// + public string DeviceName { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public string Manufacturer => "Novation"; - /// - public bool SupportsSyncBack => false; + /// + public string Model { get; } - /// - /// Gets the of the . - /// - public NovationColorCapabilities ColorCapabilities { get; } + /// + public object? LayoutMetadata { get; set; } - /// - /// Gets the (midi)-id of the .. - /// - public int DeviceId { get; } + /// + /// Gets the of the . + /// + public NovationColorCapabilities ColorCapabilities { get; } - #endregion + /// + /// Gets the (midi)-id of the .. + /// + public int DeviceId { get; } - #region Constructors + #endregion - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The represented device model. - /// The (midi)-id of the . - /// The of the . - internal NovationRGBDeviceInfo(RGBDeviceType deviceType, string model, int deviceId, NovationColorCapabilities colorCapabilities) - { - this.DeviceType = deviceType; - this.Model = model; - this.DeviceId = deviceId; - this.ColorCapabilities = colorCapabilities; + #region Constructors - DeviceName = $"{Manufacturer} {Model}"; - } + /// + /// Internal constructor of managed . + /// + /// The type of the . + /// The represented device model. + /// The (midi)-id of the . + /// The of the . + internal NovationRGBDeviceInfo(RGBDeviceType deviceType, string model, int deviceId, NovationColorCapabilities colorCapabilities) + { + this.DeviceType = deviceType; + this.Model = model; + this.DeviceId = deviceId; + this.ColorCapabilities = colorCapabilities; - #endregion + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs b/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs index 5dd9d544..5a3367a9 100644 --- a/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs +++ b/RGB.NET.Devices.Novation/Generic/RGBColorUpdateQueue.cs @@ -1,195 +1,193 @@ using System; -using System.Collections.Generic; using RGB.NET.Core; using Sanford.Multimedia.Midi; -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +/// +/// Represents the update-queue performing updates for a RGB-color novation device. +/// +public class RGBColorUpdateQueue : MidiUpdateQueue { - /// - /// Represents the update-queue performing updates for a RGB-color novation device. - /// - public class RGBColorUpdateQueue : MidiUpdateQueue - { - #region Properties & Fields + #region Properties & Fields - private static readonly (Color, int)[] COLOR_PALETTE = - { - (new Color(0, 0, 0), 0), - (new Color(28, 28, 28), 1), - (new Color(124, 124, 124), 2), - (new Color(252, 252, 252), 3), - (new Color(255, 77, 71), 4), - (new Color(255, 10, 0), 5), - (new Color(90, 1, 0), 6), - (new Color(25, 0, 0), 7), - (new Color(255, 189, 98), 8), - (new Color(255, 86, 0), 9), - (new Color(90, 29, 0), 10), - (new Color(36, 24, 0), 11), - (new Color(253, 253, 33), 12), - (new Color(253, 253, 0), 13), - (new Color(88, 88, 0), 14), - (new Color(24, 24, 0), 15), - (new Color(128, 253, 42), 16), - (new Color(64, 253, 0), 17), - (new Color(22, 88, 0), 18), - (new Color(19, 40, 0), 19), - (new Color(52, 253, 43), 20), - (new Color(0, 253, 0), 21), - (new Color(0, 88, 0), 22), - (new Color(0, 24, 0), 23), - (new Color(51, 253, 70), 24), - (new Color(50, 253, 126), 28), - (new Color(0, 253, 58), 29), - (new Color(0, 88, 20), 30), - (new Color(0, 28, 15), 31), - (new Color(47, 252, 176), 32), - (new Color(0, 252, 145), 33), - (new Color(0, 88, 49), 34), - (new Color(0, 24, 15), 35), - (new Color(57, 191, 255), 36), - (new Color(0, 167, 255), 37), - (new Color(0, 64, 81), 38), - (new Color(0, 16, 24), 39), - (new Color(65, 134, 255), 40), - (new Color(0, 80, 255), 41), - (new Color(0, 26, 90), 42), - (new Color(0, 7, 25), 43), - (new Color(70, 71, 255), 44), - (new Color(0, 0, 255), 45), - (new Color(0, 0, 91), 46), - (new Color(0, 0, 25), 47), - (new Color(131, 71, 255), 48), - (new Color(80, 0, 255), 49), - (new Color(22, 0, 103), 50), - (new Color(11, 0, 50), 51), - (new Color(255, 73, 255), 52), - (new Color(255, 0, 255), 53), - (new Color(90, 0, 90), 54), - (new Color(25, 0, 25), 55), - (new Color(255, 77, 132), 56), - (new Color(255, 7, 82), 57), - (new Color(90, 1, 27), 58), - (new Color(33, 0, 16), 59), - (new Color(255, 25, 0), 60), - (new Color(155, 53, 0), 61), - (new Color(122, 81, 0), 62), - (new Color(62, 100, 0), 63), - (new Color(0, 56, 0), 64), - (new Color(0, 84, 50), 65), - (new Color(0, 83, 126), 66), - (new Color(0, 68, 77), 68), - (new Color(27, 0, 210), 69), - (new Color(32, 32, 32), 71), - (new Color(186, 253, 0), 73), - (new Color(170, 237, 0), 74), - (new Color(86, 253, 0), 75), - (new Color(0, 136, 0), 76), - (new Color(0, 252, 122), 77), - (new Color(0, 27, 255), 79), - (new Color(53, 0, 255), 80), - (new Color(119, 0, 255), 81), - (new Color(180, 23, 126), 82), - (new Color(65, 32, 0), 83), - (new Color(255, 74, 0), 84), - (new Color(131, 225, 0), 85), - (new Color(101, 253, 0), 86), - (new Color(69, 253, 97), 89), - (new Color(0, 252, 202), 90), - (new Color(80, 134, 255), 91), - (new Color(39, 77, 201), 92), - (new Color(130, 122, 237), 93), - (new Color(211, 12, 255), 94), - (new Color(255, 6, 90), 95), - (new Color(255, 125, 0), 96), - (new Color(185, 177, 0), 97), - (new Color(138, 253, 0), 98), - (new Color(130, 93, 0), 99), - (new Color(57, 40, 0), 100), - (new Color(13, 76, 5), 101), - (new Color(0, 80, 55), 102), - (new Color(19, 19, 41), 103), - (new Color(16, 31, 90), 104), - (new Color(106, 60, 23), 105), - (new Color(172, 4, 0), 106), - (new Color(225, 81, 53), 107), - (new Color(220, 105, 0), 108), - (new Color(255, 255, 0), 109), - (new Color(153, 225, 0), 110), - (new Color(95, 181, 0), 111), - (new Color(27, 27, 49), 112), - (new Color(220, 253, 84), 113), - (new Color(118, 252, 184), 114), - (new Color(150, 151, 255), 115), - (new Color(139, 97, 255), 116), - (new Color(64, 64, 64), 117), - (new Color(116, 116, 116), 118), - (new Color(222, 252, 252), 119), - (new Color(164, 4, 0), 120), - (new Color(53, 0, 0), 121), - (new Color(0, 209, 0), 122), - (new Color(0, 64, 0), 123), - (new Color(61, 48, 0), 125), - (new Color(180, 93, 0), 126), - (new Color(74, 20, 0), 127), - }; + private static readonly (Color, int)[] COLOR_PALETTE = + { + (new Color(0, 0, 0), 0), + (new Color(28, 28, 28), 1), + (new Color(124, 124, 124), 2), + (new Color(252, 252, 252), 3), + (new Color(255, 77, 71), 4), + (new Color(255, 10, 0), 5), + (new Color(90, 1, 0), 6), + (new Color(25, 0, 0), 7), + (new Color(255, 189, 98), 8), + (new Color(255, 86, 0), 9), + (new Color(90, 29, 0), 10), + (new Color(36, 24, 0), 11), + (new Color(253, 253, 33), 12), + (new Color(253, 253, 0), 13), + (new Color(88, 88, 0), 14), + (new Color(24, 24, 0), 15), + (new Color(128, 253, 42), 16), + (new Color(64, 253, 0), 17), + (new Color(22, 88, 0), 18), + (new Color(19, 40, 0), 19), + (new Color(52, 253, 43), 20), + (new Color(0, 253, 0), 21), + (new Color(0, 88, 0), 22), + (new Color(0, 24, 0), 23), + (new Color(51, 253, 70), 24), + (new Color(50, 253, 126), 28), + (new Color(0, 253, 58), 29), + (new Color(0, 88, 20), 30), + (new Color(0, 28, 15), 31), + (new Color(47, 252, 176), 32), + (new Color(0, 252, 145), 33), + (new Color(0, 88, 49), 34), + (new Color(0, 24, 15), 35), + (new Color(57, 191, 255), 36), + (new Color(0, 167, 255), 37), + (new Color(0, 64, 81), 38), + (new Color(0, 16, 24), 39), + (new Color(65, 134, 255), 40), + (new Color(0, 80, 255), 41), + (new Color(0, 26, 90), 42), + (new Color(0, 7, 25), 43), + (new Color(70, 71, 255), 44), + (new Color(0, 0, 255), 45), + (new Color(0, 0, 91), 46), + (new Color(0, 0, 25), 47), + (new Color(131, 71, 255), 48), + (new Color(80, 0, 255), 49), + (new Color(22, 0, 103), 50), + (new Color(11, 0, 50), 51), + (new Color(255, 73, 255), 52), + (new Color(255, 0, 255), 53), + (new Color(90, 0, 90), 54), + (new Color(25, 0, 25), 55), + (new Color(255, 77, 132), 56), + (new Color(255, 7, 82), 57), + (new Color(90, 1, 27), 58), + (new Color(33, 0, 16), 59), + (new Color(255, 25, 0), 60), + (new Color(155, 53, 0), 61), + (new Color(122, 81, 0), 62), + (new Color(62, 100, 0), 63), + (new Color(0, 56, 0), 64), + (new Color(0, 84, 50), 65), + (new Color(0, 83, 126), 66), + (new Color(0, 68, 77), 68), + (new Color(27, 0, 210), 69), + (new Color(32, 32, 32), 71), + (new Color(186, 253, 0), 73), + (new Color(170, 237, 0), 74), + (new Color(86, 253, 0), 75), + (new Color(0, 136, 0), 76), + (new Color(0, 252, 122), 77), + (new Color(0, 27, 255), 79), + (new Color(53, 0, 255), 80), + (new Color(119, 0, 255), 81), + (new Color(180, 23, 126), 82), + (new Color(65, 32, 0), 83), + (new Color(255, 74, 0), 84), + (new Color(131, 225, 0), 85), + (new Color(101, 253, 0), 86), + (new Color(69, 253, 97), 89), + (new Color(0, 252, 202), 90), + (new Color(80, 134, 255), 91), + (new Color(39, 77, 201), 92), + (new Color(130, 122, 237), 93), + (new Color(211, 12, 255), 94), + (new Color(255, 6, 90), 95), + (new Color(255, 125, 0), 96), + (new Color(185, 177, 0), 97), + (new Color(138, 253, 0), 98), + (new Color(130, 93, 0), 99), + (new Color(57, 40, 0), 100), + (new Color(13, 76, 5), 101), + (new Color(0, 80, 55), 102), + (new Color(19, 19, 41), 103), + (new Color(16, 31, 90), 104), + (new Color(106, 60, 23), 105), + (new Color(172, 4, 0), 106), + (new Color(225, 81, 53), 107), + (new Color(220, 105, 0), 108), + (new Color(255, 255, 0), 109), + (new Color(153, 225, 0), 110), + (new Color(95, 181, 0), 111), + (new Color(27, 27, 49), 112), + (new Color(220, 253, 84), 113), + (new Color(118, 252, 184), 114), + (new Color(150, 151, 255), 115), + (new Color(139, 97, 255), 116), + (new Color(64, 64, 64), 117), + (new Color(116, 116, 116), 118), + (new Color(222, 252, 252), 119), + (new Color(164, 4, 0), 120), + (new Color(53, 0, 0), 121), + (new Color(0, 209, 0), 122), + (new Color(0, 64, 0), 123), + (new Color(61, 48, 0), 125), + (new Color(180, 93, 0), 126), + (new Color(74, 20, 0), 127), + }; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The device-id of the device this queue is performing updates for. - public RGBColorUpdateQueue(IDeviceUpdateTrigger updateTrigger, int deviceId) - : base(updateTrigger, deviceId) - { } + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The device-id of the device this queue is performing updates for. + public RGBColorUpdateQueue(IDeviceUpdateTrigger updateTrigger, int deviceId) + : base(updateTrigger, deviceId) + { } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override ShortMessage CreateMessage(KeyValuePair data) - { - (byte mode, byte id) = ((byte, byte))data.Key; - if (mode == 0x00) return null; + /// + protected override ShortMessage? CreateMessage(object key, in Color color) + { + (byte mode, byte id) = ((byte, byte))key; + if (mode == 0x00) return null; - return new ShortMessage(mode, id, Convert.ToByte(ConvertColor(data.Value))); - } + return new ShortMessage(mode, id, Convert.ToByte(ConvertColor(color))); + } - /// - /// Convert a to its novation-representation depending on the of the . - /// Source: http://www.launchpadfun.com/downloads_de/velocity-colors/ - /// - /// The to convert. - /// The novation-representation of the . - protected virtual int ConvertColor(Color color) + /// + /// Convert a to its novation-representation depending on the of the . + /// Source: http://www.launchpadfun.com/downloads_de/velocity-colors/ + /// + /// The to convert. + /// The novation-representation of the . + protected virtual int ConvertColor(in Color color) + { + int bestVelocity = 0; + double bestMatchDistance = double.MaxValue; + foreach ((Color c, int velocity) in COLOR_PALETTE) { - int bestVelocity = 0; - double bestMatchDistance = double.MaxValue; - foreach ((Color c, int velocity) in COLOR_PALETTE) + double distance = c.DistanceTo(color); + if (distance < bestMatchDistance) { - double distance = c.DistanceTo(color); - if (distance < bestMatchDistance) - { - bestVelocity = velocity; - bestMatchDistance = distance; - } + bestVelocity = velocity; + bestMatchDistance = distance; } - - return bestVelocity; } - /// - public override void Reset() - { - base.Reset(); - SendMessage(new ShortMessage(Convert.ToByte(0xB0), Convert.ToByte(0), Convert.ToByte(0))); - } + return bestVelocity; + } - #endregion + /// + public override void Reset() + { + base.Reset(); + SendMessage(new ShortMessage(Convert.ToByte(0xB0), Convert.ToByte(0), Convert.ToByte(0))); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Helper/EnumExtension.cs b/RGB.NET.Devices.Novation/Helper/EnumExtension.cs index a3f432a7..27de266f 100644 --- a/RGB.NET.Devices.Novation/Helper/EnumExtension.cs +++ b/RGB.NET.Devices.Novation/Helper/EnumExtension.cs @@ -2,46 +2,46 @@ using System.Reflection; using RGB.NET.Devices.Novation.Attributes; -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +/// +/// Offers some extensions and helper-methods for enum related things. +/// +internal static class EnumExtension { /// - /// Offers some extensions and helper-methods for enum related things. + /// Gets the value of the . /// - internal static class EnumExtension - { - /// - /// Gets the value of the . - /// - /// The enum value to get the description from. - /// The value of the of the source. - internal static string GetDeviceId(this Enum source) => source.GetAttribute()?.Id; + /// The enum value to get the description from. + /// The value of the of the source. + internal static string? GetDeviceId(this Enum source) => source.GetAttribute()?.Id; - /// - /// Gets the value of the . - /// - /// The enum value to get the description from. - /// The value of the of the source. - internal static NovationColorCapabilities GetColorCapability(this Enum source) => source.GetAttribute()?.Capability ?? NovationColorCapabilities.None; + /// + /// Gets the value of the . + /// + /// The enum value to get the description from. + /// The value of the of the source. + internal static NovationColorCapabilities GetColorCapability(this Enum source) => source.GetAttribute()?.Capability ?? NovationColorCapabilities.None; - /// - /// Gets the value of the . - /// - /// The enum value to get the description from. - /// The value of the of the source. - internal static LedIdMappings GetLedIdMapping(this Enum source) => source.GetAttribute()?.LedIdMapping ?? LedIdMappings.Current; + /// + /// Gets the value of the . + /// + /// The enum value to get the description from. + /// The value of the of the source. + internal static LedIdMappings GetLedIdMapping(this Enum source) => source.GetAttribute()?.LedIdMapping ?? LedIdMappings.Current; - /// - /// Gets the attribute of type T. - /// - /// The enum value to get the attribute from - /// The generic attribute type - /// The . - private static T GetAttribute(this Enum source) - where T : Attribute - { - FieldInfo fi = source.GetType().GetField(source.ToString()); - T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); - return attributes.Length > 0 ? attributes[0] : null; - } + /// + /// Gets the attribute of type T. + /// + /// The enum value to get the attribute from + /// The generic attribute type + /// The . + private static T? GetAttribute(this Enum source) + where T : Attribute + { + FieldInfo? fi = source.GetType().GetField(source.ToString()); + if (fi == null) return null; + T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); + return attributes.Length > 0 ? attributes[0] : null; } -} +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Launchpad/LaunchpadIdMapping.cs b/RGB.NET.Devices.Novation/Launchpad/LaunchpadIdMapping.cs index 39aa29f4..81a6793b 100644 --- a/RGB.NET.Devices.Novation/Launchpad/LaunchpadIdMapping.cs +++ b/RGB.NET.Devices.Novation/Launchpad/LaunchpadIdMapping.cs @@ -1,184 +1,289 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +internal static class LaunchpadIdMapping { - internal static class LaunchpadIdMapping + internal static readonly Dictionary LEGACY = new() { - internal static readonly Dictionary LEGACY = new Dictionary - { - { LedId.Invalid, (0x00, 0xFF, 8, 0) }, + { LedId.Invalid, (0x00, 0xFF, 8, 0) }, + + { LedId.LedMatrix1, (0x90, 0x00, 0, 1) }, + { LedId.LedMatrix2, (0x90, 0x01, 1, 1) }, + { LedId.LedMatrix3, (0x90, 0x02, 2, 1) }, + { LedId.LedMatrix4, (0x90, 0x03, 3, 1) }, + { LedId.LedMatrix5, (0x90, 0x04, 4, 1) }, + { LedId.LedMatrix6, (0x90, 0x05, 5, 1) }, + { LedId.LedMatrix7, (0x90, 0x06, 6, 1) }, + { LedId.LedMatrix8, (0x90, 0x07, 7, 1) }, + { LedId.LedMatrix9, (0x90, 0x10, 0, 2) }, + { LedId.LedMatrix10, (0x90, 0x11, 1, 2) }, + { LedId.LedMatrix11, (0x90, 0x12, 2, 2) }, + { LedId.LedMatrix12, (0x90, 0x13, 3, 2) }, + { LedId.LedMatrix13, (0x90, 0x14, 4, 2) }, + { LedId.LedMatrix14, (0x90, 0x15, 5, 2) }, + { LedId.LedMatrix15, (0x90, 0x16, 6, 2) }, + { LedId.LedMatrix16, (0x90, 0x17, 7, 2) }, + { LedId.LedMatrix17, (0x90, 0x20, 0, 3) }, + { LedId.LedMatrix18, (0x90, 0x21, 1, 3) }, + { LedId.LedMatrix19, (0x90, 0x22, 2, 3) }, + { LedId.LedMatrix20, (0x90, 0x23, 3, 3) }, + { LedId.LedMatrix21, (0x90, 0x24, 4, 3) }, + { LedId.LedMatrix22, (0x90, 0x25, 5, 3) }, + { LedId.LedMatrix23, (0x90, 0x26, 6, 3) }, + { LedId.LedMatrix24, (0x90, 0x27, 7, 3) }, + { LedId.LedMatrix25, (0x90, 0x30, 0, 4) }, + { LedId.LedMatrix26, (0x90, 0x31, 1, 4) }, + { LedId.LedMatrix27, (0x90, 0x32, 2, 4) }, + { LedId.LedMatrix28, (0x90, 0x33, 3, 4) }, + { LedId.LedMatrix29, (0x90, 0x34, 4, 4) }, + { LedId.LedMatrix30, (0x90, 0x35, 5, 4) }, + { LedId.LedMatrix31, (0x90, 0x36, 6, 4) }, + { LedId.LedMatrix32, (0x90, 0x37, 7, 4) }, + { LedId.LedMatrix33, (0x90, 0x40, 0, 5) }, + { LedId.LedMatrix34, (0x90, 0x41, 1, 5) }, + { LedId.LedMatrix35, (0x90, 0x42, 2, 5) }, + { LedId.LedMatrix36, (0x90, 0x43, 3, 5) }, + { LedId.LedMatrix37, (0x90, 0x44, 4, 5) }, + { LedId.LedMatrix38, (0x90, 0x45, 5, 5) }, + { LedId.LedMatrix39, (0x90, 0x46, 6, 5) }, + { LedId.LedMatrix40, (0x90, 0x47, 7, 5) }, + { LedId.LedMatrix41, (0x90, 0x50, 0, 6) }, + { LedId.LedMatrix42, (0x90, 0x51, 1, 6) }, + { LedId.LedMatrix43, (0x90, 0x52, 2, 6) }, + { LedId.LedMatrix44, (0x90, 0x53, 3, 6) }, + { LedId.LedMatrix45, (0x90, 0x54, 4, 6) }, + { LedId.LedMatrix46, (0x90, 0x55, 5, 6) }, + { LedId.LedMatrix47, (0x90, 0x56, 6, 6) }, + { LedId.LedMatrix48, (0x90, 0x57, 7, 6) }, + { LedId.LedMatrix49, (0x90, 0x60, 0, 7) }, + { LedId.LedMatrix50, (0x90, 0x61, 1, 7) }, + { LedId.LedMatrix51, (0x90, 0x62, 2, 7) }, + { LedId.LedMatrix52, (0x90, 0x63, 3, 7) }, + { LedId.LedMatrix53, (0x90, 0x64, 4, 7) }, + { LedId.LedMatrix54, (0x90, 0x65, 5, 7) }, + { LedId.LedMatrix55, (0x90, 0x66, 6, 7) }, + { LedId.LedMatrix56, (0x90, 0x67, 7, 7) }, + { LedId.LedMatrix57, (0x90, 0x70, 0, 8) }, + { LedId.LedMatrix58, (0x90, 0x71, 1, 8) }, + { LedId.LedMatrix59, (0x90, 0x72, 2, 8) }, + { LedId.LedMatrix60, (0x90, 0x73, 3, 8) }, + { LedId.LedMatrix61, (0x90, 0x74, 4, 8) }, + { LedId.LedMatrix62, (0x90, 0x75, 5, 8) }, + { LedId.LedMatrix63, (0x90, 0x76, 6, 8) }, + { LedId.LedMatrix64, (0x90, 0x77, 7, 8) }, + + { LedId.Custom1, (0xB0, 0x68, 0, 0) }, // Up + { LedId.Custom2, (0xB0, 0x69, 1, 0) }, // Down + { LedId.Custom3, (0xB0, 0x6A, 2, 0) }, // Left + { LedId.Custom4, (0xB0, 0x6B, 3, 0) }, // Right + { LedId.Custom5, (0xB0, 0x6C, 4, 0) }, // Session + { LedId.Custom6, (0xB0, 0x6D, 5, 0) }, // User 1 + { LedId.Custom7, (0xB0, 0x6E, 6, 0) }, // User 2 + { LedId.Custom8, (0xB0, 0x6F, 7, 0) }, // Mix - { LedId.LedMatrix1, (0x90, 0x00, 0, 1) }, - { LedId.LedMatrix2, (0x90, 0x01, 1, 1) }, - { LedId.LedMatrix3, (0x90, 0x02, 2, 1) }, - { LedId.LedMatrix4, (0x90, 0x03, 3, 1) }, - { LedId.LedMatrix5, (0x90, 0x04, 4, 1) }, - { LedId.LedMatrix6, (0x90, 0x05, 5, 1) }, - { LedId.LedMatrix7, (0x90, 0x06, 6, 1) }, - { LedId.LedMatrix8, (0x90, 0x07, 7, 1) }, - { LedId.LedMatrix9, (0x90, 0x10, 0, 2) }, - { LedId.LedMatrix10, (0x90, 0x11, 1, 2) }, - { LedId.LedMatrix11, (0x90, 0x12, 2, 2) }, - { LedId.LedMatrix12, (0x90, 0x13, 3, 2) }, - { LedId.LedMatrix13, (0x90, 0x14, 4, 2) }, - { LedId.LedMatrix14, (0x90, 0x15, 5, 2) }, - { LedId.LedMatrix15, (0x90, 0x16, 6, 2) }, - { LedId.LedMatrix16, (0x90, 0x17, 7, 2) }, - { LedId.LedMatrix17, (0x90, 0x20, 0, 3) }, - { LedId.LedMatrix18, (0x90, 0x21, 1, 3) }, - { LedId.LedMatrix19, (0x90, 0x22, 2, 3) }, - { LedId.LedMatrix20, (0x90, 0x23, 3, 3) }, - { LedId.LedMatrix21, (0x90, 0x24, 4, 3) }, - { LedId.LedMatrix22, (0x90, 0x25, 5, 3) }, - { LedId.LedMatrix23, (0x90, 0x26, 6, 3) }, - { LedId.LedMatrix24, (0x90, 0x27, 7, 3) }, - { LedId.LedMatrix25, (0x90, 0x30, 0, 4) }, - { LedId.LedMatrix26, (0x90, 0x31, 1, 4) }, - { LedId.LedMatrix27, (0x90, 0x32, 2, 4) }, - { LedId.LedMatrix28, (0x90, 0x33, 3, 4) }, - { LedId.LedMatrix29, (0x90, 0x34, 4, 4) }, - { LedId.LedMatrix30, (0x90, 0x35, 5, 4) }, - { LedId.LedMatrix31, (0x90, 0x36, 6, 4) }, - { LedId.LedMatrix32, (0x90, 0x37, 7, 4) }, - { LedId.LedMatrix33, (0x90, 0x40, 0, 5) }, - { LedId.LedMatrix34, (0x90, 0x41, 1, 5) }, - { LedId.LedMatrix35, (0x90, 0x42, 2, 5) }, - { LedId.LedMatrix36, (0x90, 0x43, 3, 5) }, - { LedId.LedMatrix37, (0x90, 0x44, 4, 5) }, - { LedId.LedMatrix38, (0x90, 0x45, 5, 5) }, - { LedId.LedMatrix39, (0x90, 0x46, 6, 5) }, - { LedId.LedMatrix40, (0x90, 0x47, 7, 5) }, - { LedId.LedMatrix41, (0x90, 0x50, 0, 6) }, - { LedId.LedMatrix42, (0x90, 0x51, 1, 6) }, - { LedId.LedMatrix43, (0x90, 0x52, 2, 6) }, - { LedId.LedMatrix44, (0x90, 0x53, 3, 6) }, - { LedId.LedMatrix45, (0x90, 0x54, 4, 6) }, - { LedId.LedMatrix46, (0x90, 0x55, 5, 6) }, - { LedId.LedMatrix47, (0x90, 0x56, 6, 6) }, - { LedId.LedMatrix48, (0x90, 0x57, 7, 6) }, - { LedId.LedMatrix49, (0x90, 0x60, 0, 7) }, - { LedId.LedMatrix50, (0x90, 0x61, 1, 7) }, - { LedId.LedMatrix51, (0x90, 0x62, 2, 7) }, - { LedId.LedMatrix52, (0x90, 0x63, 3, 7) }, - { LedId.LedMatrix53, (0x90, 0x64, 4, 7) }, - { LedId.LedMatrix54, (0x90, 0x65, 5, 7) }, - { LedId.LedMatrix55, (0x90, 0x66, 6, 7) }, - { LedId.LedMatrix56, (0x90, 0x67, 7, 7) }, - { LedId.LedMatrix57, (0x90, 0x70, 0, 8) }, - { LedId.LedMatrix58, (0x90, 0x71, 1, 8) }, - { LedId.LedMatrix59, (0x90, 0x72, 2, 8) }, - { LedId.LedMatrix60, (0x90, 0x73, 3, 8) }, - { LedId.LedMatrix61, (0x90, 0x74, 4, 8) }, - { LedId.LedMatrix62, (0x90, 0x75, 5, 8) }, - { LedId.LedMatrix63, (0x90, 0x76, 6, 8) }, - { LedId.LedMatrix64, (0x90, 0x77, 7, 8) }, + { LedId.Custom9, (0x90, 0x08, 8, 1) }, //Scene1 + { LedId.Custom10, (0x90, 0x18, 8, 2) }, //Scene2 + { LedId.Custom11, (0x90, 0x28, 8, 3) }, //Scene3 + { LedId.Custom12, (0x90, 0x38, 8, 4) }, //Scene4 + { LedId.Custom13, (0x90, 0x48, 8, 5) }, //Scene5 + { LedId.Custom14, (0x90, 0x58, 8, 6) }, //Scene6 + { LedId.Custom15, (0x90, 0x68, 8, 7) }, //Scene7 + { LedId.Custom16, (0x90, 0x78, 8, 8) }, //Scene8 + }; + + internal static readonly Dictionary CURRENT = new() + { + { LedId.Invalid, (0x00, 0xFF, 8, 0) }, - { LedId.Custom1, (0xB0, 0x68, 0, 0) }, // Up - { LedId.Custom2, (0xB0, 0x69, 1, 0) }, // Down - { LedId.Custom3, (0xB0, 0x6A, 2, 0) }, // Left - { LedId.Custom4, (0xB0, 0x6B, 3, 0) }, // Right - { LedId.Custom5, (0xB0, 0x6C, 4, 0) }, // Session - { LedId.Custom6, (0xB0, 0x6D, 5, 0) }, // User 1 - { LedId.Custom7, (0xB0, 0x6E, 6, 0) }, // User 2 - { LedId.Custom8, (0xB0, 0x6F, 7, 0) }, // Mix + { LedId.LedMatrix1, (0x90, 81, 0, 1) }, + { LedId.LedMatrix2, (0x90, 82, 1, 1) }, + { LedId.LedMatrix3, (0x90, 83, 2, 1) }, + { LedId.LedMatrix4, (0x90, 84, 3, 1) }, + { LedId.LedMatrix5, (0x90, 85, 4, 1) }, + { LedId.LedMatrix6, (0x90, 86, 5, 1) }, + { LedId.LedMatrix7, (0x90, 87, 6, 1) }, + { LedId.LedMatrix8, (0x90, 88, 7, 1) }, + { LedId.LedMatrix9, (0x90, 71, 0, 2) }, + { LedId.LedMatrix10, (0x90, 72, 1, 2) }, + { LedId.LedMatrix11, (0x90, 73, 2, 2) }, + { LedId.LedMatrix12, (0x90, 74, 3, 2) }, + { LedId.LedMatrix13, (0x90, 75, 4, 2) }, + { LedId.LedMatrix14, (0x90, 76, 5, 2) }, + { LedId.LedMatrix15, (0x90, 77, 6, 2) }, + { LedId.LedMatrix16, (0x90, 78, 7, 2) }, + { LedId.LedMatrix17, (0x90, 61, 0, 3) }, + { LedId.LedMatrix18, (0x90, 62, 1, 3) }, + { LedId.LedMatrix19, (0x90, 63, 2, 3) }, + { LedId.LedMatrix20, (0x90, 64, 3, 3) }, + { LedId.LedMatrix21, (0x90, 65, 4, 3) }, + { LedId.LedMatrix22, (0x90, 66, 5, 3) }, + { LedId.LedMatrix23, (0x90, 67, 6, 3) }, + { LedId.LedMatrix24, (0x90, 68, 7, 3) }, + { LedId.LedMatrix25, (0x90, 51, 0, 4) }, + { LedId.LedMatrix26, (0x90, 52, 1, 4) }, + { LedId.LedMatrix27, (0x90, 53, 2, 4) }, + { LedId.LedMatrix28, (0x90, 54, 3, 4) }, + { LedId.LedMatrix29, (0x90, 55, 4, 4) }, + { LedId.LedMatrix30, (0x90, 56, 5, 4) }, + { LedId.LedMatrix31, (0x90, 57, 6, 4) }, + { LedId.LedMatrix32, (0x90, 58, 7, 4) }, + { LedId.LedMatrix33, (0x90, 41, 0, 5) }, + { LedId.LedMatrix34, (0x90, 42, 1, 5) }, + { LedId.LedMatrix35, (0x90, 43, 2, 5) }, + { LedId.LedMatrix36, (0x90, 44, 3, 5) }, + { LedId.LedMatrix37, (0x90, 45, 4, 5) }, + { LedId.LedMatrix38, (0x90, 46, 5, 5) }, + { LedId.LedMatrix39, (0x90, 47, 6, 5) }, + { LedId.LedMatrix40, (0x90, 48, 7, 5) }, + { LedId.LedMatrix41, (0x90, 31, 0, 6) }, + { LedId.LedMatrix42, (0x90, 32, 1, 6) }, + { LedId.LedMatrix43, (0x90, 33, 2, 6) }, + { LedId.LedMatrix44, (0x90, 34, 3, 6) }, + { LedId.LedMatrix45, (0x90, 35, 4, 6) }, + { LedId.LedMatrix46, (0x90, 36, 5, 6) }, + { LedId.LedMatrix47, (0x90, 37, 6, 6) }, + { LedId.LedMatrix48, (0x90, 38, 7, 6) }, + { LedId.LedMatrix49, (0x90, 21, 0, 7) }, + { LedId.LedMatrix50, (0x90, 22, 1, 7) }, + { LedId.LedMatrix51, (0x90, 23, 2, 7) }, + { LedId.LedMatrix52, (0x90, 24, 3, 7) }, + { LedId.LedMatrix53, (0x90, 25, 4, 7) }, + { LedId.LedMatrix54, (0x90, 26, 5, 7) }, + { LedId.LedMatrix55, (0x90, 27, 6, 7) }, + { LedId.LedMatrix56, (0x90, 28, 7, 7) }, + { LedId.LedMatrix57, (0x90, 11, 0, 8) }, + { LedId.LedMatrix58, (0x90, 12, 1, 8) }, + { LedId.LedMatrix59, (0x90, 13, 2, 8) }, + { LedId.LedMatrix60, (0x90, 14, 3, 8) }, + { LedId.LedMatrix61, (0x90, 15, 4, 8) }, + { LedId.LedMatrix62, (0x90, 16, 5, 8) }, + { LedId.LedMatrix63, (0x90, 17, 6, 8) }, + { LedId.LedMatrix64, (0x90, 18, 7, 8) }, + + { LedId.Custom1, (0xB0, 104, 0, 0) }, // Up + { LedId.Custom2, (0xB0, 105, 1, 0) }, // Down + { LedId.Custom3, (0xB0, 106, 2, 0) }, // Left + { LedId.Custom4, (0xB0, 107, 3, 0) }, // Right + { LedId.Custom5, (0xB0, 108, 4, 0) }, // Session + { LedId.Custom6, (0xB0, 109, 5, 0) }, // User 1 + { LedId.Custom7, (0xB0, 110, 6, 0) }, // User 2 + { LedId.Custom8, (0xB0, 111, 7, 0) }, // Mix + + { LedId.Custom9, (0x90, 89, 8, 1) }, //Scene1 + { LedId.Custom10, (0x90, 79, 8, 2) }, //Scene2 + { LedId.Custom11, (0x90, 69, 8, 3) }, //Scene3 + { LedId.Custom12, (0x90, 59, 8, 4) }, //Scene4 + { LedId.Custom13, (0x90, 49, 8, 5) }, //Scene5 + { LedId.Custom14, (0x90, 39, 8, 6) }, //Scene6 + { LedId.Custom15, (0x90, 29, 8, 7) }, //Scene7 + { LedId.Custom16, (0x90, 19, 8, 8) }, //Scene8 + }; + + internal static readonly Dictionary PRO = new() + { + { LedId.Invalid, (0x00, 0xFF, 8, 0) }, - { LedId.Custom9, (0x90, 0x08, 8, 1) }, //Scene1 - { LedId.Custom10, (0x90, 0x18, 8, 2) }, //Scene2 - { LedId.Custom11, (0x90, 0x28, 8, 3) }, //Scene3 - { LedId.Custom12, (0x90, 0x38, 8, 4) }, //Scene4 - { LedId.Custom13, (0x90, 0x48, 8, 5) }, //Scene5 - { LedId.Custom14, (0x90, 0x58, 8, 6) }, //Scene6 - { LedId.Custom15, (0x90, 0x68, 8, 7) }, //Scene7 - { LedId.Custom16, (0x90, 0x78, 8, 8) }, //Scene8 - }; + { LedId.LedMatrix1, (0x90, 81, 0, 1) }, + { LedId.LedMatrix2, (0x90, 82, 1, 1) }, + { LedId.LedMatrix3, (0x90, 83, 2, 1) }, + { LedId.LedMatrix4, (0x90, 84, 3, 1) }, + { LedId.LedMatrix5, (0x90, 85, 4, 1) }, + { LedId.LedMatrix6, (0x90, 86, 5, 1) }, + { LedId.LedMatrix7, (0x90, 87, 6, 1) }, + { LedId.LedMatrix8, (0x90, 88, 7, 1) }, + { LedId.LedMatrix9, (0x90, 71, 0, 2) }, + { LedId.LedMatrix10, (0x90, 72, 1, 2) }, + { LedId.LedMatrix11, (0x90, 73, 2, 2) }, + { LedId.LedMatrix12, (0x90, 74, 3, 2) }, + { LedId.LedMatrix13, (0x90, 75, 4, 2) }, + { LedId.LedMatrix14, (0x90, 76, 5, 2) }, + { LedId.LedMatrix15, (0x90, 77, 6, 2) }, + { LedId.LedMatrix16, (0x90, 78, 7, 2) }, + { LedId.LedMatrix17, (0x90, 61, 0, 3) }, + { LedId.LedMatrix18, (0x90, 62, 1, 3) }, + { LedId.LedMatrix19, (0x90, 63, 2, 3) }, + { LedId.LedMatrix20, (0x90, 64, 3, 3) }, + { LedId.LedMatrix21, (0x90, 65, 4, 3) }, + { LedId.LedMatrix22, (0x90, 66, 5, 3) }, + { LedId.LedMatrix23, (0x90, 67, 6, 3) }, + { LedId.LedMatrix24, (0x90, 68, 7, 3) }, + { LedId.LedMatrix25, (0x90, 51, 0, 4) }, + { LedId.LedMatrix26, (0x90, 52, 1, 4) }, + { LedId.LedMatrix27, (0x90, 53, 2, 4) }, + { LedId.LedMatrix28, (0x90, 54, 3, 4) }, + { LedId.LedMatrix29, (0x90, 55, 4, 4) }, + { LedId.LedMatrix30, (0x90, 56, 5, 4) }, + { LedId.LedMatrix31, (0x90, 57, 6, 4) }, + { LedId.LedMatrix32, (0x90, 58, 7, 4) }, + { LedId.LedMatrix33, (0x90, 41, 0, 5) }, + { LedId.LedMatrix34, (0x90, 42, 1, 5) }, + { LedId.LedMatrix35, (0x90, 43, 2, 5) }, + { LedId.LedMatrix36, (0x90, 44, 3, 5) }, + { LedId.LedMatrix37, (0x90, 45, 4, 5) }, + { LedId.LedMatrix38, (0x90, 46, 5, 5) }, + { LedId.LedMatrix39, (0x90, 47, 6, 5) }, + { LedId.LedMatrix40, (0x90, 48, 7, 5) }, + { LedId.LedMatrix41, (0x90, 31, 0, 6) }, + { LedId.LedMatrix42, (0x90, 32, 1, 6) }, + { LedId.LedMatrix43, (0x90, 33, 2, 6) }, + { LedId.LedMatrix44, (0x90, 34, 3, 6) }, + { LedId.LedMatrix45, (0x90, 35, 4, 6) }, + { LedId.LedMatrix46, (0x90, 36, 5, 6) }, + { LedId.LedMatrix47, (0x90, 37, 6, 6) }, + { LedId.LedMatrix48, (0x90, 38, 7, 6) }, + { LedId.LedMatrix49, (0x90, 21, 0, 7) }, + { LedId.LedMatrix50, (0x90, 22, 1, 7) }, + { LedId.LedMatrix51, (0x90, 23, 2, 7) }, + { LedId.LedMatrix52, (0x90, 24, 3, 7) }, + { LedId.LedMatrix53, (0x90, 25, 4, 7) }, + { LedId.LedMatrix54, (0x90, 26, 5, 7) }, + { LedId.LedMatrix55, (0x90, 27, 6, 7) }, + { LedId.LedMatrix56, (0x90, 28, 7, 7) }, + { LedId.LedMatrix57, (0x90, 11, 0, 8) }, + { LedId.LedMatrix58, (0x90, 12, 1, 8) }, + { LedId.LedMatrix59, (0x90, 13, 2, 8) }, + { LedId.LedMatrix60, (0x90, 14, 3, 8) }, + { LedId.LedMatrix61, (0x90, 15, 4, 8) }, + { LedId.LedMatrix62, (0x90, 16, 5, 8) }, + { LedId.LedMatrix63, (0x90, 17, 6, 8) }, + { LedId.LedMatrix64, (0x90, 18, 7, 8) }, - internal static readonly Dictionary CURRENT = new Dictionary - { - { LedId.Invalid, (0x00, 0xFF, 8, 0) }, + { LedId.Custom1, (0xB0, 91, 0, 0) }, // Up + { LedId.Custom2, (0xB0, 92, 1, 0) }, // Down + { LedId.Custom3, (0xB0, 93, 2, 0) }, // Left + { LedId.Custom4, (0xB0, 94, 3, 0) }, // Right + { LedId.Custom5, (0xB0, 95, 4, 0) }, // Session + { LedId.Custom6, (0xB0, 96, 5, 0) }, // Note + { LedId.Custom7, (0xB0, 97, 6, 0) }, // Device + { LedId.Custom8, (0xB0, 98, 7, 0) }, // User - { LedId.LedMatrix1, (0x90, 81, 0, 1) }, - { LedId.LedMatrix2, (0x90, 82, 1, 1) }, - { LedId.LedMatrix3, (0x90, 83, 2, 1) }, - { LedId.LedMatrix4, (0x90, 84, 3, 1) }, - { LedId.LedMatrix5, (0x90, 85, 4, 1) }, - { LedId.LedMatrix6, (0x90, 86, 5, 1) }, - { LedId.LedMatrix7, (0x90, 87, 6, 1) }, - { LedId.LedMatrix8, (0x90, 88, 7, 1) }, - { LedId.LedMatrix9, (0x90, 71, 0, 2) }, - { LedId.LedMatrix10, (0x90, 72, 1, 2) }, - { LedId.LedMatrix11, (0x90, 73, 2, 2) }, - { LedId.LedMatrix12, (0x90, 74, 3, 2) }, - { LedId.LedMatrix13, (0x90, 75, 4, 2) }, - { LedId.LedMatrix14, (0x90, 76, 5, 2) }, - { LedId.LedMatrix15, (0x90, 77, 6, 2) }, - { LedId.LedMatrix16, (0x90, 78, 7, 2) }, - { LedId.LedMatrix17, (0x90, 61, 0, 3) }, - { LedId.LedMatrix18, (0x90, 62, 1, 3) }, - { LedId.LedMatrix19, (0x90, 63, 2, 3) }, - { LedId.LedMatrix20, (0x90, 64, 3, 3) }, - { LedId.LedMatrix21, (0x90, 65, 4, 3) }, - { LedId.LedMatrix22, (0x90, 66, 5, 3) }, - { LedId.LedMatrix23, (0x90, 67, 6, 3) }, - { LedId.LedMatrix24, (0x90, 68, 7, 3) }, - { LedId.LedMatrix25, (0x90, 51, 0, 4) }, - { LedId.LedMatrix26, (0x90, 52, 1, 4) }, - { LedId.LedMatrix27, (0x90, 53, 2, 4) }, - { LedId.LedMatrix28, (0x90, 54, 3, 4) }, - { LedId.LedMatrix29, (0x90, 55, 4, 4) }, - { LedId.LedMatrix30, (0x90, 56, 5, 4) }, - { LedId.LedMatrix31, (0x90, 57, 6, 4) }, - { LedId.LedMatrix32, (0x90, 58, 7, 4) }, - { LedId.LedMatrix33, (0x90, 41, 0, 5) }, - { LedId.LedMatrix34, (0x90, 42, 1, 5) }, - { LedId.LedMatrix35, (0x90, 43, 2, 5) }, - { LedId.LedMatrix36, (0x90, 44, 3, 5) }, - { LedId.LedMatrix37, (0x90, 45, 4, 5) }, - { LedId.LedMatrix38, (0x90, 46, 5, 5) }, - { LedId.LedMatrix39, (0x90, 47, 6, 5) }, - { LedId.LedMatrix40, (0x90, 48, 7, 5) }, - { LedId.LedMatrix41, (0x90, 31, 0, 6) }, - { LedId.LedMatrix42, (0x90, 32, 1, 6) }, - { LedId.LedMatrix43, (0x90, 33, 2, 6) }, - { LedId.LedMatrix44, (0x90, 34, 3, 6) }, - { LedId.LedMatrix45, (0x90, 35, 4, 6) }, - { LedId.LedMatrix46, (0x90, 36, 5, 6) }, - { LedId.LedMatrix47, (0x90, 37, 6, 6) }, - { LedId.LedMatrix48, (0x90, 38, 7, 6) }, - { LedId.LedMatrix49, (0x90, 21, 0, 7) }, - { LedId.LedMatrix50, (0x90, 22, 1, 7) }, - { LedId.LedMatrix51, (0x90, 23, 2, 7) }, - { LedId.LedMatrix52, (0x90, 24, 3, 7) }, - { LedId.LedMatrix53, (0x90, 25, 4, 7) }, - { LedId.LedMatrix54, (0x90, 26, 5, 7) }, - { LedId.LedMatrix55, (0x90, 27, 6, 7) }, - { LedId.LedMatrix56, (0x90, 28, 7, 7) }, - { LedId.LedMatrix57, (0x90, 11, 0, 8) }, - { LedId.LedMatrix58, (0x90, 12, 1, 8) }, - { LedId.LedMatrix59, (0x90, 13, 2, 8) }, - { LedId.LedMatrix60, (0x90, 14, 3, 8) }, - { LedId.LedMatrix61, (0x90, 15, 4, 8) }, - { LedId.LedMatrix62, (0x90, 16, 5, 8) }, - { LedId.LedMatrix63, (0x90, 17, 6, 8) }, - { LedId.LedMatrix64, (0x90, 18, 7, 8) }, + { LedId.Custom9, (0x90, 89, 8, 1) }, // Scene1 + { LedId.Custom10, (0x90, 79, 8, 2) }, // Scene2 + { LedId.Custom11, (0x90, 69, 8, 3) }, // Scene3 + { LedId.Custom12, (0x90, 59, 8, 4) }, // Scene4 + { LedId.Custom13, (0x90, 49, 8, 5) }, // Scene5 + { LedId.Custom14, (0x90, 39, 8, 6) }, // Scene6 + { LedId.Custom15, (0x90, 29, 8, 7) }, // Scene7 + { LedId.Custom16, (0x90, 19, 8, 8) }, // Scene8 - { LedId.Custom1, (0xB0, 104, 0, 0) }, // Up - { LedId.Custom2, (0xB0, 105, 1, 0) }, // Down - { LedId.Custom3, (0xB0, 106, 2, 0) }, // Left - { LedId.Custom4, (0xB0, 107, 3, 0) }, // Right - { LedId.Custom5, (0xB0, 108, 4, 0) }, // Session - { LedId.Custom6, (0xB0, 109, 5, 0) }, // User 1 - { LedId.Custom7, (0xB0, 110, 6, 0) }, // User 2 - { LedId.Custom8, (0xB0, 111, 7, 0) }, // Mix + { LedId.Custom17, (0x90, 80, 8, 1) }, // Shift + { LedId.Custom18, (0x90, 70, 8, 2) }, // Click + { LedId.Custom19, (0x90, 60, 8, 3) }, // Undo + { LedId.Custom20, (0x90, 50, 8, 4) }, // Delete + { LedId.Custom21, (0x90, 40, 8, 5) }, // Quantise + { LedId.Custom22, (0x90, 30, 8, 6) }, // Duplicate + { LedId.Custom23, (0x90, 20, 8, 7) }, // Double + { LedId.Custom24, (0x90, 10, 8, 8) }, // Record - { LedId.Custom9, (0x90, 89, 8, 1) }, //Scene1 - { LedId.Custom10, (0x90, 79, 8, 2) }, //Scene2 - { LedId.Custom11, (0x90, 69, 8, 3) }, //Scene3 - { LedId.Custom12, (0x90, 59, 8, 4) }, //Scene4 - { LedId.Custom13, (0x90, 49, 8, 5) }, //Scene5 - { LedId.Custom14, (0x90, 39, 8, 6) }, //Scene6 - { LedId.Custom15, (0x90, 29, 8, 7) }, //Scene7 - { LedId.Custom16, (0x90, 19, 8, 8) }, //Scene8 - }; - } -} + { LedId.Custom25, (0x90, 1, 8, 1) }, // Record Arm + { LedId.Custom26, (0x90, 2, 8, 2) }, // Track Select + { LedId.Custom27, (0x90, 3, 8, 3) }, // Mute + { LedId.Custom28, (0x90, 4, 8, 4) }, // Solo + { LedId.Custom29, (0x90, 5, 8, 5) }, // Volume + { LedId.Custom30, (0x90, 6, 8, 6) }, // Pan + { LedId.Custom31, (0x90, 7, 8, 7) }, // Sends + { LedId.Custom32, (0x90, 8, 8, 8) }, // Stop Clip + }; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Launchpad/LedIdMappings.cs b/RGB.NET.Devices.Novation/Launchpad/LedIdMappings.cs index e264f1a4..93c1539a 100644 --- a/RGB.NET.Devices.Novation/Launchpad/LedIdMappings.cs +++ b/RGB.NET.Devices.Novation/Launchpad/LedIdMappings.cs @@ -1,8 +1,8 @@ -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +internal enum LedIdMappings { - internal enum LedIdMappings - { - Current, - Legacy - } -} + Current, + Legacy, + Pro +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs index e00f1148..81e5dce2 100644 --- a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs +++ b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDevice.cs @@ -2,56 +2,62 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +/// +/// +/// Represents a Novation launchpad. +/// +public class NovationLaunchpadRGBDevice : NovationRGBDevice, ILedMatrix { - /// + #region Constructors + + /// /// - /// Represents a Novation launchpad. + /// Initializes a new instance of the class. /// - public class NovationLaunchpadRGBDevice : NovationRGBDevice, ILedMatrix + /// The specific information provided by Novation for the launchpad + /// The update trigger used to update this device. + internal NovationLaunchpadRGBDevice(NovationLaunchpadRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, updateTrigger) { - #region Constructors + InitializeLayout(); + } - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Novation for the launchpad - internal NovationLaunchpadRGBDevice(NovationLaunchpadRGBDeviceInfo info) - : base(info) - { } + #endregion - #endregion + #region Methods - #region Methods + private void InitializeLayout() + { + Dictionary mapping = GetDeviceMapping(); - /// - protected override void InitializeLayout() + const int BUTTON_SIZE = 20; + foreach (LedId ledId in mapping.Keys) { - Dictionary mapping = GetDeviceMapping(); - - const int BUTTON_SIZE = 20; - foreach (LedId ledId in mapping.Keys) - { - (_, _, int x, int y) = mapping[ledId]; - InitializeLed(ledId, new Point(BUTTON_SIZE * x, BUTTON_SIZE * y), new Size(BUTTON_SIZE)); - } - - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Novation\Launchpads", $"{model.ToUpper()}.xml"), "Default"); + (_, _, int x, int y) = mapping[ledId]; + AddLed(ledId, new Point(BUTTON_SIZE * x, BUTTON_SIZE * y), new Size(BUTTON_SIZE)); } + } - /// - protected override object CreateLedCustomData(LedId ledId) => GetDeviceMapping().TryGetValue(ledId, out (byte mode, byte id, int _, int __) data) ? (data.mode, data.id) : ((byte)0x00, (byte)0x00); + /// + // ReSharper disable RedundantCast + protected override object GetLedCustomData(LedId ledId) => GetDeviceMapping().TryGetValue(ledId, out (byte mode, byte id, int _, int __) data) ? (data.mode, data.id) : ((byte)0x00, (byte)0x00); + // ReSharper restore RedundantCast - protected virtual Dictionary GetDeviceMapping() - => DeviceInfo.LedIdMapping switch - { - LedIdMappings.Current => LaunchpadIdMapping.CURRENT, - LedIdMappings.Legacy => LaunchpadIdMapping.LEGACY, - _ => throw new ArgumentOutOfRangeException() - }; + /// + /// Gets the mapping used to access the LEDs of the device based on . + /// + /// The mapping of the device. + /// Thrown if the value of is not known. + protected virtual Dictionary GetDeviceMapping() + => DeviceInfo.LedMapping switch + { + LedIdMappings.Current => LaunchpadIdMapping.CURRENT, + LedIdMappings.Legacy => LaunchpadIdMapping.LEGACY, + LedIdMappings.Pro => LaunchpadIdMapping.PRO, + _ => throw new ArgumentOutOfRangeException() + }; - #endregion - } + #endregion } \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDeviceInfo.cs b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDeviceInfo.cs index ce86e05a..06296b95 100644 --- a/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Novation/Launchpad/NovationLaunchpadRGBDeviceInfo.cs @@ -1,35 +1,34 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Novation -{ - /// - /// - /// Represents a generic information for a . - /// - public class NovationLaunchpadRGBDeviceInfo : NovationRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Devices.Novation; - internal LedIdMappings LedIdMapping { get; } +/// +/// +/// Represents a generic information for a . +/// +public class NovationLaunchpadRGBDeviceInfo : NovationRGBDeviceInfo +{ + #region Properties & Fields - #endregion + internal LedIdMappings LedMapping { get; } - #region Constructors + #endregion - /// - /// - /// Internal constructor of managed . - /// - /// The represented device model. - /// - /// The of the . - internal NovationLaunchpadRGBDeviceInfo(string model, int deviceId, NovationColorCapabilities colorCapabilities, - LedIdMappings ledIdMapping) - : base(RGBDeviceType.LedMatrix, model, deviceId, colorCapabilities) - { - this.LedIdMapping = ledIdMapping; - } + #region Constructors - #endregion + /// + /// + /// Internal constructor of managed . + /// + /// The represented device model. + /// The id of the device. + /// The of the . + /// A mapping of leds this device is initialized with. + internal NovationLaunchpadRGBDeviceInfo(string model, int deviceId, NovationColorCapabilities colorCapabilities, LedIdMappings ledMapping) + : base(RGBDeviceType.LedMatrix, model, deviceId, colorCapabilities) + { + this.LedMapping = ledMapping; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs index 4e031fe4..9d2d8d22 100644 --- a/RGB.NET.Devices.Novation/NovationDeviceProvider.cs +++ b/RGB.NET.Devices.Novation/NovationDeviceProvider.cs @@ -3,133 +3,69 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Linq; using RGB.NET.Core; using Sanford.Multimedia.Midi; -namespace RGB.NET.Devices.Novation +namespace RGB.NET.Devices.Novation; + +/// +/// +/// Represents a device provider responsible for Novation devices. +/// +public class NovationDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static NovationDeviceProvider? _instance; /// - /// Represents a device provider responsible for Novation devices. + /// Gets the singleton instance. /// - public class NovationDeviceProvider : IRGBDeviceProvider + public static NovationDeviceProvider Instance => _instance ?? new NovationDeviceProvider(); + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + private NovationDeviceProvider() { - #region Properties & Fields - - private static NovationDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static NovationDeviceProvider Instance => _instance ?? new NovationDeviceProvider(); - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess => false; - - /// - public IEnumerable Devices { get; private set; } - - /// - /// The used to trigger the updates for novation devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - private NovationDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(NovationDeviceProvider)}"); - _instance = this; + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(NovationDeviceProvider)}"); + _instance = this; + } - UpdateTrigger = new DeviceUpdateTrigger(); - } + #endregion - #endregion + #region Methods - #region Methods + /// + protected override void InitializeSDK() { } - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) + /// + protected override IEnumerable LoadDevices() + { + for (int index = 0; index < OutputDeviceBase.DeviceCount; index++) { - IsInitialized = false; - - try - { - UpdateTrigger?.Stop(); - - IList devices = new List(); - - if (loadFilter.HasFlag(RGBDeviceType.LedMatrix)) - for (int index = 0; index < OutputDeviceBase.DeviceCount; index++) - { - try - { - MidiOutCaps outCaps = OutputDeviceBase.GetDeviceCapabilities(index); - if (outCaps.name == null) continue; - - NovationDevices? deviceId = (NovationDevices?)Enum.GetValues(typeof(NovationDevices)) - .Cast() - .FirstOrDefault(x => x.GetDeviceId().ToUpperInvariant().Contains(outCaps.name.ToUpperInvariant())); - - if (deviceId == null) continue; - - NovationColorCapabilities colorCapability = deviceId.GetColorCapability(); - if (colorCapability == NovationColorCapabilities.None) continue; - - INovationRGBDevice device = new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo(outCaps.name, index, colorCapability, deviceId.GetLedIdMapping())); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - } - - UpdateTrigger?.Start(); - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) - throw; - return false; - } - - return true; - } + MidiOutCaps outCaps = OutputDeviceBase.GetDeviceCapabilities(index); + if (outCaps.name == null) continue; - /// - public void ResetDevices() - { - foreach (IRGBDevice device in Devices) - { - NovationLaunchpadRGBDevice novationDevice = device as NovationLaunchpadRGBDevice; - novationDevice?.Reset(); - } - } + string deviceName = outCaps.name.ToUpperInvariant(); + NovationDevices? deviceId = (NovationDevices?)Enum.GetValues(typeof(NovationDevices)) + .Cast() + .Where(x => x.GetDeviceId() != null) + .FirstOrDefault(x => deviceName.Contains(x.GetDeviceId()!.ToUpperInvariant())); - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } - } + if (deviceId == null) continue; + + NovationColorCapabilities colorCapability = deviceId.GetColorCapability(); + if (colorCapability == NovationColorCapabilities.None) continue; - #endregion + yield return new NovationLaunchpadRGBDevice(new NovationLaunchpadRGBDeviceInfo(outCaps.name, index, colorCapability, deviceId.GetLedIdMapping()), GetUpdateTrigger()); + } } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/NovationDeviceProviderLoader.cs b/RGB.NET.Devices.Novation/NovationDeviceProviderLoader.cs deleted file mode 100644 index f2fc28d2..00000000 --- a/RGB.NET.Devices.Novation/NovationDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Novation -{ - /// - /// Represents a device provider loaded used to dynamically load novation devices into an application. - /// - public class NovationDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => NovationDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Novation/README.md b/RGB.NET.Devices.Novation/README.md new file mode 100644 index 00000000..f0cabf50 --- /dev/null +++ b/RGB.NET.Devices.Novation/README.md @@ -0,0 +1,11 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for Novation-Devices. + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(NovationDeviceProvider.Instance); +``` + +# Required SDK +This provider does not require an additional SDK. diff --git a/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj b/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj index abd09fa5..12a79191 100644 --- a/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj +++ b/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.Novation Novation-Device-Implementations of RGB.NET Novation-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,37 +35,29 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - - + + - - + + + \ No newline at end of file diff --git a/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj.DotSettings b/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj.DotSettings index b5910cae..a290ae5f 100644 --- a/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj.DotSettings +++ b/RGB.NET.Devices.Novation/RGB.NET.Devices.Novation.csproj.DotSettings @@ -2,4 +2,5 @@ True True True - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Devices.OpenRGB/Abstract/AbstractOpenRGBDevice.cs b/RGB.NET.Devices.OpenRGB/Abstract/AbstractOpenRGBDevice.cs new file mode 100644 index 00000000..78f3f1fb --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/Abstract/AbstractOpenRGBDevice.cs @@ -0,0 +1,24 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.OpenRGB; + +/// +/// +/// Represents a generic OpenRGB Device. +/// +public abstract class AbstractOpenRGBDevice : AbstractRGBDevice, IOpenRGBDevice + where TDeviceInfo : OpenRGBDeviceInfo +{ + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The generic information provided by OpenRGB for this device. + /// The queue used to update this device. + protected AbstractOpenRGBDevice(TDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) + { } + + #endregion +} diff --git a/RGB.NET.Devices.OpenRGB/Abstract/IOpenRGBDevice.cs b/RGB.NET.Devices.OpenRGB/Abstract/IOpenRGBDevice.cs new file mode 100644 index 00000000..7659d948 --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/Abstract/IOpenRGBDevice.cs @@ -0,0 +1,9 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.OpenRGB; + +/// +/// Represents a generic OpenRGB Device. +/// +public interface IOpenRGBDevice : IRGBDevice +{ } diff --git a/RGB.NET.Devices.OpenRGB/Abstract/OpenRGBDeviceInfo.cs b/RGB.NET.Devices.OpenRGB/Abstract/OpenRGBDeviceInfo.cs new file mode 100644 index 00000000..05afff3e --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/Abstract/OpenRGBDeviceInfo.cs @@ -0,0 +1,52 @@ +using RGB.NET.Core; +using OpenRGBDevice = OpenRGB.NET.Models.Device; + +namespace RGB.NET.Devices.OpenRGB; + +/// +/// Represents generic information for an OpenRGB Device +/// +public class OpenRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields + + /// + public RGBDeviceType DeviceType { get; } + + /// + public string DeviceName { get; } + + /// + public string Manufacturer { get; } + + /// + public string Model { get; } + + /// + public object? LayoutMetadata { get; set; } + + /// + /// Gets the OpenRGB device. + /// + public OpenRGBDevice OpenRGBDevice { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of . + /// + /// The OpenRGB device to extract information from. + internal OpenRGBDeviceInfo(OpenRGBDevice openRGBDevice) + { + this.OpenRGBDevice = openRGBDevice; + + DeviceType = Helper.GetRgbNetDeviceType(openRGBDevice.Type); + Manufacturer = Helper.GetVendorName(openRGBDevice); + Model = Helper.GetModelName(openRGBDevice); + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); + } + + #endregion +} diff --git a/RGB.NET.Devices.OpenRGB/Generic/LedMappings.cs b/RGB.NET.Devices.OpenRGB/Generic/LedMappings.cs new file mode 100644 index 00000000..d6deb99f --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/Generic/LedMappings.cs @@ -0,0 +1,145 @@ +using RGB.NET.Core; +using System.Collections.Generic; + +namespace RGB.NET.Devices.OpenRGB; + +internal static class LedMappings +{ + public static readonly Dictionary DEFAULT = new() + { + ["Key: A"] = LedId.Keyboard_A, + ["Key: B"] = LedId.Keyboard_B, + ["Key: C"] = LedId.Keyboard_C, + ["Key: D"] = LedId.Keyboard_D, + ["Key: E"] = LedId.Keyboard_E, + ["Key: F"] = LedId.Keyboard_F, + ["Key: G"] = LedId.Keyboard_G, + ["Key: H"] = LedId.Keyboard_H, + ["Key: I"] = LedId.Keyboard_I, + ["Key: J"] = LedId.Keyboard_J, + ["Key: K"] = LedId.Keyboard_K, + ["Key: L"] = LedId.Keyboard_L, + ["Key: M"] = LedId.Keyboard_M, + ["Key: N"] = LedId.Keyboard_N, + ["Key: O"] = LedId.Keyboard_O, + ["Key: P"] = LedId.Keyboard_P, + ["Key: Q"] = LedId.Keyboard_Q, + ["Key: R"] = LedId.Keyboard_R, + ["Key: S"] = LedId.Keyboard_S, + ["Key: T"] = LedId.Keyboard_T, + ["Key: U"] = LedId.Keyboard_U, + ["Key: V"] = LedId.Keyboard_V, + ["Key: W"] = LedId.Keyboard_W, + ["Key: X"] = LedId.Keyboard_X, + ["Key: Y"] = LedId.Keyboard_Y, + ["Key: Z"] = LedId.Keyboard_Z, + ["Key: 1"] = LedId.Keyboard_1, + ["Key: 2"] = LedId.Keyboard_2, + ["Key: 3"] = LedId.Keyboard_3, + ["Key: 4"] = LedId.Keyboard_4, + ["Key: 5"] = LedId.Keyboard_5, + ["Key: 6"] = LedId.Keyboard_6, + ["Key: 7"] = LedId.Keyboard_7, + ["Key: 8"] = LedId.Keyboard_8, + ["Key: 9"] = LedId.Keyboard_9, + ["Key: 0"] = LedId.Keyboard_0, + ["Key: Enter"] = LedId.Keyboard_Enter, + ["Key: Enter (ISO)"] = LedId.Keyboard_Enter, + ["Key: Escape"] = LedId.Keyboard_Escape, + ["Key: Backspace"] = LedId.Keyboard_Backspace, + ["Key: Tab"] = LedId.Keyboard_Tab, + ["Key: Space"] = LedId.Keyboard_Space, + ["Key: -"] = LedId.Keyboard_MinusAndUnderscore, + ["Key: ="] = LedId.Keyboard_EqualsAndPlus, + ["Key: ["] = LedId.Keyboard_BracketLeft, + ["Key: ]"] = LedId.Keyboard_BracketRight, + ["Key: \\ (ANSI)"] = LedId.Keyboard_Backslash, + ["Key: #"] = LedId.Keyboard_NonUsTilde, + ["Key: ;"] = LedId.Keyboard_SemicolonAndColon, + ["Key: '"] = LedId.Keyboard_ApostropheAndDoubleQuote, + ["Key: `"] = LedId.Keyboard_GraveAccentAndTilde, + ["Key: ,"] = LedId.Keyboard_CommaAndLessThan, + ["Key: ."] = LedId.Keyboard_PeriodAndBiggerThan, + ["Key: /"] = LedId.Keyboard_SlashAndQuestionMark, + ["Key: Caps Lock"] = LedId.Keyboard_CapsLock, + ["Key: F1"] = LedId.Keyboard_F1, + ["Key: F2"] = LedId.Keyboard_F2, + ["Key: F3"] = LedId.Keyboard_F3, + ["Key: F4"] = LedId.Keyboard_F4, + ["Key: F5"] = LedId.Keyboard_F5, + ["Key: F6"] = LedId.Keyboard_F6, + ["Key: F7"] = LedId.Keyboard_F7, + ["Key: F8"] = LedId.Keyboard_F8, + ["Key: F9"] = LedId.Keyboard_F9, + ["Key: F10"] = LedId.Keyboard_F10, + ["Key: F11"] = LedId.Keyboard_F11, + ["Key: F12"] = LedId.Keyboard_F12, + ["Key: Print Screen"] = LedId.Keyboard_PrintScreen, + ["Key: Scroll Lock"] = LedId.Keyboard_ScrollLock, + ["Key: Pause/Break"] = LedId.Keyboard_PauseBreak, + ["Key: Insert"] = LedId.Keyboard_Insert, + ["Key: Home"] = LedId.Keyboard_Home, + ["Key: Page Up"] = LedId.Keyboard_PageUp, + ["Key: Delete"] = LedId.Keyboard_Delete, + ["Key: End"] = LedId.Keyboard_End, + ["Key: Page Down"] = LedId.Keyboard_PageDown, + ["Key: Right Arrow"] = LedId.Keyboard_ArrowRight, + ["Key: Left Arrow"] = LedId.Keyboard_ArrowLeft, + ["Key: Down Arrow"] = LedId.Keyboard_ArrowDown, + ["Key: Up Arrow"] = LedId.Keyboard_ArrowUp, + ["Key: Num Lock"] = LedId.Keyboard_NumLock, + ["Key: Number Pad /"] = LedId.Keyboard_NumSlash, + ["Key: Number Pad *"] = LedId.Keyboard_NumAsterisk, + ["Key: Number Pad -"] = LedId.Keyboard_NumMinus, + ["Key: Number Pad +"] = LedId.Keyboard_NumPlus, + ["Key: Number Pad Enter"] = LedId.Keyboard_NumEnter, + ["Key: Number Pad 1"] = LedId.Keyboard_Num1, + ["Key: Number Pad 2"] = LedId.Keyboard_Num2, + ["Key: Number Pad 3"] = LedId.Keyboard_Num3, + ["Key: Number Pad 4"] = LedId.Keyboard_Num4, + ["Key: Number Pad 5"] = LedId.Keyboard_Num5, + ["Key: Number Pad 6"] = LedId.Keyboard_Num6, + ["Key: Number Pad 7"] = LedId.Keyboard_Num7, + ["Key: Number Pad 8"] = LedId.Keyboard_Num8, + ["Key: Number Pad 9"] = LedId.Keyboard_Num9, + ["Key: Number Pad 0"] = LedId.Keyboard_Num0, + ["Key: Number Pad ."] = LedId.Keyboard_NumPeriodAndDelete, + ["Key: Left Fn"] = LedId.Keyboard_Function, + ["Key: Right Fn"] = LedId.Keyboard_Function, + ["Key: \\ (ISO)"] = LedId.Keyboard_NonUsBackslash, + ["Key: Menu"] = LedId.Keyboard_Application, + ["Key: Left Control"] = LedId.Keyboard_LeftCtrl, + ["Key: Left Shift"] = LedId.Keyboard_LeftShift, + ["Key: Left Alt"] = LedId.Keyboard_LeftAlt, + ["Key: Left Windows"] = LedId.Keyboard_LeftGui, + ["Key: Right Control"] = LedId.Keyboard_RightCtrl, + ["Key: Right Shift"] = LedId.Keyboard_RightShift, + ["Key: Right Alt"] = LedId.Keyboard_RightAlt, + ["Key: Right Windows"] = LedId.Keyboard_RightGui, + ["Key: Media Next"] = LedId.Keyboard_MediaNextTrack, + ["Key: Media Previous"] = LedId.Keyboard_MediaPreviousTrack, + ["Key: Media Stop"] = LedId.Keyboard_MediaStop, + ["Key: Media Pause"] = LedId.Keyboard_MediaPlay, + ["Key: Media Play"] = LedId.Keyboard_MediaPlay, + ["Key: Media Play/Pause"] = LedId.Keyboard_MediaPlay, + ["Key: Media Mute"] = LedId.Keyboard_MediaMute, + ["Logo"] = LedId.Logo, + ["Key: Brightness"] = LedId.Keyboard_Brightness, + ["Key: M1"] = LedId.Keyboard_Macro1, + ["Key: M2"] = LedId.Keyboard_Macro2, + ["Key: M3"] = LedId.Keyboard_Macro3, + ["Key: M4"] = LedId.Keyboard_Macro4, + ["Key: M5"] = LedId.Keyboard_Macro5, + ["Key: G1"] = LedId.Keyboard_Programmable1, + ["Key: G2"] = LedId.Keyboard_Programmable2, + ["Key: G3"] = LedId.Keyboard_Programmable3, + ["Key: G4"] = LedId.Keyboard_Programmable4, + ["Key: G5"] = LedId.Keyboard_Programmable5, + ["Key: G6"] = LedId.Keyboard_Programmable6, + ["Key: G7"] = LedId.Keyboard_Programmable7, + ["Key: G8"] = LedId.Keyboard_Programmable8, + ["Key: G9"] = LedId.Keyboard_Programmable9, + ["Lighting"] = LedId.Keyboard_Brightness, + ["Game Mode"] = LedId.Keyboard_WinLock, + }; +} diff --git a/RGB.NET.Devices.OpenRGB/Generic/OpenRGBGenericDevice.cs b/RGB.NET.Devices.OpenRGB/Generic/OpenRGBGenericDevice.cs new file mode 100644 index 00000000..8f19c5ae --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/Generic/OpenRGBGenericDevice.cs @@ -0,0 +1,83 @@ +using OpenRGB.NET.Enums; +using RGB.NET.Core; + +namespace RGB.NET.Devices.OpenRGB; + +/// +public class OpenRGBGenericDevice : AbstractOpenRGBDevice +{ + #region Constructors + /// + /// Initializes a new instance of the class. + /// + /// Generic information for the device. + /// The queue used to update the device. + public OpenRGBGenericDevice(OpenRGBDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) + { + InitializeLayout(); + } + + #endregion + + #region Methods + + /// + /// Initializes the LEDs of the device based on the data provided by the SDK. + /// + private void InitializeLayout() + { + LedId initial = Helper.GetInitialLedIdForDeviceType(DeviceInfo.DeviceType); + + int y = 0; + Size ledSize = new(19); + int zoneLedIndex = 0; + const int LED_SPACING = 20; + + foreach (global::OpenRGB.NET.Models.Zone? zone in DeviceInfo.OpenRGBDevice.Zones) + { + if (zone.Type == ZoneType.Matrix) + { + for (int row = 0; row < zone.MatrixMap.Height; row++) + { + for (int column = 0; column < zone.MatrixMap.Width; column++) + { + uint index = zone.MatrixMap.Matrix[row, column]; + + //will be max value if the position does not have an associated key + if (index == uint.MaxValue) + continue; + + LedId ledId = LedMappings.DEFAULT.TryGetValue(DeviceInfo.OpenRGBDevice.Leds[zoneLedIndex + index].Name, out LedId id) + ? id + : initial++; + + //HACK: doing this because some different Led Names are mapped to the same LedId + //for example, "Enter" and "ISO Enter". + //this way, at least they'll be controllable as CustomX + while (AddLed(ledId, new Point(LED_SPACING * column, y + (LED_SPACING * row)), ledSize, zoneLedIndex + (int)index) == null) + ledId = initial++; + } + } + y += (int)(zone.MatrixMap.Height * LED_SPACING); + } + else + { + for (int i = 0; i < zone.LedCount; i++) + { + LedId ledId = initial++; + + while (AddLed(ledId, new Point(LED_SPACING * i, y), ledSize, zoneLedIndex + i) == null) + ledId = initial++; + } + } + + //we'll just set each zone in its own row for now, + //with each led for that zone being horizontally distributed + y += LED_SPACING; + zoneLedIndex += (int)zone.LedCount; + } + } + + #endregion +} diff --git a/RGB.NET.Devices.OpenRGB/Generic/OpenRGBUpdateQueue.cs b/RGB.NET.Devices.OpenRGB/Generic/OpenRGBUpdateQueue.cs new file mode 100644 index 00000000..aab78d42 --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/Generic/OpenRGBUpdateQueue.cs @@ -0,0 +1,61 @@ +using OpenRGB.NET; +using RGB.NET.Core; +using System; +using System.Linq; +using OpenRGBColor = OpenRGB.NET.Models.Color; +using OpenRGBDevice = OpenRGB.NET.Models.Device; + +namespace RGB.NET.Devices.OpenRGB; + +/// +/// +/// Represents the update-queue performing updates for OpenRGB devices. +/// +public class OpenRGBUpdateQueue : UpdateQueue +{ + #region Properties & Fields + + private readonly int _deviceid; + + private readonly OpenRGBClient _openRGB; + private readonly OpenRGBDevice _device; + private readonly OpenRGBColor[] _colors; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The index used to identify the device. + /// The OpenRGB client used to send updates to the OpenRGB server. + /// The OpenRGB Device containing device-specific information. + public OpenRGBUpdateQueue(IDeviceUpdateTrigger updateTrigger, int deviceid, OpenRGBClient client, OpenRGBDevice device) + : base(updateTrigger) + { + this._deviceid = deviceid; + this._openRGB = client; + this._device = device; + + _colors = Enumerable.Range(0, _device.Colors.Length) + .Select(_ => new OpenRGBColor()) + .ToArray(); + } + + #endregion + + #region Methods + + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + foreach ((object key, Color color) in dataSet) + _colors[(int)key] = new OpenRGBColor(color.GetR(), color.GetG(), color.GetB()); + + _openRGB.UpdateLeds(_deviceid, _colors); + } + + #endregion +} diff --git a/RGB.NET.Devices.OpenRGB/Helper.cs b/RGB.NET.Devices.OpenRGB/Helper.cs new file mode 100644 index 00000000..639730e2 --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/Helper.cs @@ -0,0 +1,56 @@ +using OpenRGB.NET.Enums; +using RGB.NET.Core; +using OpenRGBDevice = OpenRGB.NET.Models.Device; + +namespace RGB.NET.Devices.OpenRGB; + +internal static class Helper +{ + public static LedId GetInitialLedIdForDeviceType(RGBDeviceType type) + => type switch + { + RGBDeviceType.Mouse => LedId.Mouse1, + RGBDeviceType.Headset => LedId.Headset1, + RGBDeviceType.Mousepad => LedId.Mousepad1, + RGBDeviceType.LedStripe => LedId.LedStripe1, + RGBDeviceType.LedMatrix => LedId.LedMatrix1, + RGBDeviceType.Mainboard => LedId.Mainboard1, + RGBDeviceType.GraphicsCard => LedId.GraphicsCard1, + RGBDeviceType.DRAM => LedId.DRAM1, + RGBDeviceType.HeadsetStand => LedId.HeadsetStand1, + RGBDeviceType.Keypad => LedId.Keypad1, + RGBDeviceType.Fan => LedId.Fan1, + RGBDeviceType.Speaker => LedId.Speaker1, + RGBDeviceType.Cooler => LedId.Cooler1, + RGBDeviceType.Keyboard => LedId.Keyboard_Custom1, + _ => LedId.Custom1 + }; + + public static RGBDeviceType GetRgbNetDeviceType(DeviceType type) + => type switch + { + DeviceType.Motherboard => RGBDeviceType.Mainboard, + DeviceType.Dram => RGBDeviceType.DRAM, + DeviceType.Gpu => RGBDeviceType.GraphicsCard, + DeviceType.Cooler => RGBDeviceType.Cooler, + DeviceType.Ledstrip => RGBDeviceType.LedStripe, + DeviceType.Keyboard => RGBDeviceType.Keyboard, + DeviceType.Mouse => RGBDeviceType.Mouse, + DeviceType.Mousemat => RGBDeviceType.Mousepad, + DeviceType.Headset => RGBDeviceType.Headset, + DeviceType.Speaker => RGBDeviceType.Speaker, + DeviceType.HeadsetStand => RGBDeviceType.HeadsetStand, + _ => RGBDeviceType.Unknown + }; + + public static LedId GetInitialLedIdForDeviceType(DeviceType type) + => GetInitialLedIdForDeviceType(GetRgbNetDeviceType(type)); + + public static string GetVendorName(OpenRGBDevice openRGBDevice) => string.IsNullOrWhiteSpace(openRGBDevice.Vendor) + ? "OpenRGB" + : openRGBDevice.Vendor; + + public static string GetModelName(OpenRGBDevice openRGBDevice) => string.IsNullOrWhiteSpace(openRGBDevice.Vendor) + ? openRGBDevice.Name + : openRGBDevice.Name.Replace(openRGBDevice.Vendor, "").Trim(); +} diff --git a/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs b/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs new file mode 100644 index 00000000..b912cded --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/OpenRGBDeviceProvider.cs @@ -0,0 +1,146 @@ +using OpenRGB.NET; +using OpenRGB.NET.Models; +using RGB.NET.Core; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace RGB.NET.Devices.OpenRGB; + +/// +/// +/// Represents a device provider responsible for OpenRGB devices. +/// +public class OpenRGBDeviceProvider : AbstractRGBDeviceProvider +{ + #region Properties & Fields + + private readonly List _clients = new(); + + private static OpenRGBDeviceProvider? _instance; + + /// + /// Gets the singleton instance. + /// + public static OpenRGBDeviceProvider Instance => _instance ?? new OpenRGBDeviceProvider(); + + /// + /// Gets a list of all defined device-definitions. + /// + public List DeviceDefinitions { get; } = new(); + + /// + /// Indicates whether all devices will be added, or just the ones with a 'Direct' mode. Defaults to false. + /// + public bool ForceAddAllDevices { get; set; } = false; + + /// + /// Defines which device types will be separated by zones. Defaults to | . + /// + public RGBDeviceType PerZoneDeviceFlag { get; } = RGBDeviceType.LedStripe | RGBDeviceType.Mainboard | RGBDeviceType.Speaker; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public OpenRGBDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(OpenRGBDeviceProvider)}"); + _instance = this; + } + + #endregion + + #region Methods + + /// + /// Adds the specified to this device-provider. + /// + /// The to add. + // ReSharper disable once UnusedMember.Global + public void AddDeviceDefinition(OpenRGBServerDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); + + /// + protected override void InitializeSDK() + { + foreach (OpenRGBServerDefinition? deviceDefinition in DeviceDefinitions) + { + try + { + OpenRGBClient openRgb = new(ip: deviceDefinition.Ip, port: deviceDefinition.Port, name: deviceDefinition.ClientName, autoconnect: true); + _clients.Add(openRgb); + deviceDefinition.Connected = true; + } + catch (Exception e) + { + deviceDefinition.Connected = false; + deviceDefinition.LastError = e.Message; + Throw(e); + } + } + } + + /// + protected override IEnumerable LoadDevices() + { + foreach (OpenRGBClient? openRgb in _clients) + { + int deviceCount = openRgb.GetControllerCount(); + + for (int i = 0; i < deviceCount; i++) + { + Device? device = openRgb.GetControllerData(i); + + int directModeIndex = Array.FindIndex(device.Modes, d => d.Name == "Direct"); + if (directModeIndex != -1) + { + //set the device to direct mode if it has it + openRgb.SetMode(i, directModeIndex); + } + else if (!ForceAddAllDevices) + { + //if direct mode does not exist + //and if we're not forcing, continue to the next device. + continue; + } + + OpenRGBUpdateQueue? updateQueue = new(GetUpdateTrigger(), i, openRgb, device); + + if (PerZoneDeviceFlag.HasFlag(Helper.GetRgbNetDeviceType(device.Type))) + { + int totalLedCount = 0; + + foreach (Zone zone in device.Zones) + if (zone.LedCount > 0) + { + yield return new OpenRGBZoneDevice(new OpenRGBDeviceInfo(device), totalLedCount, zone, updateQueue); + totalLedCount += (int)zone.LedCount; + } + } + else + yield return new OpenRGBGenericDevice(new OpenRGBDeviceInfo(device), updateQueue); + } + } + } + + /// + public override void Dispose() + { + base.Dispose(); + + foreach (OpenRGBClient client in _clients) + { + try { client.Dispose(); } + catch { /* at least we tried */ } + } + + _clients.Clear(); + DeviceDefinitions.Clear(); + Devices = Enumerable.Empty(); + } + #endregion +} diff --git a/RGB.NET.Devices.OpenRGB/OpenRGBServerDefinition.cs b/RGB.NET.Devices.OpenRGB/OpenRGBServerDefinition.cs new file mode 100644 index 00000000..860b6bc3 --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/OpenRGBServerDefinition.cs @@ -0,0 +1,32 @@ +namespace RGB.NET.Devices.OpenRGB; + +/// +/// Represents a definition of an OpenRGB server. +/// +public class OpenRGBServerDefinition +{ + /// + /// The name of the client that will appear in the OpenRGB interface. + /// + public string? ClientName { get; set; } = "RGB.NET"; + + /// + /// The ip address of the server. + /// + public string? Ip { get; set; } = "127.0.0.1"; + + /// + /// The port of the server. + /// + public int Port { get; set; } = 6742; + + /// + /// Whether the provider is connected to this server definition or not. + /// + public bool Connected { get; set; } + + /// + /// The error that occurred when connecting, if this failed. + /// + public string? LastError { get; set; } +} \ No newline at end of file diff --git a/RGB.NET.Devices.OpenRGB/PerZone/OpenRGBZoneDevice.cs b/RGB.NET.Devices.OpenRGB/PerZone/OpenRGBZoneDevice.cs new file mode 100644 index 00000000..42ab4330 --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/PerZone/OpenRGBZoneDevice.cs @@ -0,0 +1,79 @@ +using OpenRGB.NET.Enums; +using OpenRGB.NET.Models; +using RGB.NET.Core; + +namespace RGB.NET.Devices.OpenRGB; + +/// +public class OpenRGBZoneDevice : AbstractOpenRGBDevice +{ + #region Properties & Fields + + private readonly int _initialLed; + private readonly Zone _zone; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The information provided by OpenRGB + /// The ledId of the first led in the device that belongs to this zone. + /// The Zone information provided by OpenRGB. + /// The queue used to update this zone. + public OpenRGBZoneDevice(OpenRGBDeviceInfo info, int initialLed, Zone zone, IUpdateQueue updateQueue) + : base(info, updateQueue) + { + _initialLed = initialLed; + _zone = zone; + + InitializeLayout(); + } + + #endregion + + #region Methods + + private void InitializeLayout() + { + Size ledSize = new(19); + const int LED_SPACING = 20; + LedId initialId = Helper.GetInitialLedIdForDeviceType(DeviceInfo.DeviceType) + _initialLed; + + if (_zone.Type == ZoneType.Matrix) + { + for (int row = 0; row < _zone.MatrixMap.Height; row++) + { + for (int column = 0; column < _zone.MatrixMap.Width; column++) + { + uint index = _zone.MatrixMap.Matrix[row, column]; + + //will be max value if the position does not have an associated key + if (index == uint.MaxValue) + continue; + + LedId ledId = LedMappings.DEFAULT.TryGetValue(DeviceInfo.OpenRGBDevice.Leds[_initialLed + index].Name, out LedId id) + ? id + : initialId++; + + while (AddLed(ledId, new Point(LED_SPACING * column, LED_SPACING * row), ledSize, _initialLed + (int)index) == null) + ledId = initialId++; + } + } + } + else + { + for (int i = 0; i < _zone.LedCount; i++) + { + LedId ledId = initialId++; + + while (AddLed(ledId, new Point(LED_SPACING * i, 0), ledSize, _initialLed + i) == null) + ledId = initialId++; + } + } + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.OpenRGB/README.md b/RGB.NET.Devices.OpenRGB/README.md new file mode 100644 index 00000000..185910f3 --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/README.md @@ -0,0 +1,16 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for E1.31 DMX-Devices. + +## Usage +This provider does not load anything by default and requires additional configuration to work. + +```csharp +// Add as many OpenRGB-instances as you like +OpenRGBDeviceProvider.Instance.AddDeviceDefinition(new OpenRGBServerDefinition()); + +surface.Attach(OpenRGBDeviceProvider.Instance.Devices); +``` + +You can also configure additional things like IP and Port in the ServerDefinition. + +# Required SDK +This provider does not require an additional SDK. diff --git a/RGB.NET.Devices.OpenRGB/RGB.NET.Devices.OpenRGB.csproj b/RGB.NET.Devices.OpenRGB/RGB.NET.Devices.OpenRGB.csproj new file mode 100644 index 00000000..9fd3eec9 --- /dev/null +++ b/RGB.NET.Devices.OpenRGB/RGB.NET.Devices.OpenRGB.csproj @@ -0,0 +1,67 @@ + + + net7.0;net6.0;net5.0 + latest + enable + + diogotr7 + Wyrez + en-US + en-US + RGB.NET.Devices.OpenRGB + RGB.NET.Devices.OpenRGB + RGB.NET.Devices.OpenRGB + RGB.NET.Devices.OpenRGB + RGB.NET.Devices.OpenRGB + OpenRGB-Device-Implementations of RGB.NET + OpenRGB-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md + https://github.com/DarthAffe/RGB.NET + LGPL-2.1-only + Github + https://github.com/DarthAffe/RGB.NET + True + + + + 0.0.1 + 0.0.1 + 0.0.1 + + ..\bin\ + true + True + True + portable + snupkg + + + + $(DefineConstants);TRACE;DEBUG + true + false + + + + true + $(NoWarn);CS1591;CS1572;CS1573 + $(DefineConstants);RELEASE + + + + + + + + + + + + + + + + diff --git a/RGB.NET.Brushes/RGB.NET.Brushes.csproj.DotSettings b/RGB.NET.Devices.OpenRGB/RGB.NET.Devices.OpenRGB.csproj.DotSettings similarity index 59% rename from RGB.NET.Brushes/RGB.NET.Brushes.csproj.DotSettings rename to RGB.NET.Devices.OpenRGB/RGB.NET.Devices.OpenRGB.csproj.DotSettings index c25ceffb..f79e29d7 100644 --- a/RGB.NET.Brushes/RGB.NET.Brushes.csproj.DotSettings +++ b/RGB.NET.Devices.OpenRGB/RGB.NET.Devices.OpenRGB.csproj.DotSettings @@ -1,3 +1,4 @@  - True - True \ No newline at end of file + True + True + True \ No newline at end of file diff --git a/RGB.NET.Devices.PicoPi/Enum/UpdateMode.cs b/RGB.NET.Devices.PicoPi/Enum/UpdateMode.cs new file mode 100644 index 00000000..2a617713 --- /dev/null +++ b/RGB.NET.Devices.PicoPi/Enum/UpdateMode.cs @@ -0,0 +1,14 @@ +// ReSharper disable InconsistentNaming +#pragma warning disable 1591 + +namespace RGB.NET.Devices.PicoPi.Enum; + +/// +/// Contains a list of possible ways of communication with the device. +/// +public enum UpdateMode +{ + Auto = 0x00, + HID = 0x01, + BULK = 0x02, +} \ No newline at end of file diff --git a/RGB.NET.Devices.PicoPi/PicoPi/LedMappings.cs b/RGB.NET.Devices.PicoPi/PicoPi/LedMappings.cs new file mode 100644 index 00000000..85c6c0b4 --- /dev/null +++ b/RGB.NET.Devices.PicoPi/PicoPi/LedMappings.cs @@ -0,0 +1,28 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.PicoPi; + +/// +/// Contains mappings for to the buffer-offset. +/// +public static class LedMappings +{ + #region Properties & Fields + + /// + /// Gets the defautlt offset-mapping. + /// + public static LedMapping StripeMapping = new(); + + #endregion + + #region Constructors + + static LedMappings() + { + for (int i = 0; i < 255; i++) + StripeMapping.Add(LedId.LedStripe1 + i, i); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.PicoPi/PicoPi/PicoPiBulkUpdateQueue.cs b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiBulkUpdateQueue.cs new file mode 100644 index 00000000..fa328933 --- /dev/null +++ b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiBulkUpdateQueue.cs @@ -0,0 +1,66 @@ +using System; +using RGB.NET.Core; + +namespace RGB.NET.Devices.PicoPi; + +/// +/// +/// Represents the update-queue performing updates for Pico-Pi bulk-devices. +/// +/// +/// Using this requires the libusb driver to be installed! +/// +public class PicoPiBulkUpdateQueue : UpdateQueue +{ + #region Properties & Fields + + private readonly PicoPiSDK _sdk; + private readonly int _channel; + + private readonly byte[] _dataBuffer; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The sdk used to access the device. + /// The channel to update. + /// The maximum amount of leds to update. + public PicoPiBulkUpdateQueue(IDeviceUpdateTrigger updateTrigger, PicoPiSDK sdk, int channel, int ledCount) + : base(updateTrigger) + { + this._sdk = sdk; + this._channel = channel; + + _dataBuffer = new byte[ledCount * 3]; + } + + #endregion + + #region Methods + + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + Span buffer = _dataBuffer; + foreach ((object key, Color color) in dataSet) + { + int index = key as int? ?? -1; + if (index < 0) continue; + + (byte _, byte r, byte g, byte b) = color.GetRGBBytes(); + int offset = index * 3; + buffer[offset] = r; + buffer[offset + 1] = g; + buffer[offset + 2] = b; + } + + _sdk.SendBulkUpdate(buffer, _channel); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.PicoPi/PicoPi/PicoPiHIDUpdateQueue.cs b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiHIDUpdateQueue.cs new file mode 100644 index 00000000..8ee06a23 --- /dev/null +++ b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiHIDUpdateQueue.cs @@ -0,0 +1,63 @@ +using System; +using RGB.NET.Core; + +namespace RGB.NET.Devices.PicoPi; + +/// +/// +/// Represents the update-queue performing updates for Pico-Pi HID-devices. +/// +public class PicoPiHIDUpdateQueue : UpdateQueue +{ + #region Properties & Fields + + private readonly PicoPiSDK _sdk; + private readonly int _channel; + + private readonly byte[] _dataBuffer; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The sdk used to access the device. + /// The channel to update. + /// The maximum amount of leds to update. + public PicoPiHIDUpdateQueue(IDeviceUpdateTrigger updateTrigger, PicoPiSDK sdk, int channel, int ledCount) + : base(updateTrigger) + { + this._sdk = sdk; + this._channel = channel; + + _dataBuffer = new byte[ledCount * 3]; + } + + #endregion + + #region Methods + + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + Span buffer = _dataBuffer; + foreach ((object key, Color color) in dataSet) + { + int index = key as int? ?? -1; + if (index < 0) continue; + + (byte _, byte r, byte g, byte b) = color.GetRGBBytes(); + int offset = index * 3; + buffer[offset] = r; + buffer[offset + 1] = g; + buffer[offset + 2] = b; + } + + _sdk.SendHidUpdate(buffer, _channel); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.PicoPi/PicoPi/PicoPiRGBDevice.cs b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiRGBDevice.cs new file mode 100644 index 00000000..486842d6 --- /dev/null +++ b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiRGBDevice.cs @@ -0,0 +1,46 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.PicoPi; + +/// +/// +/// Represents a device based on an Raspberry Pi Pico. +/// +public class PicoPiRGBDevice : AbstractRGBDevice +{ + #region Properties & Fields + + private readonly LedMapping _ledMapping; + + #endregion + + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The device info of this device. + /// The queue used to update this device. + /// A mapping of leds this device is initialized with. + public PicoPiRGBDevice(PicoPiRGBDeviceInfo deviceInfo, IUpdateQueue updateQueue, LedMapping ledMapping) + : base(deviceInfo, updateQueue) + { + this._ledMapping = ledMapping; + } + + #endregion + + #region Methods + + internal void Initialize() + { + for (int i = 0; i < DeviceInfo.LedCount; i++) + AddLed(_ledMapping[i], new Point(i * 10, 0), new Size(10, 10), i); + } + + /// + protected override object GetLedCustomData(LedId ledId) => _ledMapping.TryGetValue(ledId, out int index) ? index : -1; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.PicoPi/PicoPi/PicoPiRGBDeviceInfo.cs b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiRGBDeviceInfo.cs new file mode 100644 index 00000000..ffe8e71a --- /dev/null +++ b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiRGBDeviceInfo.cs @@ -0,0 +1,64 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.PicoPi; + +/// +/// Represents a generic information for a . +/// +public class PicoPiRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields + + /// + public RGBDeviceType DeviceType { get; } + + /// + public string DeviceName { get; } + + /// + public string Manufacturer => "RGB.NET"; + + /// + public string Model { get; } + + /// + public object? LayoutMetadata { get; set; } + + /// + /// Gets the Id of the device. + /// + public string Id { get; } + + /// + /// Gets the version of the device firmware. + /// + public int Version { get; } + + /// + /// Gets the channel this device is using. + /// + public int Channel { get; } + + /// + /// Gets the amount of LEDs on this device. + /// + public int LedCount { get; } + + #endregion + + #region Constructors + + internal PicoPiRGBDeviceInfo(RGBDeviceType deviceType, string model, string id, int version, int channel, int ledCount) + { + this.DeviceType = deviceType; + this.Model = model; + this.Id = id; + this.Version = version; + this.Channel = channel; + this.LedCount = ledCount; + + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, $"{Model} {id} (Channel {channel})"); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.PicoPi/PicoPi/PicoPiSDK.cs b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiSDK.cs new file mode 100644 index 00000000..a47916cd --- /dev/null +++ b/RGB.NET.Devices.PicoPi/PicoPi/PicoPiSDK.cs @@ -0,0 +1,311 @@ +// ReSharper disable MemberCanBePrivate.Global +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using HidSharp; +using LibUsbDotNet.LibUsb; +using LibUsbDotNet.Main; +using RGB.NET.Core; + +namespace RGB.NET.Devices.PicoPi; + +/// +/// Represents a SDK to access devices based on a Raspberry Pi Pico. +/// +public class PicoPiSDK : IDisposable +{ + #region Constants + + /// + /// The vendor id used by the pico-pi firmware. + /// Registered at https://pid.codes/1209/2812/ + /// + public const int VENDOR_ID = 0x1209; + + /// + /// The product id used by the pico-pi firmware. + /// Registered at https://pid.codes/1209/2812/ + /// + public const int HID_BULK_CONTROLLER_PID = 0x2812; + + private const byte COMMAND_CHANNEL_COUNT = 0x01; + private const byte COMMAND_LEDCOUNTS = 0x0A; + private const byte COMMAND_PINS = 0x0B; + private const byte COMMAND_ID = 0x0E; + private const byte COMMAND_VERSION = 0x0F; + private const byte COMMAND_UPDATE = 0x01; + private const byte COMMAND_UPDATE_BULK = 0x02; + + public const int HID_OFFSET_MULTIPLIER = 60; + + #endregion + + #region Properties & Fields + + private readonly HidDevice _hidDevice; + private readonly HidStream _hidStream; + + private UsbContext? _usbContext; + private IUsbDevice? _bulkDevice; + private UsbEndpointWriter? _bulkWriter; + + private readonly byte[] _hidSendBuffer; + private readonly byte[] _bulkSendBuffer; + + private int _bulkTransferLength; + + /// + /// Gets if updates via the Bulk-Enbpoint are possible. + /// + public bool IsBulkSupported { get; private set; } + + /// + /// Gets the Id of the device. + /// + public string Id { get; } + + /// + /// Gets the version of the device firmware. + /// + public int Version { get; } + + /// + /// Gets a collection of channels, led counts and pins that are available on this device. + /// + public IReadOnlyList<(int channel, int ledCount, int pin)> Channels { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The underlying hid device. + public PicoPiSDK(HidDevice device) + { + this._hidDevice = device; + + _hidSendBuffer = new byte[_hidDevice.GetMaxOutputReportLength() - 1]; + + _hidStream = _hidDevice.Open(); + LoadBulkDevice(); + + Id = GetId(); + Version = GetVersion(); + Channels = new ReadOnlyCollection<(int channel, int ledCount, int pin)>(GetChannels().ToList()); + + _bulkSendBuffer = new byte[(Channels.Sum(c => c.ledCount + 1) * 3) + 5]; + } + + #endregion + + #region Methods + + /// + /// Configures the amount of leds to update on the specified channels. + /// + /// This is a configuration function. The value is persistent on the device. + /// The values to set on the device. + public void SetLedCounts(params (int channel, int ledCount)[] ledCounts) + { + byte[] data = new byte[Channels.Count + 2]; + data[1] = COMMAND_LEDCOUNTS; + foreach ((int channel, int ledCount, _) in Channels) + data[channel + 1] = (byte)ledCount; + + foreach ((int channel, int ledCount) in ledCounts) + data[channel + 1] = (byte)ledCount; + + SendHID(data); + } + + /// + /// Configures the pins used by the specified channels. + /// + /// This is a configuration function. The value is persistent on the device. + /// T values to set on the device. + public void SetPins(params (int channel, int pin)[] pins) + { + byte[] data = new byte[Channels.Count + 2]; + data[1] = COMMAND_PINS; + foreach ((int channel, _, int pin) in Channels) + data[channel + 1] = (byte)pin; + + foreach ((int channel, int pin) in pins) + data[channel + 1] = (byte)pin; + + SendHID(data); + } + + private void LoadBulkDevice() + { + try + { + _usbContext = new UsbContext(); + // DarthAffe 24.04.2021: Not using .Find as it's not returning the device :( + IEnumerable devices = _usbContext.List().Where(d => (d.VendorId == _hidDevice.VendorID) && (d.ProductId == _hidDevice.ProductID)); + foreach (IUsbDevice device in devices) + { + try + { + device.Open(); + if (device.Info.SerialNumber == _hidDevice.GetSerialNumber()) + { + _bulkDevice = device; + break; + } + device.Dispose(); + } + catch { /**/ } + } + + if (_bulkDevice != null) + { + _bulkDevice.ClaimInterface(1); + _bulkWriter = _bulkDevice.OpenEndpointWriter(WriteEndpointID.Ep02, EndpointType.Bulk); + + IsBulkSupported = true; + } + } + catch + { + _bulkWriter = null; + try { _bulkDevice?.Dispose(); } catch { /**/ } + try { _usbContext?.Dispose(); } catch { /**/ } + _bulkDevice = null; + } + } + + private string GetId() + { + SendHID(0x00, COMMAND_ID); + return ConversionHelper.ToHex(Read().Skip(1).Take(8).ToArray()); + } + + private int GetVersion() + { + SendHID(0x00, COMMAND_VERSION); + return Read()[1]; + } + + private IEnumerable<(int channel, int ledCount, int pin)> GetChannels() + { + SendHID(0x00, COMMAND_CHANNEL_COUNT); + int channelCount = Read()[1]; + + for (int i = 1; i <= channelCount; i++) + { + SendHID(0x00, (byte)((i << 4) | COMMAND_LEDCOUNTS)); + int ledCount = Read()[1]; + + SendHID(0x00, (byte)((i << 4) | COMMAND_PINS)); + int pin = Read()[1]; + + yield return (i, ledCount, pin); + } + } + + /// + /// Sends a update to the device using the HID-endpoint and fragments the data if needed. + /// + /// The data to send. + /// The channel to update. + public void SendHidUpdate(in Span buffer, int channel) + { + int chunks = buffer.Length / HID_OFFSET_MULTIPLIER; + if ((chunks * HID_OFFSET_MULTIPLIER) < buffer.Length) chunks++; + for (int i = 0; i < chunks; i++) + { + int offset = i * HID_OFFSET_MULTIPLIER; + int length = Math.Min(buffer.Length - offset, HID_OFFSET_MULTIPLIER); + bool update = i == (chunks - 1); + SendHidUpdate(buffer.Slice(offset, length), channel, i, update); + } + } + + /// + /// Sends a update to the device using the HID-endpoint. + /// + /// The data packet to send. + /// The channel to update. + /// The chunk id of the packet. (Required if packets are fragmented.) + /// A value indicating if the device should update directly after receiving this packet. (If packets are fragmented this should only be true for the last chunk.) + public void SendHidUpdate(in Span data, int channel, int chunk, bool update) + { + if (data.Length == 0) return; + + Span sendBuffer = _hidSendBuffer; + sendBuffer[0] = 0x00; + sendBuffer[1] = (byte)((channel << 4) | COMMAND_UPDATE); + sendBuffer[2] = update ? (byte)1 : (byte)0; + sendBuffer[3] = (byte)chunk; + data.CopyTo(sendBuffer.Slice(4, data.Length)); + SendHID(_hidSendBuffer); + } + + /// + /// Sends a update to the device using the bulk-endpoint. + /// + /// + /// Silently fails if not bulk-updates are supported. (Check ) + /// + /// The data packet to send. + /// The channel to update. + public void SendBulkUpdate(in Span data, int channel) + { + if ((data.Length == 0) || !IsBulkSupported) return; + + Span sendBuffer = new Span(_bulkSendBuffer)[2..]; + int payloadSize = data.Length; + + sendBuffer[_bulkTransferLength++] = (byte)((channel << 4) | COMMAND_UPDATE_BULK); + sendBuffer[_bulkTransferLength++] = (byte)((payloadSize >> 8) & 0xFF); + sendBuffer[_bulkTransferLength++] = (byte)(payloadSize & 0xFF); + data.CopyTo(sendBuffer.Slice(_bulkTransferLength, payloadSize)); + _bulkTransferLength += payloadSize; + } + + /// + /// Flushing the bulk endpoint, causing the device to update. + /// + public void FlushBulk() + { + if (_bulkTransferLength == 0) return; + + _bulkSendBuffer[0] = (byte)((_bulkTransferLength >> 8) & 0xFF); + _bulkSendBuffer[1] = (byte)(_bulkTransferLength & 0xFF); + SendBulk(_bulkSendBuffer, _bulkTransferLength + 2); + + _bulkTransferLength = 0; + } + + /// + /// Resets all leds to black. + /// + public void Reset() + { + foreach ((int channel, int ledCount, _) in Channels) + SendHidUpdate(new byte[ledCount * 3], channel); + } + + private void SendHID(params byte[] data) => _hidStream.Write(data); + private void SendBulk(byte[] data, int count) => _bulkWriter!.Write(data, 0, count, 1000, out int _); + + private byte[] Read() => _hidStream.Read(); + + /// + public void Dispose() + { + Reset(); + + _hidStream.Dispose(); + _bulkDevice?.Dispose(); + _usbContext?.Dispose(); + + GC.SuppressFinalize(this); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.PicoPi/PicoPiDeviceProvider.cs b/RGB.NET.Devices.PicoPi/PicoPiDeviceProvider.cs new file mode 100644 index 00000000..bce7e9c7 --- /dev/null +++ b/RGB.NET.Devices.PicoPi/PicoPiDeviceProvider.cs @@ -0,0 +1,130 @@ +// ReSharper disable MemberCanBePrivate.Global + +using System; +using System.Collections.Generic; +using System.Linq; +using HidSharp; +using RGB.NET.Core; +using RGB.NET.Devices.PicoPi.Enum; +using RGB.NET.HID; + +namespace RGB.NET.Devices.PicoPi; + +/// +/// +/// Represents a device provider responsible for PicoPi-devices. +/// +// ReSharper disable once InconsistentNaming +public class PicoPiDeviceProvider : AbstractRGBDeviceProvider +{ + #region Constants + + private const int AUTO_UPDATE_MODE_CHUNK_THRESHOLD = 2; + + #endregion + + #region Properties & Fields + + private static PicoPiDeviceProvider? _instance; + /// + /// Gets the singleton instance. + /// + public static PicoPiDeviceProvider Instance => _instance ?? new PicoPiDeviceProvider(); + + /// + /// Gets the HID-definitions for PicoPi-devices. + /// + public static HIDLoader DeviceDefinitions { get; } = new(PicoPiSDK.VENDOR_ID) + { + { PicoPiSDK.HID_BULK_CONTROLLER_PID, RGBDeviceType.LedStripe, "WS2812B-Controller", LedMappings.StripeMapping, 0 }, + }; + + private readonly List _sdks = new(); + + /// + /// Gets or sets the endpoint used to update devices. (default ). + /// If auto is set it automatically is using bulk-updates for devies with more than 40 LEDs if supported. Else HID is used. + /// + public UpdateMode UpdateMode { get; set; } = UpdateMode.Auto; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public PicoPiDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(PicoPiDeviceProvider)}"); + _instance = this; + } + + #endregion + + #region Methods + + /// + protected override void InitializeSDK() { } + + /// + protected override IEnumerable GetLoadedDevices(RGBDeviceType loadFilter) + { + DeviceDefinitions.LoadFilter = loadFilter; + + return base.GetLoadedDevices(loadFilter); + } + + /// + protected override IEnumerable LoadDevices() + { + IEnumerable<(HIDDeviceDefinition definition, HidDevice device)> devices = DeviceDefinitions.GetConnectedDevices(); + foreach ((HIDDeviceDefinition definition, HidDevice device) in devices) + { + PicoPiSDK sdk = new(device); + _sdks.Add(sdk); + IDeviceUpdateTrigger updateTrigger = GetUpdateTrigger(sdk.Id.GetHashCode()); + foreach ((int channel, int ledCount, _) in sdk.Channels.Where(c => c.ledCount > 0)) + { + PicoPiRGBDevice picoPiDevice = new(new PicoPiRGBDeviceInfo(definition.DeviceType, definition.Name, sdk.Id, sdk.Version, channel, ledCount), GetUpdateQueue(updateTrigger, sdk, channel, ledCount), definition.LedMapping); + picoPiDevice.Initialize(); + yield return picoPiDevice; + } + + if (sdk.IsBulkSupported) + updateTrigger.Update += (_, _) => sdk.FlushBulk(); + } + } + + private IUpdateQueue GetUpdateQueue(IDeviceUpdateTrigger updateTrigger, PicoPiSDK sdk, int channel, int ledCount) + { + switch (UpdateMode) + { + case UpdateMode.HID: + return new PicoPiHIDUpdateQueue(updateTrigger, sdk, channel, ledCount); + + case UpdateMode.BULK: + if (!sdk.IsBulkSupported) throw new NotSupportedException("Bulk updates aren't supported for this device. Make sure the firmware is built with bulk support and the libusb driver is installed."); + return new PicoPiBulkUpdateQueue(updateTrigger, sdk, channel, ledCount); + + case UpdateMode.Auto: + if (!sdk.IsBulkSupported || (sdk.Channels.Sum(c => (int)Math.Ceiling(c.ledCount / 20.0)) <= AUTO_UPDATE_MODE_CHUNK_THRESHOLD)) return new PicoPiHIDUpdateQueue(updateTrigger, sdk, channel, ledCount); + return new PicoPiBulkUpdateQueue(updateTrigger, sdk, channel, ledCount); + + default: throw new IndexOutOfRangeException($"Update mode {UpdateMode} is not supported."); + } + } + + /// + protected override void Reset() + { + base.Reset(); + + foreach (PicoPiSDK sdk in _sdks) + sdk.Dispose(); + _sdks.Clear(); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Groups/RGB.NET.Groups.csproj b/RGB.NET.Devices.PicoPi/RGB.NET.Devices.PicoPi.csproj similarity index 52% rename from RGB.NET.Groups/RGB.NET.Groups.csproj rename to RGB.NET.Devices.PicoPi/RGB.NET.Devices.PicoPi.csproj index 59c8c356..db64c4a1 100644 --- a/RGB.NET.Groups/RGB.NET.Groups.csproj +++ b/RGB.NET.Devices.PicoPi/RGB.NET.Devices.PicoPi.csproj @@ -1,24 +1,26 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez en-US en-US - RGB.NET.Groups - RGB.NET.Groups - RGB.NET.Groups - RGB.NET.Groups - RGB.NET.Groups - Group-Presets of RGB.NET - Group-Presets of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + RGB.NET.Devices.PicoPi + RGB.NET.Devices.PicoPi + RGB.NET.Devices.PicoPi + RGB.NET.Devices.PicoPi + RGB.NET.Devices.PicoPi + PicoPi-Device-Implementations of RGB.NET + PicoPi-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,36 +35,33 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + + + + + - - + + + \ No newline at end of file diff --git a/RGB.NET.Groups/RGB.NET.Groups.csproj.DotSettings b/RGB.NET.Devices.PicoPi/RGB.NET.Devices.PicoPi.csproj.DotSettings similarity index 60% rename from RGB.NET.Groups/RGB.NET.Groups.csproj.DotSettings rename to RGB.NET.Devices.PicoPi/RGB.NET.Devices.PicoPi.csproj.DotSettings index b2485000..22c2a5dd 100644 --- a/RGB.NET.Groups/RGB.NET.Groups.csproj.DotSettings +++ b/RGB.NET.Devices.PicoPi/RGB.NET.Devices.PicoPi.csproj.DotSettings @@ -1,3 +1,3 @@  - True - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Devices.PicoPi/ReadMe.md b/RGB.NET.Devices.PicoPi/ReadMe.md new file mode 100644 index 00000000..c0d3b49b --- /dev/null +++ b/RGB.NET.Devices.PicoPi/ReadMe.md @@ -0,0 +1,13 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for RGB.NET-Devices based on the Raspi Pi Pico. + +To create your own Raspberry PI Pico based controller check the RGB.NET Firmware at [https://github.com/DarthAffe/RGB.NET-PicoPi](https://github.com/DarthAffe/RGB.NET-PicoPi) + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(PicoPiDeviceProvider.Instance); +``` + +# Required SDK +This provider does not require an additional SDK. diff --git a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs index 853b2227..1dd5c70a 100644 --- a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs +++ b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDevice.cs @@ -4,46 +4,40 @@ using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// +/// Represents a razer chroma link. +/// +public class RazerChromaLinkRGBDevice : RazerRGBDevice, IUnknownDevice { - /// + #region Constructors + + /// /// - /// Represents a razer chroma link. + /// Initializes a new instance of the class. /// - public class RazerChromaLinkRGBDevice : RazerRGBDevice, ILedStripe + /// The specific information provided by CUE for the chroma link. + /// The update trigger used to update this device. + internal RazerChromaLinkRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerChromaLinkUpdateQueue(updateTrigger)) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the chroma link. - internal RazerChromaLinkRGBDevice(RazerChromaLinkRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods + InitializeLayout(); + } - /// - protected override void InitializeLayout() - { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\ChromaLink", $"{model}.xml"), null); + #endregion - if (LedMapping.Count == 0) - for (int i = 0; i < _Defines.CHROMALINK_MAX_LEDS; i++) - InitializeLed(LedId.Custom1 + i, new Rectangle(i * 11, 0, 10, 10)); - } + #region Methods - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Custom1; + private void InitializeLayout() + { + for (int i = 0; i < _Defines.CHROMALINK_MAX_LEDS; i++) + AddLed(LedId.Custom1 + i, new Point(i * 10, 0), new Size(10, 10)); + } - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerChromaLinkUpdateQueue(updateTrigger, DeviceInfo.DeviceId); + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Custom1; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDeviceInfo.cs b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDeviceInfo.cs deleted file mode 100644 index fb9c3c4b..00000000 --- a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkRGBDeviceInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Razer -{ - /// - /// - /// Represents a generic information for a . - /// - public class RazerChromaLinkRGBDeviceInfo : RazerRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The Id of the . - /// The model of the . - internal RazerChromaLinkRGBDeviceInfo(Guid deviceId, string model) - : base(deviceId, RGBDeviceType.LedStripe, model) - { } - - #endregion - } -} diff --git a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs index a9ade2b3..42755b95 100644 --- a/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/ChromaLink/RazerChromaLinkUpdateQueue.cs @@ -1,50 +1,48 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// Represents the update-queue performing updates for razer chroma-link devices. +/// +public class RazerChromaLinkUpdateQueue : RazerUpdateQueue { + #region Constructors + /// - /// Represents the update-queue performing updates for razer chroma-link devices. + /// Initializes a new instance of the class. /// - public class RazerChromaLinkUpdateQueue : RazerUpdateQueue - { - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used to update this queue. - /// The id of the device updated by this queue. - public RazerChromaLinkUpdateQueue(IDeviceUpdateTrigger updateTrigger, Guid deviceId) - : base(updateTrigger, deviceId) - { } + /// The update trigger used to update this queue. + public RazerChromaLinkUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override IntPtr CreateEffectParams(Dictionary dataSet) - { - _Color[] colors = new _Color[_Defines.CHROMALINK_MAX_LEDS]; + /// + protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet) + { + _Color[] colors = new _Color[_Defines.CHROMALINK_MAX_LEDS]; - foreach (KeyValuePair data in dataSet) - colors[(int)data.Key] = new _Color(data.Value); + foreach ((object key, Color color) in dataSet) + colors[(int)key] = new _Color(color); - _ChromaLinkCustomEffect effectParams = new _ChromaLinkCustomEffect { Color = colors }; + _ChromaLinkCustomEffect effectParams = new() + { Color = colors }; - IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); - Marshal.StructureToPtr(effectParams, ptr, false); + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); + Marshal.StructureToPtr(effectParams, ptr, false); - return ptr; - } + return ptr; + } - /// - protected override void CreateEffect(IntPtr effectParams, ref Guid effectId) => _RazerSDK.CreateChromaLinkEffect(_Defines.CHROMALINK_EFFECT_ID, effectParams, ref effectId); + /// + protected override void CreateEffect(IntPtr effectParams, ref Guid effectId) => _RazerSDK.CreateChromaLinkEffect(_Defines.CHROMALINK_EFFECT_ID, effectParams, ref effectId); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Enum/DeviceType.cs b/RGB.NET.Devices.Razer/Enum/DeviceType.cs index 202988dc..9d9954db 100644 --- a/RGB.NET.Devices.Razer/Enum/DeviceType.cs +++ b/RGB.NET.Devices.Razer/Enum/DeviceType.cs @@ -1,14 +1,13 @@ -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +internal enum DeviceType { - internal enum DeviceType - { - Keyboard = 1, - Mouse = 2, - Headset = 3, - Mousepad = 4, - Keypad = 5, - System = 6, - Speakers = 7, - Invalid - } -} + Keyboard = 1, + Mouse = 2, + Headset = 3, + Mousepad = 4, + Keypad = 5, + System = 6, + Speakers = 7, + Invalid +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Enum/RazerEndpointType.cs b/RGB.NET.Devices.Razer/Enum/RazerEndpointType.cs new file mode 100644 index 00000000..01bb0609 --- /dev/null +++ b/RGB.NET.Devices.Razer/Enum/RazerEndpointType.cs @@ -0,0 +1,42 @@ +namespace RGB.NET.Devices.Razer; + +/// +/// Represents a type of Razer SDK endpoint +/// +public enum RazerEndpointType +{ + /// + /// The keyboard endpoint + /// + Keyboard, + + /// + /// The laptop keyboard endpoint, shares the endpoint but has a different LED layout + /// + LaptopKeyboard, + + /// + /// The mouse endpoint + /// + Mouse, + + /// + /// The headset endpoint + /// + Headset, + + /// + /// The mousepad endpoint + /// + Mousepad, + + /// + /// The keypad endpoint + /// + Keypad, + + /// + /// The Chroma Link endpoint + /// + ChromaLink, +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Enum/RazerError.cs b/RGB.NET.Devices.Razer/Enum/RazerError.cs index 34007920..c25b0d38 100644 --- a/RGB.NET.Devices.Razer/Enum/RazerError.cs +++ b/RGB.NET.Devices.Razer/Enum/RazerError.cs @@ -1,93 +1,92 @@ -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// Razer-SDK: Error codes for Chroma SDK. If the error is not defined here, refer to WinError.h from the Windows SDK. +/// +public enum RazerError { /// - /// Razer-SDK: Error codes for Chroma SDK. If the error is not defined here, refer to WinError.h from the Windows SDK. - /// - public enum RazerError : int - { - /// - /// Razer-SDK: Invalid. - /// - Invalid = -1, - - /// - /// Razer-SDK: Success. - /// - Success = 0, - - /// - /// Razer-SDK: Access denied. - /// - AccessDenied = 5, - - /// - /// Razer-SDK: Invalid handle. - /// - InvalidHandle = 6, - - /// - /// Razer-SDK: Not supported. - /// - NotSupported = 50, - - /// - /// Razer-SDK: Invalid parameter. - /// - InvalidParameter = 87, - - /// - /// Razer-SDK: The service has not been started. - /// - ServiceNotActive = 1062, - - /// - /// Razer-SDK: Cannot start more than one instance of the specified program. - /// - SingleInstanceApp = 1152, - - /// - /// Razer-SDK: Device not connected. - /// - DeviceNotConnected = 1167, - - /// - /// Razer-SDK: Element not found. - /// - NotFound = 1168, - - /// - /// Razer-SDK: Request aborted. - /// - RequestAborted = 1235, - - /// - /// Razer-SDK: An attempt was made to perform an initialization operation when initialization has already been completed. - /// - AlreadyInitialized = 1247, - - /// - /// Razer-SDK: Resource not available or disabled. - /// - ResourceDisabled = 4309, - - /// - /// Razer-SDK: Device not available or supported. - /// - DeviceNotAvailable = 4319, - - /// - /// Razer-SDK: The group or resource is not in the correct state to perform the requested operation. - /// - NotValidState = 5023, - - /// - /// Razer-SDK: No more items. - /// - NoMoreItems = 259, - - /// - /// Razer-SDK: General failure. - /// - Failed = unchecked(-2147467259) - } -} + /// Razer-SDK: Invalid. + /// + Invalid = -1, + + /// + /// Razer-SDK: Success. + /// + Success = 0, + + /// + /// Razer-SDK: Access denied. + /// + AccessDenied = 5, + + /// + /// Razer-SDK: Invalid handle. + /// + InvalidHandle = 6, + + /// + /// Razer-SDK: Not supported. + /// + NotSupported = 50, + + /// + /// Razer-SDK: Invalid parameter. + /// + InvalidParameter = 87, + + /// + /// Razer-SDK: The service has not been started. + /// + ServiceNotActive = 1062, + + /// + /// Razer-SDK: Cannot start more than one instance of the specified program. + /// + SingleInstanceApp = 1152, + + /// + /// Razer-SDK: Device not connected. + /// + DeviceNotConnected = 1167, + + /// + /// Razer-SDK: Element not found. + /// + NotFound = 1168, + + /// + /// Razer-SDK: Request aborted. + /// + RequestAborted = 1235, + + /// + /// Razer-SDK: An attempt was made to perform an initialization operation when initialization has already been completed. + /// + AlreadyInitialized = 1247, + + /// + /// Razer-SDK: Resource not available or disabled. + /// + ResourceDisabled = 4309, + + /// + /// Razer-SDK: Device not available or supported. + /// + DeviceNotAvailable = 4319, + + /// + /// Razer-SDK: The group or resource is not in the correct state to perform the requested operation. + /// + NotValidState = 5023, + + /// + /// Razer-SDK: No more items. + /// + NoMoreItems = 259, + + /// + /// Razer-SDK: General failure. + /// + Failed = unchecked(-2147467259) +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Enum/RazerLogicalKeyboardLayout.cs b/RGB.NET.Devices.Razer/Enum/RazerLogicalKeyboardLayout.cs deleted file mode 100644 index 1ec93820..00000000 --- a/RGB.NET.Devices.Razer/Enum/RazerLogicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Razer -{ - /// - /// Contains list of available logical layouts for razer keyboards. - /// - public enum RazerLogicalKeyboardLayout - { - TODO - }; -} diff --git a/RGB.NET.Devices.Razer/Enum/RazerPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Razer/Enum/RazerPhysicalKeyboardLayout.cs deleted file mode 100644 index 090a2db7..00000000 --- a/RGB.NET.Devices.Razer/Enum/RazerPhysicalKeyboardLayout.cs +++ /dev/null @@ -1,15 +0,0 @@ -// ReSharper disable UnusedMember.Global -// ReSharper disable InconsistentNaming - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Razer -{ - /// - /// Contains list of available physical layouts for razer keyboards. - /// - public enum RazerPhysicalKeyboardLayout - { - TODO - } -} diff --git a/RGB.NET.Devices.Razer/Exceptions/RazerException.cs b/RGB.NET.Devices.Razer/Exceptions/RazerException.cs index edd6bac9..3350c811 100644 --- a/RGB.NET.Devices.Razer/Exceptions/RazerException.cs +++ b/RGB.NET.Devices.Razer/Exceptions/RazerException.cs @@ -3,35 +3,34 @@ using System; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// +/// Represents an exception thrown by the Razer-SDK. +/// +public class RazerException : ApplicationException { - /// + #region Properties & Fields + /// - /// Represents an exception thrown by the Razer-SDK. + /// Gets the error code provided by the SDK. /// - public class RazerException : ApplicationException - { - #region Properties & Fields - - /// - /// Gets the error code provided by the SDK. - /// - public RazerError ErrorCode { get; } - - #endregion + public RazerError ErrorCode { get; } - #region Constructors + #endregion - /// - /// - /// Initializes a new instance of the class. - /// - /// The error code provided by the SDK. - public RazerException(RazerError errorCode) - { - this.ErrorCode = errorCode; - } + #region Constructors - #endregion + /// + /// + /// Initializes a new instance of the class. + /// + /// The error code provided by the SDK. + public RazerException(RazerError errorCode) + { + this.ErrorCode = errorCode; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Generic/Devices.cs b/RGB.NET.Devices.Razer/Generic/Devices.cs index a1eeeff4..fb470551 100644 --- a/RGB.NET.Devices.Razer/Generic/Devices.cs +++ b/RGB.NET.Devices.Razer/Generic/Devices.cs @@ -1,71 +1,70 @@ using System; using System.Collections.Generic; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +internal class Devices { - internal class Devices - { - public static readonly List<(Guid guid, string model)> KEYBOARDS = new List<(Guid guid, string model)> - { - (new Guid("2EA1BB63-CA28-428D-9F06-196B88330BBB"), "Blackwidow Chroma"), - (new Guid("ED1C1B82-BFBE-418F-B49D-D03F05B149DF"), "Razer Blackwidow Chroma Tournament Edition"), - (new Guid("18C5AD9B-4326-4828-92C4-2669A66D2283"), "Razer Deathstalker "), - (new Guid("872AB2A9-7959-4478-9FED-15F6186E72E4"), "Overwatch Keyboard"), - (new Guid("5AF60076-ADE9-43D4-B574-52599293B554"), "Razer Blackwidow X Chroma"), - (new Guid("2D84DD51-3290-4AAC-9A89-D8AFDE38B57C"), "Razer Blackwidow X TE Chroma"), - (new Guid("803378C1-CC48-4970-8539-D828CC1D420A"), "Razer Omata Chroma"), - (new Guid("C83BDFE8-E7FC-40E0-99DB-872E23F19891"), "Razer Blade Stealth"), - (new Guid("F2BEDFAF-A0FE-4651-9D41-B6CE603A3DDD"), "Razer Blade"), - (new Guid("A73AC338-F0E5-4BF7-91AE-DD1F7E1737A5"), "Razer Blade Pro"), - (new Guid("608E743F-B402-44BD-A7A6-7AA9F574ECF4"), "Razer Blackwidow Chroma v2"), - (new Guid("F85E7473-8F03-45B6-A16E-CE26CB8D2441"), "Razer Huntsman"), - (new Guid("16BB5ABD-C1CD-4CB3-BDF7-62438748BD98"), "Razer Blackwidow Elite") - }; + public static readonly List<(Guid guid, string model)> KEYBOARDS = new() + { + (new Guid("2EA1BB63-CA28-428D-9F06-196B88330BBB"), "Blackwidow Chroma"), + (new Guid("ED1C1B82-BFBE-418F-B49D-D03F05B149DF"), "Razer Blackwidow Chroma Tournament Edition"), + (new Guid("18C5AD9B-4326-4828-92C4-2669A66D2283"), "Razer Deathstalker "), + (new Guid("872AB2A9-7959-4478-9FED-15F6186E72E4"), "Overwatch Keyboard"), + (new Guid("5AF60076-ADE9-43D4-B574-52599293B554"), "Razer Blackwidow X Chroma"), + (new Guid("2D84DD51-3290-4AAC-9A89-D8AFDE38B57C"), "Razer Blackwidow X TE Chroma"), + (new Guid("803378C1-CC48-4970-8539-D828CC1D420A"), "Razer Omata Chroma"), + (new Guid("C83BDFE8-E7FC-40E0-99DB-872E23F19891"), "Razer Blade Stealth"), + (new Guid("F2BEDFAF-A0FE-4651-9D41-B6CE603A3DDD"), "Razer Blade"), + (new Guid("A73AC338-F0E5-4BF7-91AE-DD1F7E1737A5"), "Razer Blade Pro"), + (new Guid("608E743F-B402-44BD-A7A6-7AA9F574ECF4"), "Razer Blackwidow Chroma v2"), + (new Guid("F85E7473-8F03-45B6-A16E-CE26CB8D2441"), "Razer Huntsman"), + (new Guid("16BB5ABD-C1CD-4CB3-BDF7-62438748BD98"), "Razer Blackwidow Elite") + }; - public static readonly List<(Guid guid, string model)> MICE = new List<(Guid guid, string model)> - { - (new Guid("7EC00450-E0EE-4289-89D5-0D879C19061A"), "Razer Mamba Chroma Tournament Edition"), - (new Guid("AEC50D91-B1F1-452F-8E16-7B73F376FDF3"), "Razer Deathadder Chroma "), - (new Guid("FF8A5929-4512-4257-8D59-C647BF9935D0"), "Razer Diamondback"), - (new Guid("D527CBDC-EB0A-483A-9E89-66D50463EC6C"), "Razer Mamba"), - (new Guid("D714C50B-7158-4368-B99C-601ACB985E98"), "Razer Naga Epic"), - (new Guid("F1876328-6CA4-46AE-BE04-BE812B414433"), "Razer Naga"), - (new Guid("52C15681-4ECE-4DD9-8A52-A1418459EB34"), "Razer Orochi Chroma"), - (new Guid("195D70F5-F285-4CFF-99F2-B8C0E9658DB4"), "Razer Naga Hex Chroma"), - (new Guid("77834867-3237-4A9F-AD77-4A46C4183003"), "Razer DeathAdder Elite Chroma") - }; + public static readonly List<(Guid guid, string model)> MICE = new() + { + (new Guid("7EC00450-E0EE-4289-89D5-0D879C19061A"), "Razer Mamba Chroma Tournament Edition"), + (new Guid("AEC50D91-B1F1-452F-8E16-7B73F376FDF3"), "Razer Deathadder Chroma "), + (new Guid("FF8A5929-4512-4257-8D59-C647BF9935D0"), "Razer Diamondback"), + (new Guid("D527CBDC-EB0A-483A-9E89-66D50463EC6C"), "Razer Mamba"), + (new Guid("D714C50B-7158-4368-B99C-601ACB985E98"), "Razer Naga Epic"), + (new Guid("F1876328-6CA4-46AE-BE04-BE812B414433"), "Razer Naga"), + (new Guid("52C15681-4ECE-4DD9-8A52-A1418459EB34"), "Razer Orochi Chroma"), + (new Guid("195D70F5-F285-4CFF-99F2-B8C0E9658DB4"), "Razer Naga Hex Chroma"), + (new Guid("77834867-3237-4A9F-AD77-4A46C4183003"), "Razer DeathAdder Elite Chroma") + }; - public static readonly List<(Guid guid, string model)> HEADSETS = new List<(Guid guid, string model)> - { - (new Guid("DF3164D7-5408-4A0E-8A7F-A7412F26BEBF"), "Razer ManO'War"), - (new Guid("CD1E09A5-D5E6-4A6C-A93B-E6D9BF1D2092"), "Razer Kraken 7.1 Chroma"), - (new Guid("7FB8A36E-9E74-4BB3-8C86-CAC7F7891EBD"), "Razer Kraken 7.1 Chroma Refresh"), - (new Guid("FB357780-4617-43A7-960F-D1190ED54806"), "Razer Kraken Kitty") - }; + public static readonly List<(Guid guid, string model)> HEADSETS = new() + { + (new Guid("DF3164D7-5408-4A0E-8A7F-A7412F26BEBF"), "Razer ManO'War"), + (new Guid("CD1E09A5-D5E6-4A6C-A93B-E6D9BF1D2092"), "Razer Kraken 7.1 Chroma"), + (new Guid("7FB8A36E-9E74-4BB3-8C86-CAC7F7891EBD"), "Razer Kraken 7.1 Chroma Refresh"), + (new Guid("FB357780-4617-43A7-960F-D1190ED54806"), "Razer Kraken Kitty") + }; - public static readonly List<(Guid guid, string model)> MOUSEMATS = new List<(Guid guid, string model)> - { - (new Guid("80F95A94-73D2-48CA-AE9A-0986789A9AF2"), "Razer Firefly") - }; + public static readonly List<(Guid guid, string model)> MOUSEMATS = new() + { + (new Guid("80F95A94-73D2-48CA-AE9A-0986789A9AF2"), "Razer Firefly") + }; - public static readonly List<(Guid guid, string model)> KEYPADS = new List<(Guid guid, string model)> - { - (new Guid("9D24B0AB-0162-466C-9640-7A924AA4D9FD"), "Razer Orbweaver"), - (new Guid("00F0545C-E180-4AD1-8E8A-419061CE505E"), "Razer Tartarus") - }; + public static readonly List<(Guid guid, string model)> KEYPADS = new() + { + (new Guid("9D24B0AB-0162-466C-9640-7A924AA4D9FD"), "Razer Orbweaver"), + (new Guid("00F0545C-E180-4AD1-8E8A-419061CE505E"), "Razer Tartarus") + }; - public static readonly List<(Guid guid, string model)> CHROMALINKS = new List<(Guid guid, string model)> - { - (new Guid("0201203B-62F3-4C50-83DD-598BABD208E0"), "Core Chroma"), - (new Guid("35F6F18D-1AE5-436C-A575-AB44A127903A"), "Lenovo Y900"), - (new Guid("47DB1FA7-6B9B-4EE6-B6F4-4071A3B2053B"), "Lenovo Y27"), - (new Guid("BB2E9C9B-B0D2-461A-BA52-230B5D6C3609"), "Chroma Box") - }; + public static readonly List<(Guid guid, string model)> CHROMALINKS = new() + { + (new Guid("0201203B-62F3-4C50-83DD-598BABD208E0"), "Core Chroma"), + (new Guid("35F6F18D-1AE5-436C-A575-AB44A127903A"), "Lenovo Y900"), + (new Guid("47DB1FA7-6B9B-4EE6-B6F4-4071A3B2053B"), "Lenovo Y27"), + (new Guid("BB2E9C9B-B0D2-461A-BA52-230B5D6C3609"), "Chroma Box") + }; - public static readonly List<(Guid guid, string model)> SPEAKERS = new List<(Guid guid, string model)> - { - (new Guid("45B308F2-CD44-4594-8375-4D5945AD880E"), "Nommo Chroma"), - (new Guid("3017280B-D7F9-4D7B-930E-7B47181B46B5"), "Nommo Chroma Pro") - }; - } -} + public static readonly List<(Guid guid, string model)> SPEAKERS = new() + { + (new Guid("45B308F2-CD44-4594-8375-4D5945AD880E"), "Nommo Chroma"), + (new Guid("3017280B-D7F9-4D7B-930E-7B47181B46B5"), "Nommo Chroma Pro") + }; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs b/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs index 9cf89ad7..35a38714 100644 --- a/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Generic/IRazerRGBDevice.cs @@ -1,13 +1,9 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Razer -{ - /// - /// Represents a razer RGB-device. - /// - internal interface IRazerRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - void Reset(); - } -} +namespace RGB.NET.Devices.Razer; + +/// +/// Represents a razer RGB-device. +/// +public interface IRazerRGBDevice : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Generic/LedMappings.cs b/RGB.NET.Devices.Razer/Generic/LedMappings.cs new file mode 100644 index 00000000..c0e8b3a4 --- /dev/null +++ b/RGB.NET.Devices.Razer/Generic/LedMappings.cs @@ -0,0 +1,274 @@ +using RGB.NET.Core; +using RGB.NET.Devices.Razer.Native; + +namespace RGB.NET.Devices.Razer; + +/// +/// Contains mappings for to the matrix location. +/// +public static class LedMappings +{ + /// + /// Gets the mapping for keyboards. + /// + public static LedMapping Keyboard { get; } = new() + { + //Row 0 is empty + + #region Row 1 + + [LedId.Keyboard_Escape] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 2, + [LedId.Keyboard_F1] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 4, + [LedId.Keyboard_F2] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 5, + [LedId.Keyboard_F3] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 6, + [LedId.Keyboard_F4] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 7, + [LedId.Keyboard_F5] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 8, + [LedId.Keyboard_F6] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 9, + [LedId.Keyboard_F7] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 10, + [LedId.Keyboard_F8] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 11, + [LedId.Keyboard_F9] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 12, + [LedId.Keyboard_F10] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 13, + [LedId.Keyboard_F11] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 14, + [LedId.Keyboard_F12] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 15, + [LedId.Keyboard_PrintScreen] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 16, + [LedId.Keyboard_ScrollLock] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 17, + [LedId.Keyboard_PauseBreak] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 18, + [LedId.Logo] = (_Defines.KEYBOARD_MAX_COLUMN * 1) + 21, + + #endregion + + #region Row 2 + + [LedId.Keyboard_Programmable1] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 1, + [LedId.Keyboard_GraveAccentAndTilde] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 2, + [LedId.Keyboard_1] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 3, + [LedId.Keyboard_2] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 4, + [LedId.Keyboard_3] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 5, + [LedId.Keyboard_4] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 6, + [LedId.Keyboard_5] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 7, + [LedId.Keyboard_6] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 8, + [LedId.Keyboard_7] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 9, + [LedId.Keyboard_8] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 10, + [LedId.Keyboard_9] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 11, + [LedId.Keyboard_0] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 12, + [LedId.Keyboard_MinusAndUnderscore] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 13, + [LedId.Keyboard_EqualsAndPlus] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 14, + [LedId.Keyboard_Backspace] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 15, + [LedId.Keyboard_Insert] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 16, + [LedId.Keyboard_Home] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 17, + [LedId.Keyboard_PageUp] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 18, + [LedId.Keyboard_NumLock] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 19, + [LedId.Keyboard_NumSlash] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 20, + [LedId.Keyboard_NumAsterisk] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 21, + [LedId.Keyboard_NumMinus] = (_Defines.KEYBOARD_MAX_COLUMN * 2) + 22, + + #endregion + + #region Row 3 + + [LedId.Keyboard_Programmable2] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 1, + [LedId.Keyboard_Tab] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 2, + [LedId.Keyboard_Q] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 3, + [LedId.Keyboard_W] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 4, + [LedId.Keyboard_E] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 5, + [LedId.Keyboard_R] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 6, + [LedId.Keyboard_T] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 7, + [LedId.Keyboard_Y] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 8, + [LedId.Keyboard_U] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 9, + [LedId.Keyboard_I] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 10, + [LedId.Keyboard_O] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 11, + [LedId.Keyboard_P] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 12, + [LedId.Keyboard_BracketLeft] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 13, + [LedId.Keyboard_BracketRight] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 14, + [LedId.Keyboard_Backslash] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 15, + [LedId.Keyboard_Delete] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 16, + [LedId.Keyboard_End] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 17, + [LedId.Keyboard_PageDown] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 18, + [LedId.Keyboard_Num7] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 19, + [LedId.Keyboard_Num8] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 20, + [LedId.Keyboard_Num9] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 21, + [LedId.Keyboard_NumPlus] = (_Defines.KEYBOARD_MAX_COLUMN * 3) + 22, + + #endregion + + #region Row 4 + + [LedId.Keyboard_Programmable3] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 1, + [LedId.Keyboard_CapsLock] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 2, + [LedId.Keyboard_A] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 3, + [LedId.Keyboard_S] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 4, + [LedId.Keyboard_D] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 5, + [LedId.Keyboard_F] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 6, + [LedId.Keyboard_G] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 7, + [LedId.Keyboard_H] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 8, + [LedId.Keyboard_J] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 9, + [LedId.Keyboard_K] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 10, + [LedId.Keyboard_L] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 11, + [LedId.Keyboard_SemicolonAndColon] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 12, + [LedId.Keyboard_ApostropheAndDoubleQuote] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 13, + [LedId.Keyboard_NonUsTilde] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 14, + [LedId.Keyboard_Enter] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 15, + [LedId.Keyboard_Num4] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 19, + [LedId.Keyboard_Num5] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 20, + [LedId.Keyboard_Num6] = (_Defines.KEYBOARD_MAX_COLUMN * 4) + 21, + + #endregion + + #region Row 5 + + [LedId.Keyboard_Programmable4] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 1, + [LedId.Keyboard_LeftShift] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 2, + [LedId.Keyboard_NonUsBackslash] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 3, + [LedId.Keyboard_Z] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 4, + [LedId.Keyboard_X] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 5, + [LedId.Keyboard_C] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 6, + [LedId.Keyboard_V] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 7, + [LedId.Keyboard_B] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 8, + [LedId.Keyboard_N] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 9, + [LedId.Keyboard_M] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 10, + [LedId.Keyboard_CommaAndLessThan] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 11, + [LedId.Keyboard_PeriodAndBiggerThan] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 12, + [LedId.Keyboard_SlashAndQuestionMark] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 13, + [LedId.Keyboard_RightShift] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 15, + [LedId.Keyboard_ArrowUp] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 17, + [LedId.Keyboard_Num1] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 19, + [LedId.Keyboard_Num2] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 20, + [LedId.Keyboard_Num3] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 21, + [LedId.Keyboard_NumEnter] = (_Defines.KEYBOARD_MAX_COLUMN * 5) + 22, + + #endregion + + #region Row 6 + + [LedId.Keyboard_Programmable5] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 1, + [LedId.Keyboard_LeftCtrl] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 2, + [LedId.Keyboard_LeftGui] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 3, + [LedId.Keyboard_LeftAlt] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 4, + [LedId.Keyboard_Space] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 8, + [LedId.Keyboard_RightAlt] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 12, + [LedId.Keyboard_RightGui] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 13, + [LedId.Keyboard_Application] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 14, + [LedId.Keyboard_RightCtrl] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 15, + [LedId.Keyboard_ArrowLeft] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 16, + [LedId.Keyboard_ArrowDown] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 17, + [LedId.Keyboard_ArrowRight] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 18, + [LedId.Keyboard_Num0] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 20, + [LedId.Keyboard_NumPeriodAndDelete] = (_Defines.KEYBOARD_MAX_COLUMN * 6) + 21, + + #endregion + + //Row 7 is also empty + }; + + /// + /// Gets the mapping for mice. + /// + /// + /// The order of the ids is a bit messed up since the officially documented locations are 1-21 and 22 is know to be used even if it's not documented. + /// 23-63 is there to not run into issues in the future. + /// + public static LedMapping Mouse { get; } = new() + { + //row 0 empty + [LedId.Mouse24] = (_Defines.MOUSE_MAX_COLUMN * 0) + 0, + [LedId.Mouse25] = (_Defines.MOUSE_MAX_COLUMN * 0) + 1, + [LedId.Mouse26] = (_Defines.MOUSE_MAX_COLUMN * 0) + 2, + [LedId.Mouse23] = (_Defines.MOUSE_MAX_COLUMN * 0) + 3, + [LedId.Mouse27] = (_Defines.MOUSE_MAX_COLUMN * 0) + 4, + [LedId.Mouse28] = (_Defines.MOUSE_MAX_COLUMN * 0) + 5, + [LedId.Mouse29] = (_Defines.MOUSE_MAX_COLUMN * 0) + 6, + + //row 1 + [LedId.Mouse1] = (_Defines.MOUSE_MAX_COLUMN * 1) + 0, + [LedId.Mouse30] = (_Defines.MOUSE_MAX_COLUMN * 1) + 1, + [LedId.Mouse31] = (_Defines.MOUSE_MAX_COLUMN * 1) + 2, + [LedId.Mouse32] = (_Defines.MOUSE_MAX_COLUMN * 1) + 3, + [LedId.Mouse33] = (_Defines.MOUSE_MAX_COLUMN * 1) + 4, + [LedId.Mouse34] = (_Defines.MOUSE_MAX_COLUMN * 1) + 5, + [LedId.Mouse2] = (_Defines.MOUSE_MAX_COLUMN * 1) + 6, + + //row 2 + [LedId.Mouse3] = (_Defines.MOUSE_MAX_COLUMN * 2) + 0, + [LedId.Mouse35] = (_Defines.MOUSE_MAX_COLUMN * 2) + 1, + [LedId.Mouse36] = (_Defines.MOUSE_MAX_COLUMN * 2) + 2, + [LedId.Mouse4] = (_Defines.MOUSE_MAX_COLUMN * 2) + 3, + [LedId.Mouse37] = (_Defines.MOUSE_MAX_COLUMN * 2) + 4, + [LedId.Mouse38] = (_Defines.MOUSE_MAX_COLUMN * 2) + 5, + [LedId.Mouse5] = (_Defines.MOUSE_MAX_COLUMN * 2) + 6, + + //row 3 + [LedId.Mouse6] = (_Defines.MOUSE_MAX_COLUMN * 3) + 0, + [LedId.Mouse39] = (_Defines.MOUSE_MAX_COLUMN * 3) + 1, + [LedId.Mouse40] = (_Defines.MOUSE_MAX_COLUMN * 3) + 2, + [LedId.Mouse41] = (_Defines.MOUSE_MAX_COLUMN * 3) + 3, + [LedId.Mouse42] = (_Defines.MOUSE_MAX_COLUMN * 3) + 4, + [LedId.Mouse43] = (_Defines.MOUSE_MAX_COLUMN * 3) + 5, + [LedId.Mouse7] = (_Defines.MOUSE_MAX_COLUMN * 3) + 6, + + //row 4 + [LedId.Mouse8] = (_Defines.MOUSE_MAX_COLUMN * 4) + 0, + [LedId.Mouse44] = (_Defines.MOUSE_MAX_COLUMN * 4) + 1, + [LedId.Mouse45] = (_Defines.MOUSE_MAX_COLUMN * 4) + 2, + [LedId.Mouse9] = (_Defines.MOUSE_MAX_COLUMN * 4) + 3, + [LedId.Mouse46] = (_Defines.MOUSE_MAX_COLUMN * 4) + 4, + [LedId.Mouse47] = (_Defines.MOUSE_MAX_COLUMN * 4) + 5, + [LedId.Mouse10] = (_Defines.MOUSE_MAX_COLUMN * 4) + 6, + + //row 5 + [LedId.Mouse11] = (_Defines.MOUSE_MAX_COLUMN * 5) + 0, + [LedId.Mouse48] = (_Defines.MOUSE_MAX_COLUMN * 5) + 1, + [LedId.Mouse49] = (_Defines.MOUSE_MAX_COLUMN * 5) + 2, + [LedId.Mouse50] = (_Defines.MOUSE_MAX_COLUMN * 5) + 3, + [LedId.Mouse51] = (_Defines.MOUSE_MAX_COLUMN * 5) + 4, + [LedId.Mouse52] = (_Defines.MOUSE_MAX_COLUMN * 5) + 5, + [LedId.Mouse12] = (_Defines.MOUSE_MAX_COLUMN * 5) + 6, + + //row 6 + [LedId.Mouse13] = (_Defines.MOUSE_MAX_COLUMN * 6) + 0, + [LedId.Mouse53] = (_Defines.MOUSE_MAX_COLUMN * 6) + 1, + [LedId.Mouse54] = (_Defines.MOUSE_MAX_COLUMN * 6) + 2, + [LedId.Mouse55] = (_Defines.MOUSE_MAX_COLUMN * 6) + 3, + [LedId.Mouse56] = (_Defines.MOUSE_MAX_COLUMN * 6) + 4, + [LedId.Mouse57] = (_Defines.MOUSE_MAX_COLUMN * 6) + 5, + [LedId.Mouse14] = (_Defines.MOUSE_MAX_COLUMN * 6) + 6, + + //row 7 + [LedId.Mouse15] = (_Defines.MOUSE_MAX_COLUMN * 7) + 0, + [LedId.Mouse58] = (_Defines.MOUSE_MAX_COLUMN * 7) + 1, + [LedId.Mouse59] = (_Defines.MOUSE_MAX_COLUMN * 7) + 2, + [LedId.Mouse16] = (_Defines.MOUSE_MAX_COLUMN * 7) + 3, + [LedId.Mouse60] = (_Defines.MOUSE_MAX_COLUMN * 7) + 4, + [LedId.Mouse61] = (_Defines.MOUSE_MAX_COLUMN * 7) + 5, + [LedId.Mouse17] = (_Defines.MOUSE_MAX_COLUMN * 7) + 6, + + //row 8 + [LedId.Mouse62] = (_Defines.MOUSE_MAX_COLUMN * 8) + 0, + [LedId.Mouse18] = (_Defines.MOUSE_MAX_COLUMN * 8) + 1, + [LedId.Mouse19] = (_Defines.MOUSE_MAX_COLUMN * 8) + 2, + [LedId.Mouse20] = (_Defines.MOUSE_MAX_COLUMN * 8) + 3, + [LedId.Mouse21] = (_Defines.MOUSE_MAX_COLUMN * 8) + 4, + [LedId.Mouse22] = (_Defines.MOUSE_MAX_COLUMN * 8) + 5, + [LedId.Mouse63] = (_Defines.MOUSE_MAX_COLUMN * 8) + 6, + }; + + //TODO DarthAffe 27.04.2021: Are mappings for these possible? + /// + /// Gets the mapping for mousepads. + /// + public static LedMapping Mousepad { get; } = new(); + + /// + /// Gets the mapping for headsets. + /// + public static LedMapping Headset { get; } = new(); + + /// + /// Gets the mapping for keypads. + /// + public static LedMapping Keypad { get; } = new(); + + /// + /// Gets the mapping for chroma link devices. + /// + public static LedMapping ChromaLink { get; } = new(); +} diff --git a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs index e537cafd..1a365955 100644 --- a/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Generic/RazerRGBDevice.cs @@ -1,95 +1,46 @@ -using System.Collections.Generic; -using System.Linq; +using System; +using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// +/// +/// Represents a generic razer-device. (keyboard, mouse, headset, mousepad). +/// +public abstract class RazerRGBDevice : AbstractRGBDevice, IRazerRGBDevice { - /// - /// + #region Constructors + /// - /// Represents a generic razer-device. (keyboard, mouse, headset, mousepad). + /// Initializes a new instance of the class. /// - public abstract class RazerRGBDevice : AbstractRGBDevice, IRazerRGBDevice - where TDeviceInfo : RazerRGBDeviceInfo + /// The generic information provided by razer for the device. + /// The queue used to update this device. + protected RazerRGBDevice(RazerRGBDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected RazerUpdateQueue UpdateQueue { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by razer for the device. - protected RazerRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - - RequiresFlush = true; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - - UpdateQueue = CreateUpdateQueue(updateTrigger); - } - - /// - /// Creates a specific for this device. - /// - /// The trigger used to update the queue. - /// The for this device. - protected abstract RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger); + RequiresFlush = true; + } - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); + #endregion - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + #region Methods - /// - /// Resets the device. - /// - public void Reset() => UpdateQueue.Reset(); + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } + /// + public override void Dispose() + { + try { UpdateQueue.Dispose(); } + catch { /* at least we tried */ } - base.Dispose(); - } + base.Dispose(); - #endregion + GC.SuppressFinalize(this); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Generic/RazerRGBDeviceInfo.cs b/RGB.NET.Devices.Razer/Generic/RazerRGBDeviceInfo.cs index 3b1f2414..7dbb8822 100644 --- a/RGB.NET.Devices.Razer/Generic/RazerRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Razer/Generic/RazerRGBDeviceInfo.cs @@ -1,61 +1,53 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Razer -{ - /// - /// - /// Represents a generic information for a Razer-. - /// - public class RazerRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Devices.Razer; - /// - /// Gets the Id of the . - /// - public Guid DeviceId { get; } - - /// - public RGBDeviceType DeviceType { get; } - - /// - public string DeviceName { get; } +/// +/// +/// Represents a generic information for a Razer-. +/// +public class RazerRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public string Manufacturer => "Razer"; + /// + public RGBDeviceType DeviceType { get; } - /// - public string Model { get; } + /// + public string DeviceName { get; } - /// - public Uri Image { get; set; } + /// + public string Manufacturer => "Razer"; - /// - public bool SupportsSyncBack => false; + /// + public string Model { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public object? LayoutMetadata { get; set; } - #endregion + /// + /// Gets the Razer SDK endpoint type the is addressed through. + /// + public RazerEndpointType EndpointType { get; } - #region Constructors + #endregion - /// - /// Internal constructor of managed . - /// - /// The Id of the . - /// The type of the . - /// The model of the . - internal RazerRGBDeviceInfo(Guid deviceId, RGBDeviceType deviceType, string model) - { - this.DeviceId = deviceId; - this.DeviceType = deviceType; - this.Model = model; + #region Constructors - DeviceName = $"{Manufacturer} {Model}"; - } + /// + /// Internal constructor of managed . + /// + /// The type of the . + /// The Razer SDK endpoint type the is addressed through. + /// The model of the . + internal RazerRGBDeviceInfo(RGBDeviceType deviceType, RazerEndpointType endpointType, string model) + { + this.DeviceType = deviceType; + this.EndpointType = endpointType; + this.Model = model; - #endregion + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs b/RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs index de99795b..cc8fedcc 100644 --- a/RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Generic/RazerUpdateQueue.cs @@ -1,78 +1,73 @@ using System; -using System.Collections.Generic; using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer -{ - /// - /// Represents a basic update-queue performing updates for razer devices. - /// - public abstract class RazerUpdateQueue : UpdateQueue - { - #region Properties & Fields +namespace RGB.NET.Devices.Razer; - private readonly Guid _deviceId; - private Guid? _lastEffect; +/// +/// Represents a basic update-queue performing updates for razer devices. +/// +public abstract class RazerUpdateQueue : UpdateQueue +{ + #region Properties & Fields + + private Guid? _lastEffect; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used to update this queue. - /// The id of the device updated by this queue. - protected RazerUpdateQueue(IDeviceUpdateTrigger updateTrigger, Guid deviceId) - : base(updateTrigger) - { - this._deviceId = deviceId; - } + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used to update this queue. + protected RazerUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void Update(Dictionary dataSet) - { - IntPtr effectParams = CreateEffectParams(dataSet); - Guid effectId = Guid.NewGuid(); - CreateEffect(effectParams, ref effectId); + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + IntPtr effectParams = CreateEffectParams(dataSet); + Guid effectId = Guid.NewGuid(); + CreateEffect(effectParams, ref effectId); - _RazerSDK.SetEffect(effectId); + _RazerSDK.SetEffect(effectId); - if (_lastEffect.HasValue) - _RazerSDK.DeleteEffect(_lastEffect.Value); + if (_lastEffect.HasValue) + _RazerSDK.DeleteEffect(_lastEffect.Value); - _lastEffect = effectId; - } + _lastEffect = effectId; + } - /// - /// Creates the effect used to update this device. - /// - /// The parameters of the effect. - /// The id this effect is created with. - protected virtual void CreateEffect(IntPtr effectParams, ref Guid effectId) => _RazerSDK.CreateEffect(_deviceId, _Defines.EFFECT_ID, effectParams, ref effectId); + /// + /// Creates the effect used to update this device. + /// + /// The parameters of the effect. + /// The id this effect is created with. + protected abstract void CreateEffect(IntPtr effectParams, ref Guid effectId); - /// - public override void Reset() + /// + public override void Reset() + { + if (_lastEffect.HasValue) { - if (_lastEffect.HasValue) - { - _RazerSDK.DeleteEffect(_lastEffect.Value); - _lastEffect = null; - } + _RazerSDK.DeleteEffect(_lastEffect.Value); + _lastEffect = null; } + } - /// - /// Creates the device-specific effect parameters for the led-update. - /// - /// The data to be updated. - /// An pointing to the effect parameter struct. - protected abstract IntPtr CreateEffectParams(Dictionary dataSet); + /// + /// Creates the device-specific effect parameters for the led-update. + /// + /// The data to be updated. + /// An pointing to the effect parameter struct. + protected abstract IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs b/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs index 25fbfd45..cec7f087 100644 --- a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDevice.cs @@ -4,46 +4,40 @@ using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// +/// Represents a razer headset. +/// +public class RazerHeadsetRGBDevice : RazerRGBDevice, IHeadset { - /// + #region Constructors + + /// /// - /// Represents a razer headset. + /// Initializes a new instance of the class. /// - public class RazerHeadsetRGBDevice : RazerRGBDevice, IHeadset + /// The specific information provided by CUE for the headset. + /// The update trigger used to update this device. + internal RazerHeadsetRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerHeadsetUpdateQueue(updateTrigger)) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the headset. - internal RazerHeadsetRGBDevice(RazerHeadsetRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods + InitializeLayout(); + } - /// - protected override void InitializeLayout() - { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\Headset", $"{model}.xml"), null); + #endregion - if (LedMapping.Count == 0) - for (int i = 0; i < _Defines.HEADSET_MAX_LEDS; i++) - InitializeLed(LedId.Headset1 + i, new Rectangle(i * 11, 0, 10, 10)); - } + #region Methods - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1; + private void InitializeLayout() + { + for (int i = 0; i < _Defines.HEADSET_MAX_LEDS; i++) + AddLed(LedId.Headset1 + i, new Point(i * 10, 0), new Size(10, 10)); + } - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerHeadsetUpdateQueue(updateTrigger, DeviceInfo.DeviceId); + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Headset1; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDeviceInfo.cs b/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDeviceInfo.cs deleted file mode 100644 index bbe77fe8..00000000 --- a/RGB.NET.Devices.Razer/Headset/RazerHeadsetRGBDeviceInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Razer -{ - /// - /// - /// Represents a generic information for a . - /// - public class RazerHeadsetRGBDeviceInfo : RazerRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The Id of the . - /// The model of the . - internal RazerHeadsetRGBDeviceInfo(Guid deviceId, string model) - : base(deviceId, RGBDeviceType.Headset, model) - { } - - #endregion - } -} diff --git a/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs b/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs index 91563e16..9cb3eaf5 100644 --- a/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Headset/RazerHeadsetUpdateQueue.cs @@ -1,50 +1,48 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// Represents the update-queue performing updates for razer headset devices. +/// +public class RazerHeadsetUpdateQueue : RazerUpdateQueue { + #region Constructors + /// - /// Represents the update-queue performing updates for razer headset devices. + /// Initializes a new instance of the class. /// - public class RazerHeadsetUpdateQueue : RazerUpdateQueue - { - #region Constructors + /// The update trigger used to update this queue. + public RazerHeadsetUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { } - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used to update this queue. - /// The id of the device updated by this queue. - public RazerHeadsetUpdateQueue(IDeviceUpdateTrigger updateTrigger, Guid deviceId) - : base(updateTrigger, deviceId) - { } + #endregion - #endregion + #region Methods - #region Methods + /// + protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet) + { + _Color[] colors = new _Color[_Defines.HEADSET_MAX_LEDS]; - /// - protected override IntPtr CreateEffectParams(Dictionary dataSet) - { - _Color[] colors = new _Color[_Defines.HEADSET_MAX_LEDS]; + foreach ((object key, Color color) in dataSet) + colors[(int)key] = new _Color(color); - foreach (KeyValuePair data in dataSet) - colors[(int)data.Key] = new _Color(data.Value); + _HeadsetCustomEffect effectParams = new() + { Color = colors }; - _HeadsetCustomEffect effectParams = new _HeadsetCustomEffect { Color = colors }; - - IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); - Marshal.StructureToPtr(effectParams, ptr, false); + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); + Marshal.StructureToPtr(effectParams, ptr, false); - return ptr; - } + return ptr; + } - /// - protected override void CreateEffect(IntPtr effectParams, ref Guid effectId) => _RazerSDK.CreateHeadsetEffect(_Defines.HEADSET_EFFECT_ID, effectParams, ref effectId); + /// + protected override void CreateEffect(IntPtr effectParams, ref Guid effectId) => _RazerSDK.CreateHeadsetEffect(_Defines.HEADSET_EFFECT_ID, effectParams, ref effectId); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs index 8c6aab6f..3a4c5f24 100644 --- a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDevice.cs @@ -4,52 +4,53 @@ using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// +/// Represents a razer keyboard. +/// +public class RazerKeyboardRGBDevice : RazerRGBDevice, IKeyboard { - /// + #region Properties & Fields + + IKeyboardDeviceInfo IKeyboard.DeviceInfo => (IKeyboardDeviceInfo)DeviceInfo; + + private readonly LedMapping _ledMapping; + + #endregion + + #region Constructors + + /// /// - /// Represents a razer keyboard. + /// Initializes a new instance of the class. /// - public class RazerKeyboardRGBDevice : RazerRGBDevice, IKeyboard + /// The specific information provided by CUE for the keyboard. + /// The update trigger used to update this device. + /// A mapping of leds this device is initialized with. + internal RazerKeyboardRGBDevice(RazerKeyboardRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger, LedMapping ledMapping) + : base(info, new RazerKeyboardUpdateQueue(updateTrigger)) + { + this._ledMapping = ledMapping; + + InitializeLayout(); + } + + #endregion + + #region Methods + + private void InitializeLayout() { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the keyboard. - internal RazerKeyboardRGBDevice(RazerKeyboardRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - //string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - //ApplyLayoutFromFile(PathHelper.GetAbsolutePath( - // $@"Layouts\Razer\Keyboards\{model}\{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), - // DeviceInfo.LogicalLayout.ToString(), PathHelper.GetAbsolutePath(@"Images\Razer\Keyboards")); - - //TODO DarthAffe 13.12.2017: Correctly select ids - if (LedMapping.Count == 0) - { - for (int i = 0; i < _Defines.KEYBOARD_MAX_ROW; i++) - for (int j = 0; j < _Defines.KEYBOARD_MAX_COLUMN; j++) - InitializeLed(LedId.Keyboard_Escape + ((i * _Defines.KEYBOARD_MAX_COLUMN) + j), new Rectangle(j * 20, i * 20, 19, 19)); - } - } - - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keyboard_Escape; - - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeyboardUpdateQueue(updateTrigger, DeviceInfo.DeviceId); - - #endregion + for (int row = 0; row < _Defines.KEYBOARD_MAX_ROW; row++) + for (int column = 0; column < _Defines.KEYBOARD_MAX_COLUMN; column++) + if (_ledMapping.TryGetValue((row * _Defines.KEYBOARD_MAX_COLUMN) + column, out LedId id)) + AddLed(id, new Point(column * 19, row * 19), new Size(19, 19)); } -} + + /// + protected override object GetLedCustomData(LedId ledId) => _ledMapping[ledId]; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDeviceInfo.cs index 1057eccb..983d030a 100644 --- a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardRGBDeviceInfo.cs @@ -1,63 +1,34 @@ // ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global -using System; -using System.Globalization; using RGB.NET.Core; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// Represents a generic information for a . +/// +public class RazerKeyboardRGBDeviceInfo : RazerRGBDeviceInfo, IKeyboardDeviceInfo { + #region Properties & Fields + + /// + public KeyboardLayoutType Layout => KeyboardLayoutType.Unknown; + + #endregion + + #region Constructors + /// /// - /// Represents a generic information for a . + /// Internal constructor of managed . /// - public class RazerKeyboardRGBDeviceInfo : RazerRGBDeviceInfo + /// The model of the . + /// The Razer SDK endpoint type the is addressed through. + internal RazerKeyboardRGBDeviceInfo(string model, RazerEndpointType endpointType) + : base(RGBDeviceType.Keyboard, endpointType, model) { - #region Properties & Fields - - /// - /// Gets the physical layout of the keyboard. - /// - public RazerPhysicalKeyboardLayout PhysicalLayout { get; private set; } - - /// - /// Gets the logical layout of the keyboard as set in CUE settings. - /// - public RazerLogicalKeyboardLayout LogicalLayout { get; private set; } - - #endregion - - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The Id of the . - /// The model of the . - /// The of the layout this keyboard is using. - internal RazerKeyboardRGBDeviceInfo(Guid deviceId, string model, CultureInfo culture) - : base(deviceId, RGBDeviceType.Keyboard, model) - { - SetLayouts(culture.KeyboardLayoutId); - } - - #endregion - - #region Methods - - private void SetLayouts(int keyboardLayoutId) - { - switch (keyboardLayoutId) - { - //TODO DarthAffe 07.10.2017: Implement - default: - PhysicalLayout = RazerPhysicalKeyboardLayout.TODO; - LogicalLayout = RazerLogicalKeyboardLayout.TODO; - break; - } - } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs index 16db3a92..09b8c2d9 100644 --- a/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Keyboard/RazerKeyboardUpdateQueue.cs @@ -1,47 +1,47 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// Represents the update-queue performing updates for razer keyboard devices. +/// +public class RazerKeyboardUpdateQueue : RazerUpdateQueue { + #region Constructors + /// - /// Represents the update-queue performing updates for razer keyboard devices. + /// Initializes a new instance of the class. /// - public class RazerKeyboardUpdateQueue : RazerUpdateQueue - { - #region Constructors + /// The update trigger used to update this queue. + public RazerKeyboardUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { } - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used to update this queue. - /// The id of the device updated by this queue. - public RazerKeyboardUpdateQueue(IDeviceUpdateTrigger updateTrigger, Guid deviceId) - : base(updateTrigger, deviceId) - { } + #endregion - #endregion + #region Methods - #region Methods + /// + protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet) + { + _Color[] colors = new _Color[_Defines.KEYBOARD_MAX_LEDS]; - /// - protected override IntPtr CreateEffectParams(Dictionary dataSet) - { - _Color[] colors = new _Color[_Defines.KEYBOARD_MAX_LEDS]; + foreach ((object key, Color color) in dataSet) + colors[(int)key] = new _Color(color); - foreach (KeyValuePair data in dataSet) - colors[(int)data.Key] = new _Color(data.Value); + _KeyboardCustomEffect effectParams = new() { Color = colors }; - _KeyboardCustomEffect effectParams = new _KeyboardCustomEffect { Color = colors }; + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); + Marshal.StructureToPtr(effectParams, ptr, false); - IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); - Marshal.StructureToPtr(effectParams, ptr, false); + return ptr; + } - return ptr; - } + /// + protected override void CreateEffect(IntPtr effectParams, ref Guid effectId) => _RazerSDK.CreateKeyboardEffect(_Defines.KEYBOARD_EFFECT_ID, effectParams, ref effectId); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs b/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs index be86e2d2..f620388e 100644 --- a/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDevice.cs @@ -4,49 +4,41 @@ using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// +/// Represents a razer keypad. +/// +public class RazerKeypadRGBDevice : RazerRGBDevice, IKeypad { - /// + #region Constructors + + /// /// - /// Represents a razer keypad. + /// Initializes a new instance of the class. /// - public class RazerKeypadRGBDevice : RazerRGBDevice, IKeypad + /// The specific information provided by CUE for the keypad. + /// The update trigger used to update this device. + internal RazerKeypadRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerKeypadUpdateQueue(updateTrigger)) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the keypad. - internal RazerKeypadRGBDevice(RazerKeypadRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\Keypad", $"{model}.xml"), null); - - if (LedMapping.Count == 0) - { - for (int i = 0; i < _Defines.KEYPAD_MAX_ROW; i++) - for (int j = 0; j < _Defines.KEYPAD_MAX_COLUMN; j++) - InitializeLed(LedId.Keypad1 + ((i * _Defines.KEYPAD_MAX_COLUMN) + j), new Rectangle(j * 20, i * 20, 19, 19)); - } - } - - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keypad1; - - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerKeypadUpdateQueue(updateTrigger, DeviceInfo.DeviceId); - - #endregion + InitializeLayout(); } -} + + #endregion + + #region Methods + + private void InitializeLayout() + { + for (int row = 0; row < _Defines.KEYPAD_MAX_ROW; row++) + for (int column = 0; column < _Defines.KEYPAD_MAX_COLUMN; column++) + AddLed(LedId.Keypad1 + ((row * _Defines.KEYPAD_MAX_COLUMN) + column), new Point(column * 19, row * 19), new Size(19, 19)); + } + + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Keypad1; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDeviceInfo.cs b/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDeviceInfo.cs deleted file mode 100644 index 8fc0d4de..00000000 --- a/RGB.NET.Devices.Razer/Keypad/RazerKeypadRGBDeviceInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Razer -{ - /// - /// - /// Represents a generic information for a . - /// - public class RazerKeypadRGBDeviceInfo : RazerRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The Id of the . - /// The model of the . - internal RazerKeypadRGBDeviceInfo(Guid deviceId, string model) - : base(deviceId, RGBDeviceType.Keypad, model) - { } - - #endregion - } -} diff --git a/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs b/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs index 2efd7578..2b6dcc6d 100644 --- a/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Keypad/RazerKeypadUpdateQueue.cs @@ -1,47 +1,47 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// Represents the update-queue performing updates for razer keypad devices. +/// +public class RazerKeypadUpdateQueue : RazerUpdateQueue { + #region Constructors + /// - /// Represents the update-queue performing updates for razer keypad devices. + /// Initializes a new instance of the class. /// - public class RazerKeypadUpdateQueue : RazerUpdateQueue - { - #region Constructors + /// The update trigger used to update this queue. + public RazerKeypadUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { } - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used to update this queue. - /// The id of the device updated by this queue. - public RazerKeypadUpdateQueue(IDeviceUpdateTrigger updateTrigger, Guid deviceId) - : base(updateTrigger, deviceId) - { } + #endregion - #endregion + #region Methods - #region Methods + /// + protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet) + { + _Color[] colors = new _Color[_Defines.KEYPAD_MAX_LEDS]; - /// - protected override IntPtr CreateEffectParams(Dictionary dataSet) - { - _Color[] colors = new _Color[_Defines.KEYPAD_MAX_LEDS]; + foreach ((object key, Color color) in dataSet) + colors[(int)key] = new _Color(color); - foreach (KeyValuePair data in dataSet) - colors[(int)data.Key] = new _Color(data.Value); + _KeypadCustomEffect effectParams = new() { Color = colors }; - _KeypadCustomEffect effectParams = new _KeypadCustomEffect { Color = colors }; + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); + Marshal.StructureToPtr(effectParams, ptr, false); - IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); - Marshal.StructureToPtr(effectParams, ptr, false); + return ptr; + } - return ptr; - } + /// + protected override void CreateEffect(IntPtr effectParams, ref Guid effectId) => _RazerSDK.CreateKeypadEffect(_Defines.KEYPAD_EFFECT_ID, effectParams, ref effectId); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs b/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs index 65624670..14334493 100644 --- a/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDevice.cs @@ -4,49 +4,51 @@ using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// +/// Represents a razer mouse. +/// +public class RazerMouseRGBDevice : RazerRGBDevice, IMouse { - /// + #region Properties & Fields + + private readonly LedMapping _ledMapping; + + #endregion + + #region Constructors + + /// /// - /// Represents a razer mouse. + /// Initializes a new instance of the class. /// - public class RazerMouseRGBDevice : RazerRGBDevice, IMouse + /// The specific information provided by CUE for the mouse. + /// The update trigger used to update this device. + /// A mapping of leds this device is initialized with. + internal RazerMouseRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger, LedMapping ledMapping) + : base(info, new RazerMouseUpdateQueue(updateTrigger)) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the mouse. - internal RazerMouseRGBDevice(RazerMouseRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\Mice", $"{model}.xml"), null); - - if (LedMapping.Count == 0) - { - for (int i = 0; i < _Defines.MOUSE_MAX_ROW; i++) - for (int j = 0; j < _Defines.MOUSE_MAX_COLUMN; j++) - InitializeLed(LedId.Mouse1 + ((i * _Defines.MOUSE_MAX_COLUMN) + j), new Rectangle(j * 11, i * 11, 10, 10)); - } - } - - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mouse1; - - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMouseUpdateQueue(updateTrigger, DeviceInfo.DeviceId); - - #endregion + this._ledMapping = ledMapping; + + InitializeLayout(); } -} + + #endregion + + #region Methods + + private void InitializeLayout() + { + for (int row = 0; row < _Defines.MOUSE_MAX_ROW; row++) + for (int column = 0; column < _Defines.MOUSE_MAX_COLUMN; column++) + if (_ledMapping.TryGetValue((row * _Defines.MOUSE_MAX_COLUMN) + column, out LedId ledId)) + AddLed(ledId, new Point(column * 10, row * 10), new Size(10, 10)); + } + + /// + protected override object GetLedCustomData(LedId ledId) => _ledMapping[ledId]; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDeviceInfo.cs b/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDeviceInfo.cs deleted file mode 100644 index c6d119cd..00000000 --- a/RGB.NET.Devices.Razer/Mouse/RazerMouseRGBDeviceInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Razer -{ - /// - /// - /// Represents a generic information for a . - /// - public class RazerMouseRGBDeviceInfo : RazerRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The Id of the . - /// The model of the . - internal RazerMouseRGBDeviceInfo(Guid deviceId, string model) - : base(deviceId, RGBDeviceType.Mouse, model) - { } - - #endregion - } -} diff --git a/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs b/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs index f1b039d1..5a50911e 100644 --- a/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Mouse/RazerMouseUpdateQueue.cs @@ -1,47 +1,48 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// Represents the update-queue performing updates for razer mouse devices. +/// +public class RazerMouseUpdateQueue : RazerUpdateQueue { + #region Constructors + /// - /// Represents the update-queue performing updates for razer mouse devices. + /// Initializes a new instance of the class. /// - public class RazerMouseUpdateQueue : RazerUpdateQueue - { - #region Constructors + /// The update trigger used to update this queue. + public RazerMouseUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { } - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used to update this queue. - /// The id of the device updated by this queue. - public RazerMouseUpdateQueue(IDeviceUpdateTrigger updateTrigger, Guid deviceId) - : base(updateTrigger, deviceId) - { } + #endregion - #endregion + #region Methods - #region Methods + /// + protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet) + { + _Color[] colors = new _Color[_Defines.MOUSE_MAX_LEDS]; - /// - protected override IntPtr CreateEffectParams(Dictionary dataSet) - { - _Color[] colors = new _Color[_Defines.MOUSE_MAX_LEDS]; + foreach ((object key, Color color) in dataSet) + colors[(int)key] = new _Color(color); - foreach (KeyValuePair data in dataSet) - colors[(int)data.Key] = new _Color(data.Value); + _MouseCustomEffect effectParams = new() { Color = colors }; - _MouseCustomEffect effectParams = new _MouseCustomEffect { Color = colors }; + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); + Marshal.StructureToPtr(effectParams, ptr, false); - IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); - Marshal.StructureToPtr(effectParams, ptr, false); + return ptr; + } - return ptr; - } - #endregion - } -} + /// + protected override void CreateEffect(IntPtr effectParams, ref Guid effectId) => _RazerSDK.CreateMouseEffect(_Defines.MOUSE_EFFECT_ID, effectParams, ref effectId); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs index d9c4d810..af47df3a 100644 --- a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs +++ b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDevice.cs @@ -4,46 +4,39 @@ using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// +/// Represents a razer mousepad. +/// +public class RazerMousepadRGBDevice : RazerRGBDevice, IMousepad { - /// + #region Constructors + + /// /// - /// Represents a razer mousepad. + /// Initializes a new instance of the class. /// - public class RazerMousepadRGBDevice : RazerRGBDevice, IMousepad + /// The specific information provided by CUE for the mousepad. + /// The update trigger used to update this device. + internal RazerMousepadRGBDevice(RazerRGBDeviceInfo info, IDeviceUpdateTrigger updateTrigger) + : base(info, new RazerMousepadUpdateQueue(updateTrigger)) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by CUE for the mousepad. - internal RazerMousepadRGBDevice(RazerMousepadRGBDeviceInfo info) - : base(info) - { } - - #endregion - - #region Methods - - /// - protected override void InitializeLayout() - { - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\Razer\Mousepad", $"{model}.xml"), null); - - if (LedMapping.Count == 0) - for (int i = 0; i < _Defines.MOUSEPAD_MAX_LEDS; i++) - InitializeLed(LedId.Mousepad1 + i, new Rectangle(i * 11, 0, 10, 10)); - } + InitializeLayout(); + } - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mousepad1; + #endregion - /// - protected override RazerUpdateQueue CreateUpdateQueue(IDeviceUpdateTrigger updateTrigger) => new RazerMousepadUpdateQueue(updateTrigger, DeviceInfo.DeviceId); + #region Methods - #endregion + private void InitializeLayout() + { + for (int i = 0; i < _Defines.MOUSEPAD_MAX_LEDS; i++) + AddLed(LedId.Mousepad1 + i, new Point(i * 10, 0), new Size(10, 10)); } -} + + /// + protected override object? GetLedCustomData(LedId ledId) => (int)ledId - (int)LedId.Mousepad1; + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDeviceInfo.cs b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDeviceInfo.cs deleted file mode 100644 index eef2aaed..00000000 --- a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadRGBDeviceInfo.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Razer -{ - /// - /// - /// Represents a generic information for a . - /// - public class RazerMousepadRGBDeviceInfo : RazerRGBDeviceInfo - { - #region Constructors - - /// - /// - /// Internal constructor of managed . - /// - /// The Id of the . - /// The model of the . - internal RazerMousepadRGBDeviceInfo(Guid deviceId, string model) - : base(deviceId, RGBDeviceType.Mousepad, model) - { } - - #endregion - } -} diff --git a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs index 6e811178..3b01b672 100644 --- a/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs +++ b/RGB.NET.Devices.Razer/Mousepad/RazerMousepadUpdateQueue.cs @@ -1,47 +1,47 @@ using System; -using System.Collections.Generic; using System.Runtime.InteropServices; using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// Represents the update-queue performing updates for razer mousepad devices. +/// +public class RazerMousepadUpdateQueue : RazerUpdateQueue { + #region Constructors + /// - /// Represents the update-queue performing updates for razer mousepad devices. + /// Initializes a new instance of the class. /// - public class RazerMousepadUpdateQueue : RazerUpdateQueue - { - #region Constructors + /// The update trigger used to update this queue. + public RazerMousepadUpdateQueue(IDeviceUpdateTrigger updateTrigger) + : base(updateTrigger) + { } - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used to update this queue. - /// The id of the device updated by this queue. - public RazerMousepadUpdateQueue(IDeviceUpdateTrigger updateTrigger, Guid deviceId) - : base(updateTrigger, deviceId) - { } + #endregion - #endregion + #region Methods - #region Methods + /// + protected override IntPtr CreateEffectParams(in ReadOnlySpan<(object key, Color color)> dataSet) + { + _Color[] colors = new _Color[_Defines.MOUSEPAD_MAX_LEDS]; - /// - protected override IntPtr CreateEffectParams(Dictionary dataSet) - { - _Color[] colors = new _Color[_Defines.MOUSEPAD_MAX_LEDS]; + foreach ((object key, Color color) in dataSet) + colors[(int)key] = new _Color(color); - foreach (KeyValuePair data in dataSet) - colors[(int)data.Key] = new _Color(data.Value); + _MousepadCustomEffect effectParams = new() { Color = colors }; - _MousepadCustomEffect effectParams = new _MousepadCustomEffect { Color = colors }; + IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); + Marshal.StructureToPtr(effectParams, ptr, false); - IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(effectParams)); - Marshal.StructureToPtr(effectParams, ptr, false); + return ptr; + } - return ptr; - } + /// + protected override void CreateEffect(IntPtr effectParams, ref Guid effectId) => _RazerSDK.CreateMousepadEffect(_Defines.MOUSEPAD_EFFECT_ID, effectParams, ref effectId); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_ChromaLinkCustomEffect.cs b/RGB.NET.Devices.Razer/Native/_ChromaLinkCustomEffect.cs index 267dbe03..6a9116d1 100644 --- a/RGB.NET.Devices.Razer/Native/_ChromaLinkCustomEffect.cs +++ b/RGB.NET.Devices.Razer/Native/_ChromaLinkCustomEffect.cs @@ -1,11 +1,13 @@ -using System.Runtime.InteropServices; +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable InconsistentNaming -namespace RGB.NET.Devices.Razer.Native +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Razer.Native; + +[StructLayout(LayoutKind.Sequential)] +internal struct _ChromaLinkCustomEffect { - [StructLayout(LayoutKind.Sequential)] - internal struct _ChromaLinkCustomEffect - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.CHROMALINK_MAX_LEDS)] - public _Color[] Color; - } -} + [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.CHROMALINK_MAX_LEDS)] + public _Color[] Color; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_Color.cs b/RGB.NET.Devices.Razer/Native/_Color.cs index a36cc788..6b792a04 100644 --- a/RGB.NET.Devices.Razer/Native/_Color.cs +++ b/RGB.NET.Devices.Razer/Native/_Color.cs @@ -6,29 +6,28 @@ using System.Runtime.InteropServices; using RGB.NET.Core; -namespace RGB.NET.Devices.Razer.Native -{ - // ReSharper disable once InconsistentNaming - [StructLayout(LayoutKind.Sequential, Size = sizeof(uint))] - internal struct _Color - { - #region Properties & Fields +namespace RGB.NET.Devices.Razer.Native; - public uint Color; +// ReSharper disable once InconsistentNaming +[StructLayout(LayoutKind.Sequential, Size = sizeof(uint))] +internal struct _Color +{ + #region Properties & Fields - #endregion + public uint Color; - #region Constructors + #endregion - public _Color(Color color) - : this(color.GetR(), color.GetG(), color.GetB()) { } + #region Constructors - public _Color(byte red, byte green, byte blue) - : this() - { - Color = red + ((uint)green << 8) + ((uint)blue << 16); - } + public _Color(Color color) + : this(color.GetR(), color.GetG(), color.GetB()) { } - #endregion + public _Color(byte red, byte green, byte blue) + : this() + { + Color = red + ((uint)green << 8) + ((uint)blue << 16); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_Defines.cs b/RGB.NET.Devices.Razer/Native/_Defines.cs index 17d5167e..ddfa863b 100644 --- a/RGB.NET.Devices.Razer/Native/_Defines.cs +++ b/RGB.NET.Devices.Razer/Native/_Defines.cs @@ -1,27 +1,33 @@ -namespace RGB.NET.Devices.Razer.Native +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable InconsistentNaming + +namespace RGB.NET.Devices.Razer.Native; + +internal static class _Defines { - internal static class _Defines - { - internal const int EFFECT_ID = 7; - internal const int HEADSET_EFFECT_ID = 4; - internal const int CHROMALINK_EFFECT_ID = 1; + internal const int EFFECT_ID = 7; + internal const int HEADSET_EFFECT_ID = 4; + internal const int CHROMALINK_EFFECT_ID = 1; + internal const int KEYBOARD_EFFECT_ID = 9; + internal const int MOUSEPAD_EFFECT_ID = 6; + internal const int MOUSE_EFFECT_ID = 8; + internal const int KEYPAD_EFFECT_ID = 2; - internal const int KEYBOARD_MAX_ROW = 6; - internal const int KEYBOARD_MAX_COLUMN = 22; - internal const int KEYBOARD_MAX_LEDS = KEYBOARD_MAX_ROW * KEYBOARD_MAX_COLUMN; + internal const int KEYBOARD_MAX_ROW = 8; + internal const int KEYBOARD_MAX_COLUMN = 24; + internal const int KEYBOARD_MAX_LEDS = KEYBOARD_MAX_ROW * KEYBOARD_MAX_COLUMN; - internal const int MOUSE_MAX_ROW = 9; - internal const int MOUSE_MAX_COLUMN = 7; - internal const int MOUSE_MAX_LEDS = KEYBOARD_MAX_ROW * KEYBOARD_MAX_COLUMN; + internal const int MOUSE_MAX_ROW = 9; + internal const int MOUSE_MAX_COLUMN = 7; + internal const int MOUSE_MAX_LEDS = MOUSE_MAX_ROW * MOUSE_MAX_COLUMN; - internal const int HEADSET_MAX_LEDS = 5; + internal const int HEADSET_MAX_LEDS = 5; - internal const int MOUSEPAD_MAX_LEDS = 15; + internal const int MOUSEPAD_MAX_LEDS = 20; - internal const int KEYPAD_MAX_ROW = 4; - internal const int KEYPAD_MAX_COLUMN = 5; - internal const int KEYPAD_MAX_LEDS = KEYPAD_MAX_ROW * KEYPAD_MAX_COLUMN; + internal const int KEYPAD_MAX_ROW = 4; + internal const int KEYPAD_MAX_COLUMN = 5; + internal const int KEYPAD_MAX_LEDS = KEYPAD_MAX_ROW * KEYPAD_MAX_COLUMN; - internal const int CHROMALINK_MAX_LEDS = 5; - } -} + internal const int CHROMALINK_MAX_LEDS = 5; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_DeviceInfo.cs b/RGB.NET.Devices.Razer/Native/_DeviceInfo.cs index 0b465c3f..d580e25d 100644 --- a/RGB.NET.Devices.Razer/Native/_DeviceInfo.cs +++ b/RGB.NET.Devices.Razer/Native/_DeviceInfo.cs @@ -5,23 +5,22 @@ using System.Runtime.InteropServices; -namespace RGB.NET.Devices.Razer.Native +namespace RGB.NET.Devices.Razer.Native; + +// ReSharper disable once InconsistentNaming +/// +/// Razer-SDK: Device info. +/// +[StructLayout(LayoutKind.Sequential)] +internal struct _DeviceInfo { - // ReSharper disable once InconsistentNaming /// - /// Razer-SDK: Device info. + /// Razer-SDK: Device types. /// - [StructLayout(LayoutKind.Sequential)] - internal struct _DeviceInfo - { - /// - /// Razer-SDK: Device types. - /// - internal DeviceType Type; + internal DeviceType Type; - /// - /// Razer-SDK: Number of devices connected. - /// - internal int Connected; - } -} + /// + /// Razer-SDK: Number of devices connected. + /// + internal int Connected; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_HeadsetCustomEffect.cs b/RGB.NET.Devices.Razer/Native/_HeadsetCustomEffect.cs index d3bcdb3c..b6341b9b 100644 --- a/RGB.NET.Devices.Razer/Native/_HeadsetCustomEffect.cs +++ b/RGB.NET.Devices.Razer/Native/_HeadsetCustomEffect.cs @@ -1,11 +1,13 @@ -using System.Runtime.InteropServices; +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable InconsistentNaming -namespace RGB.NET.Devices.Razer.Native +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Razer.Native; + +[StructLayout(LayoutKind.Sequential)] +internal struct _HeadsetCustomEffect { - [StructLayout(LayoutKind.Sequential)] - internal struct _HeadsetCustomEffect - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.HEADSET_MAX_LEDS)] - public _Color[] Color; - } -} + [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.HEADSET_MAX_LEDS)] + public _Color[] Color; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_KeyboardCustomEffect.cs b/RGB.NET.Devices.Razer/Native/_KeyboardCustomEffect.cs index 5e9294f5..32fa4e07 100644 --- a/RGB.NET.Devices.Razer/Native/_KeyboardCustomEffect.cs +++ b/RGB.NET.Devices.Razer/Native/_KeyboardCustomEffect.cs @@ -1,11 +1,18 @@ -using System.Runtime.InteropServices; +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable InconsistentNaming -namespace RGB.NET.Devices.Razer.Native +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Razer.Native; + +[StructLayout(LayoutKind.Sequential)] +internal struct _KeyboardCustomEffect { - [StructLayout(LayoutKind.Sequential)] - internal struct _KeyboardCustomEffect - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.KEYBOARD_MAX_LEDS)] - public _Color[] Color; - } -} + [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.KEYBOARD_MAX_LEDS)] + public _Color[] Color; + + //diogotr7: I don't know what these "keys" mean, they were introduced in the Keyboard::v2 + //namespace. we need to put them here to give razer the struct size it expects + [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.KEYBOARD_MAX_LEDS)] + public uint[] Key; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_KeypadCustomEffect.cs b/RGB.NET.Devices.Razer/Native/_KeypadCustomEffect.cs index a08a1755..1c22143d 100644 --- a/RGB.NET.Devices.Razer/Native/_KeypadCustomEffect.cs +++ b/RGB.NET.Devices.Razer/Native/_KeypadCustomEffect.cs @@ -1,11 +1,13 @@ -using System.Runtime.InteropServices; +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable InconsistentNaming -namespace RGB.NET.Devices.Razer.Native +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Razer.Native; + +[StructLayout(LayoutKind.Sequential)] +internal struct _KeypadCustomEffect { - [StructLayout(LayoutKind.Sequential)] - internal struct _KeypadCustomEffect - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.KEYPAD_MAX_LEDS)] - public _Color[] Color; - } -} + [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.KEYPAD_MAX_LEDS)] + public _Color[] Color; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_MouseCustomEffect.cs b/RGB.NET.Devices.Razer/Native/_MouseCustomEffect.cs index a5e15990..5bd342bc 100644 --- a/RGB.NET.Devices.Razer/Native/_MouseCustomEffect.cs +++ b/RGB.NET.Devices.Razer/Native/_MouseCustomEffect.cs @@ -1,11 +1,13 @@ -using System.Runtime.InteropServices; +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable InconsistentNaming -namespace RGB.NET.Devices.Razer.Native +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Razer.Native; + +[StructLayout(LayoutKind.Sequential)] +internal struct _MouseCustomEffect { - [StructLayout(LayoutKind.Sequential)] - internal struct _MouseCustomEffect - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.MOUSE_MAX_LEDS)] - public _Color[] Color; - } -} + [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.MOUSE_MAX_LEDS)] + public _Color[] Color; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_MousepadCustomEffect.cs b/RGB.NET.Devices.Razer/Native/_MousepadCustomEffect.cs index 01368bf7..e29008c3 100644 --- a/RGB.NET.Devices.Razer/Native/_MousepadCustomEffect.cs +++ b/RGB.NET.Devices.Razer/Native/_MousepadCustomEffect.cs @@ -1,11 +1,13 @@ -using System.Runtime.InteropServices; +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable InconsistentNaming -namespace RGB.NET.Devices.Razer.Native +using System.Runtime.InteropServices; + +namespace RGB.NET.Devices.Razer.Native; + +[StructLayout(LayoutKind.Sequential)] +internal struct _MousepadCustomEffect { - [StructLayout(LayoutKind.Sequential)] - internal struct _MousepadCustomEffect - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.MOUSEPAD_MAX_LEDS)] - public _Color[] Color; - } -} + [MarshalAs(UnmanagedType.ByValArray, SizeConst = _Defines.MOUSEPAD_MAX_LEDS)] + public _Color[] Color; +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/Native/_RazerSDK.cs b/RGB.NET.Devices.Razer/Native/_RazerSDK.cs index 48021964..a94143db 100644 --- a/RGB.NET.Devices.Razer/Native/_RazerSDK.cs +++ b/RGB.NET.Devices.Razer/Native/_RazerSDK.cs @@ -1,4 +1,5 @@ -// ReSharper disable UnusedMethodReturnValue.Global +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable UnusedMethodReturnValue.Global // ReSharper disable UnusedMember.Global using System; @@ -8,153 +9,167 @@ using System.Runtime.InteropServices; using RGB.NET.Core; -namespace RGB.NET.Devices.Razer.Native -{ - // ReSharper disable once InconsistentNaming - internal static class _RazerSDK - { - #region Libary Management - - private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - - /// - /// Reloads the SDK. - /// - internal static void Reload() - { - UnloadRazerSDK(); - LoadRazerSDK(); - } - - private static void LoadRazerSDK() - { - if (_dllHandle != IntPtr.Zero) return; - - // HACK: Load library at runtime to support both, x86 and x64 with one managed dll - List possiblePathList = Environment.Is64BitProcess ? RazerDeviceProvider.PossibleX64NativePaths : RazerDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); - if (dllPath == null) throw new RGBDeviceException($"Can't find the Razer-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - - _dllHandle = LoadLibrary(dllPath); - - _initPointer = (InitPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "Init"), typeof(InitPointer)); - _unInitPointer = (UnInitPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "UnInit"), typeof(UnInitPointer)); - _queryDevicePointer = (QueryDevicePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "QueryDevice"), typeof(QueryDevicePointer)); - _createEffectPointer = (CreateEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateEffect"), typeof(CreateEffectPointer)); - _createHeadsetEffectPointer = (CreateHeadsetEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateHeadsetEffect"), typeof(CreateHeadsetEffectPointer)); - _createChromaLinkEffectPointer = (CreateChromaLinkEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "CreateChromaLinkEffect"), typeof(CreateChromaLinkEffectPointer)); - _setEffectPointer = (SetEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "SetEffect"), typeof(SetEffectPointer)); - _deleteEffectPointer = (DeleteEffectPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "DeleteEffect"), typeof(DeleteEffectPointer)); - } - - internal static void UnloadRazerSDK() - { - if (_dllHandle == IntPtr.Zero) return; - - // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 09.11.2017: We might need to reduce the internal reference counter more than once to set the library free - while (FreeLibrary(_dllHandle)) ; - _dllHandle = IntPtr.Zero; - } - - [DllImport("kernel32.dll")] - private static extern IntPtr LoadLibrary(string dllToLoad); - - [DllImport("kernel32.dll")] - private static extern bool FreeLibrary(IntPtr dllHandle); - - [DllImport("kernel32.dll")] - private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); - - #endregion - - #region SDK-METHODS - - #region Pointers +namespace RGB.NET.Devices.Razer.Native; - private static InitPointer _initPointer; - private static UnInitPointer _unInitPointer; - private static QueryDevicePointer _queryDevicePointer; - private static CreateEffectPointer _createEffectPointer; - private static CreateHeadsetEffectPointer _createHeadsetEffectPointer; - private static CreateChromaLinkEffectPointer _createChromaLinkEffectPointer; - private static SetEffectPointer _setEffectPointer; - private static DeleteEffectPointer _deleteEffectPointer; - - #endregion - - #region Delegates - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate RazerError InitPointer(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate RazerError UnInitPointer(); +// ReSharper disable once InconsistentNaming +internal static class _RazerSDK +{ + #region Libary Management - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate RazerError QueryDevicePointer(Guid deviceId, IntPtr deviceInfo); + private static IntPtr _handle = IntPtr.Zero; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate RazerError CreateEffectPointer(Guid deviceId, int effectType, IntPtr param, ref Guid effectId); + /// + /// Reloads the SDK. + /// + internal static void Reload() + { + UnloadRazerSDK(); + LoadRazerSDK(); + } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate RazerError CreateHeadsetEffectPointer(int effectType, IntPtr param, ref Guid effectId); + private static void LoadRazerSDK() + { + if (_handle != IntPtr.Zero) return; + + List possiblePathList = GetPossibleLibraryPaths().ToList(); + + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); + if (dllPath == null) throw new RGBDeviceException($"Can't find the Razer-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); + + if (!NativeLibrary.TryLoad(dllPath, out _handle)) +#if NET6_0 + throw new RGBDeviceException($"Razer LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}"); +#else + throw new RGBDeviceException($"Razer LoadLibrary failed with error code {Marshal.GetLastWin32Error()}"); +#endif + + if (!NativeLibrary.TryGetExport(_handle, "Init", out _initPointer)) throw new RGBDeviceException("Failed to load Razer function 'Init'"); + if (!NativeLibrary.TryGetExport(_handle, "UnInit", out _unInitPointer)) throw new RGBDeviceException("Failed to load Razer function 'UnInit'"); + if (!NativeLibrary.TryGetExport(_handle, "QueryDevice", out _queryDevicePointer)) throw new RGBDeviceException("Failed to load Razer function 'QueryDevice'"); + if (!NativeLibrary.TryGetExport(_handle, "CreateEffect", out _createEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateEffect'"); + if (!NativeLibrary.TryGetExport(_handle, "CreateHeadsetEffect", out _createHeadsetEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateHeadsetEffect'"); + if (!NativeLibrary.TryGetExport(_handle, "CreateChromaLinkEffect", out _createChromaLinkEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateChromaLinkEffect'"); + if (!NativeLibrary.TryGetExport(_handle, "CreateKeyboardEffect", out _createKeyboardEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateKeyboardEffect'"); + if (!NativeLibrary.TryGetExport(_handle, "CreateKeypadEffect", out _createKeypadEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateKeypadEffect'"); + if (!NativeLibrary.TryGetExport(_handle, "CreateMouseEffect", out _createMouseEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateMouseEffect'"); + if (!NativeLibrary.TryGetExport(_handle, "CreateMousepadEffect", out _createMousepadEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'CreateMousepadEffect'"); + if (!NativeLibrary.TryGetExport(_handle, "SetEffect", out _setEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'SetEffect'"); + if (!NativeLibrary.TryGetExport(_handle, "DeleteEffect", out _deleteEffectPointer)) throw new RGBDeviceException("Failed to load Razer function 'DeleteEffect'"); + } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate RazerError CreateChromaLinkEffectPointer(int effectType, IntPtr param, ref Guid effectId); + private static IEnumerable GetPossibleLibraryPaths() + { + IEnumerable possibleLibraryPaths; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate RazerError SetEffectPointer(Guid effectId); + if (OperatingSystem.IsWindows()) + possibleLibraryPaths = Environment.Is64BitProcess ? RazerDeviceProvider.PossibleX64NativePaths : RazerDeviceProvider.PossibleX86NativePaths; + else + possibleLibraryPaths = Enumerable.Empty(); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate RazerError DeleteEffectPointer(Guid effectId); + return possibleLibraryPaths.Select(Environment.ExpandEnvironmentVariables); + } - #endregion + internal static void UnloadRazerSDK() + { + if (_handle == IntPtr.Zero) return; + + _initPointer = IntPtr.Zero; + _unInitPointer = IntPtr.Zero; + _queryDevicePointer = IntPtr.Zero; + _createEffectPointer = IntPtr.Zero; + _createHeadsetEffectPointer = IntPtr.Zero; + _createChromaLinkEffectPointer = IntPtr.Zero; + _createKeyboardEffectPointer = IntPtr.Zero; + _createKeypadEffectPointer = IntPtr.Zero; + _createMouseEffectPointer = IntPtr.Zero; + _createMousepadEffectPointer = IntPtr.Zero; + _setEffectPointer = IntPtr.Zero; + _deleteEffectPointer = IntPtr.Zero; + + NativeLibrary.Free(_handle); + _handle = IntPtr.Zero; + } - // ReSharper disable EventExceptionNotDocumented + #endregion + + #region SDK-METHODS + + #region Pointers + + private static IntPtr _initPointer; + private static IntPtr _unInitPointer; + private static IntPtr _queryDevicePointer; + private static IntPtr _createEffectPointer; + private static IntPtr _createHeadsetEffectPointer; + private static IntPtr _createChromaLinkEffectPointer; + private static IntPtr _createKeyboardEffectPointer; + private static IntPtr _createKeypadEffectPointer; + private static IntPtr _createMouseEffectPointer; + private static IntPtr _createMousepadEffectPointer; + private static IntPtr _setEffectPointer; + private static IntPtr _deleteEffectPointer; + + #endregion + + /// + /// Razer-SDK: Initialize Chroma SDK. + /// + internal static unsafe RazerError Init() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_initPointer))(); + + /// + /// Razer-SDK: UnInitialize Chroma SDK. + /// + internal static unsafe RazerError UnInit() + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_unInitPointer))(); + + /// + /// Razer-SDK: Query for device information. + /// + internal static unsafe RazerError QueryDevice(Guid deviceId, out _DeviceInfo deviceInfo) + { + int structSize = Marshal.SizeOf(typeof(_DeviceInfo)); + IntPtr deviceInfoPtr = Marshal.AllocHGlobal(structSize); - /// - /// Razer-SDK: Initialize Chroma SDK. - /// - internal static RazerError Init() => _initPointer(); + RazerError error = ((delegate* unmanaged[Cdecl])ThrowIfZero(_queryDevicePointer))(deviceId, deviceInfoPtr); - /// - /// Razer-SDK: UnInitialize Chroma SDK. - /// - internal static RazerError UnInit() => _unInitPointer(); + deviceInfo = (_DeviceInfo)Marshal.PtrToStructure(deviceInfoPtr, typeof(_DeviceInfo))!; + Marshal.FreeHGlobal(deviceInfoPtr); - /// - /// Razer-SDK: Query for device information. - /// - internal static RazerError QueryDevice(Guid deviceId, out _DeviceInfo deviceInfo) - { - int structSize = Marshal.SizeOf(typeof(_DeviceInfo)); - IntPtr deviceInfoPtr = Marshal.AllocHGlobal(structSize); + return error; + } - RazerError error = _queryDevicePointer(deviceId, deviceInfoPtr); + internal static unsafe RazerError CreateEffect(Guid deviceId, int effectType, IntPtr param, ref Guid effectId) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_createEffectPointer))(deviceId, effectType, param, ref effectId); - deviceInfo = (_DeviceInfo)Marshal.PtrToStructure(deviceInfoPtr, typeof(_DeviceInfo)); - Marshal.FreeHGlobal(deviceInfoPtr); + internal static unsafe RazerError CreateHeadsetEffect(int effectType, IntPtr param, ref Guid effectId) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_createHeadsetEffectPointer))(effectType, param, ref effectId); - return error; - } + internal static unsafe RazerError CreateChromaLinkEffect(int effectType, IntPtr param, ref Guid effectId) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_createChromaLinkEffectPointer))(effectType, param, ref effectId); - internal static RazerError CreateEffect(Guid deviceId, int effectType, IntPtr param, ref Guid effectId) => _createEffectPointer(deviceId, effectType, param, ref effectId); + internal static unsafe RazerError CreateKeyboardEffect(int effectType, IntPtr param, ref Guid effectId) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_createKeyboardEffectPointer))(effectType, param, ref effectId); - internal static RazerError CreateHeadsetEffect(int effectType, IntPtr param, ref Guid effectId) => _createHeadsetEffectPointer(effectType, param, ref effectId); + internal static unsafe RazerError CreateKeypadEffect(int effectType, IntPtr param, ref Guid effectId) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_createKeypadEffectPointer))(effectType, param, ref effectId); - internal static RazerError CreateChromaLinkEffect(int effectType, IntPtr param, ref Guid effectId) => _createChromaLinkEffectPointer(effectType, param, ref effectId); + internal static unsafe RazerError CreateMouseEffect(int effectType, IntPtr param, ref Guid effectId) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_createMouseEffectPointer))(effectType, param, ref effectId); - internal static RazerError SetEffect(Guid effectId) => _setEffectPointer(effectId); + internal static unsafe RazerError CreateMousepadEffect(int effectType, IntPtr param, ref Guid effectId) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_createMousepadEffectPointer))(effectType, param, ref effectId); - internal static RazerError DeleteEffect(Guid effectId) => _deleteEffectPointer(effectId); + internal static unsafe RazerError SetEffect(Guid effectId) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_setEffectPointer))(effectId); - // ReSharper restore EventExceptionNotDocumented + internal static unsafe RazerError DeleteEffect(Guid effectId) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_deleteEffectPointer))(effectId); - #endregion + private static IntPtr ThrowIfZero(IntPtr ptr) + { + if (ptr == IntPtr.Zero) throw new RGBDeviceException("The Razer-SDK is not initialized."); + return ptr; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/README.md b/RGB.NET.Devices.Razer/README.md new file mode 100644 index 00000000..b18dd585 --- /dev/null +++ b/RGB.NET.Devices.Razer/README.md @@ -0,0 +1,14 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for Razer-Devices. + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(RazerDeviceProvider.Instance); +``` + +Since the Razer SDK does not provide device information only known devices will work. +You can add detection for additional devices by adding entires for them to the respective static `DeviceDefinitions` on the `RazerDeviceProvider`. + +# Required SDK +The SDK needs to be installed inside Synapse by the user and is not redistributed. diff --git a/RGB.NET.Devices.Razer/RGB.NET.Devices.Razer.csproj b/RGB.NET.Devices.Razer/RGB.NET.Devices.Razer.csproj index 7ed66a54..32fcbe04 100644 --- a/RGB.NET.Devices.Razer/RGB.NET.Devices.Razer.csproj +++ b/RGB.NET.Devices.Razer/RGB.NET.Devices.Razer.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.Razer Razer-Device-Implementations of RGB.NET Razer-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,36 +35,30 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg + true $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + - - + + + \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/RGB.NET.Devices.Razer.csproj.DotSettings b/RGB.NET.Devices.Razer/RGB.NET.Devices.Razer.csproj.DotSettings index 1e5aa14b..323fe521 100644 --- a/RGB.NET.Devices.Razer/RGB.NET.Devices.Razer.csproj.DotSettings +++ b/RGB.NET.Devices.Razer/RGB.NET.Devices.Razer.csproj.DotSettings @@ -8,4 +8,5 @@ True True True - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs index c49cfcbd..09f1a278 100644 --- a/RGB.NET.Devices.Razer/RazerDeviceProvider.cs +++ b/RGB.NET.Devices.Razer/RazerDeviceProvider.cs @@ -1,239 +1,307 @@ -// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable MemberCanBePrivate.Global // ReSharper disable UnusedMember.Global // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global using System; using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Globalization; using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.Razer.Native; +using RGB.NET.HID; -namespace RGB.NET.Devices.Razer +namespace RGB.NET.Devices.Razer; + +/// +/// +/// Represents a device provider responsible for razer devices. +/// +public class RazerDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static RazerDeviceProvider? _instance; + /// + /// Gets the singleton instance. + /// + public static RazerDeviceProvider Instance => _instance ?? new RazerDeviceProvider(); + + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. + /// The first match will be used. + /// + public static List PossibleX86NativePaths { get; } = new() { @"%systemroot%\SysWOW64\RzChromaSDK.dll" }; + + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. + /// The first match will be used. + /// + public static List PossibleX64NativePaths { get; } = new() { @"%systemroot%\System32\RzChromaSDK.dll", @"%systemroot%\System32\RzChromaSDK64.dll" }; + /// - /// Represents a device provider responsible for razer devices. + /// Forces to load the devices represented by the emulator even if they aren't reported to exist. /// - public class RazerDeviceProvider : IRGBDeviceProvider + public bool LoadEmulatorDevices { get; set; } = false; + + private const int VENDOR_ID = 0x1532; + + /// + /// Gets the HID-definitions for Razer-devices. + /// + public static HIDLoader DeviceDefinitions { get; } = new(VENDOR_ID) { - #region Properties & Fields - - private static RazerDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static RazerDeviceProvider Instance => _instance ?? new RazerDeviceProvider(); - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. - /// The first match will be used. - /// - public static List PossibleX86NativePaths { get; } = new List { "x86/RzChromaSDK.dll" }; - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. - /// The first match will be used. - /// - public static List PossibleX64NativePaths { get; } = new List { "x64/RzChromaSDK.dll", "x64/RzChromaSDK64.dll" }; - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _RazerSDK.LoadedArchitecture; - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess => false; - - /// - public IEnumerable Devices { get; private set; } - - /// - /// Gets or sets a function to get the culture for a specific device. - /// - public Func GetCulture { get; set; } = CultureHelper.GetCurrentCulture; - - /// - /// Forces to load the devices represented by the emulator even if they aren't reported to exist. - /// - public bool LoadEmulatorDevices { get; set; } = false; - - /// - /// The used to trigger the updates for razer devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public RazerDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(RazerDeviceProvider)}"); - _instance = this; + // Keyboards + { 0x010D, RGBDeviceType.Keyboard, "BlackWidow Ultimate 2012", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x010E, RGBDeviceType.Keyboard, "BlackWidow Classic (Alternate)", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x010F, RGBDeviceType.Keyboard, "Anansi", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x011A, RGBDeviceType.Keyboard, "BlackWidow Ultimate 2013", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x011B, RGBDeviceType.Keyboard, "BlackWidow Stealth", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0202, RGBDeviceType.Keyboard, "DeathStalker Expert", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0203, RGBDeviceType.Keyboard, "BlackWidow Chroma", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0204, RGBDeviceType.Keyboard, "DeathStalker Chroma", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0205, RGBDeviceType.Keyboard, "Blade Stealth", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0209, RGBDeviceType.Keyboard, "BlackWidow Tournament Edition Chroma", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x020F, RGBDeviceType.Keyboard, "Blade QHD", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0210, RGBDeviceType.Keyboard, "Blade Pro (Late 2016)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0211, RGBDeviceType.Keyboard, "BlackWidow Chroma (Overwatch)", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0214, RGBDeviceType.Keyboard, "BlackWidow Ultimate 2016", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0216, RGBDeviceType.Keyboard, "BlackWidow X Chroma", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0217, RGBDeviceType.Keyboard, "BlackWidow X Ultimate", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x021A, RGBDeviceType.Keyboard, "BlackWidow X Tournament Edition Chroma", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x021E, RGBDeviceType.Keyboard, "Ornata Chroma", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x021F, RGBDeviceType.Keyboard, "Ornata", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0220, RGBDeviceType.Keyboard, "Blade Stealth (Late 2016)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0221, RGBDeviceType.Keyboard, "BlackWidow Chroma V2", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0224, RGBDeviceType.Keyboard, "Blade (Late 2016)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0225, RGBDeviceType.Keyboard, "Blade Pro (2017)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0226, RGBDeviceType.Keyboard, "Huntsman Elite", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0227, RGBDeviceType.Keyboard, "Huntsman", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0228, RGBDeviceType.Keyboard, "BlackWidow Elite", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x022A, RGBDeviceType.Keyboard, "Cynosa Chroma", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x022D, RGBDeviceType.Keyboard, "Blade Stealth (Mid 2017)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x022F, RGBDeviceType.Keyboard, "Blade Pro FullHD (2017)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0232, RGBDeviceType.Keyboard, "Blade Stealth (Late 2017)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0233, RGBDeviceType.Keyboard, "Blade 15 (2018)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0234, RGBDeviceType.Keyboard, "Blade Pro 17 (2019)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0235, RGBDeviceType.Keyboard, "BlackWidow Lite (2018)", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0237, RGBDeviceType.Keyboard, "BlackWidow Essential", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0239, RGBDeviceType.Keyboard, "Blade Stealth (2019)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x023A, RGBDeviceType.Keyboard, "Blade 15 (2019) Advanced", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x023B, RGBDeviceType.Keyboard, "Blade 15 (2018) Base Model", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x023F, RGBDeviceType.Keyboard, "Cynosa Lite", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0240, RGBDeviceType.Keyboard, "Blade 15 (2018) Mercury", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0241, RGBDeviceType.Keyboard, "BlackWidow (2019)", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0243, RGBDeviceType.Keyboard, "Huntsman Tournament Edition", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0245, RGBDeviceType.Keyboard, "Blade 15 (Mid 2019) Mercury", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0246, RGBDeviceType.Keyboard, "Blade 15 (Mid 2019) Base", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x024A, RGBDeviceType.Keyboard, "Blade Stealth (Late 2019)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x024C, RGBDeviceType.Keyboard, "Blade Pro (Late 2019)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x024D, RGBDeviceType.Keyboard, "Blade 15 Studio Edition (2019)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x024E, RGBDeviceType.Keyboard, "BlackWidow V3", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0252, RGBDeviceType.Keyboard, "Blade Stealth (Early 2020)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0253, RGBDeviceType.Keyboard, "Blade 15 Advanced (2020)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0255, RGBDeviceType.Keyboard, "Blade 15 (Early 2020) Base", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x0259, RGBDeviceType.Keyboard, "Blade Stealth (Late 2020)", LedMappings.Keyboard, RazerEndpointType.LaptopKeyboard }, + { 0x25A, RGBDeviceType.Keyboard, "BlackWidow V3 Pro", LedMappings.Keyboard, RazerEndpointType.Keyboard }, // The keyboard, only present when connected with cable + { 0x25C, RGBDeviceType.Keyboard, "BlackWidow V3 Pro", LedMappings.Keyboard, RazerEndpointType.Keyboard }, // The dongle, may not be present when connected with cable + { 0x025D, RGBDeviceType.Keyboard, "Ornata Chroma V2", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x025E, RGBDeviceType.Keyboard, "Cynosa V2", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x0266, RGBDeviceType.Keyboard, "Huntsman V2", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + { 0x026C, RGBDeviceType.Keyboard, "Huntsman V2", LedMappings.Keyboard, RazerEndpointType.Keyboard }, + + // Mice + { 0x0013, RGBDeviceType.Mouse, "Orochi 2011", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0016, RGBDeviceType.Mouse, "DeathAdder 3.5G", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0020, RGBDeviceType.Mouse, "Abyssus 1800", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0024, RGBDeviceType.Mouse, "Mamba 2012 (Wired)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0025, RGBDeviceType.Mouse, "Mamba 2012 (Wireless)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x002E, RGBDeviceType.Mouse, "Naga 2012", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x002F, RGBDeviceType.Mouse, "Imperator 2012", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0032, RGBDeviceType.Mouse, "Ouroboros 2012", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0034, RGBDeviceType.Mouse, "Taipan", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0036, RGBDeviceType.Mouse, "Naga Hex (Red)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0037, RGBDeviceType.Mouse, "DeathAdder 2013", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0038, RGBDeviceType.Mouse, "DeathAdder 1800", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0039, RGBDeviceType.Mouse, "Orochi 2013", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0040, RGBDeviceType.Mouse, "Naga 2014", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0041, RGBDeviceType.Mouse, "Naga Hex", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0042, RGBDeviceType.Mouse, "Abyssus 2014", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0043, RGBDeviceType.Mouse, "DeathAdder Chroma", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0044, RGBDeviceType.Mouse, "Mamba (Wired)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0045, RGBDeviceType.Mouse, "Mamba (Wireless)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0046, RGBDeviceType.Mouse, "Mamba Tournament Edition", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0048, RGBDeviceType.Mouse, "Orochi (Wired)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x004C, RGBDeviceType.Mouse, "Diamondback Chroma", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x004F, RGBDeviceType.Mouse, "DeathAdder 2000", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0050, RGBDeviceType.Mouse, "Naga Hex V2", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0053, RGBDeviceType.Mouse, "Naga Chroma", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0054, RGBDeviceType.Mouse, "DeathAdder 3500", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0059, RGBDeviceType.Mouse, "Lancehead (Wired)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x005A, RGBDeviceType.Mouse, "Lancehead (Wireless)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x005B, RGBDeviceType.Mouse, "Abyssus V2", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x005C, RGBDeviceType.Mouse, "DeathAdder Elite", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x005E, RGBDeviceType.Mouse, "Abyssus 2000", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0060, RGBDeviceType.Mouse, "Lancehead Tournament Edition", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0062, RGBDeviceType.Mouse, "Atheris (Receiver)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0064, RGBDeviceType.Mouse, "Basilisk", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0067, RGBDeviceType.Mouse, "Naga Trinity", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x006A, RGBDeviceType.Mouse, "Abyssus Elite (D.Va Edition)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x006B, RGBDeviceType.Mouse, "Abyssus Essential", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x006C, RGBDeviceType.Mouse, "Mamba Elite (Wired)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x006E, RGBDeviceType.Mouse, "DeathAdder Essential", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x006F, RGBDeviceType.Mouse, "Lancehead Wireless (Receiver)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0070, RGBDeviceType.Mouse, "Lancehead Wireless (Wired)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0071, RGBDeviceType.Mouse, "DeathAdder Essential (White Edition)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0072, RGBDeviceType.Mouse, "Mamba Wireless (Receiver)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0073, RGBDeviceType.Mouse, "Mamba Wireless (Wired)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0078, RGBDeviceType.Mouse, "Viper", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x007A, RGBDeviceType.Mouse, "Viper Ultimate (Wired)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x007B, RGBDeviceType.Mouse, "Viper Ultimate (Wireless)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x007C, RGBDeviceType.Mouse, "DeathAdder V2 Pro (Wired)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x007D, RGBDeviceType.Mouse, "DeathAdder V2 Pro (Wireless)", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0083, RGBDeviceType.Mouse, "Basilisk X HyperSpeed", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0085, RGBDeviceType.Mouse, "Basilisk V2", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0088, RGBDeviceType.Mouse, "Basilisk Ultimate", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0084, RGBDeviceType.Mouse, "DeathAdder V2", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x008A, RGBDeviceType.Mouse, "Viper Mini", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x008D, RGBDeviceType.Mouse, "Naga Left Handed Edition", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0091, RGBDeviceType.Mouse, "Viper 8khz", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0096, RGBDeviceType.Mouse, "Naga X", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x0099, RGBDeviceType.Mouse, "Basilisk v3", LedMappings.Mouse, RazerEndpointType.Mouse }, + { 0x00A8, RGBDeviceType.Mouse, "Naga V2 Pro", LedMappings.Mouse, RazerEndpointType.Mouse }, + + // Mousepads + { 0x0068, RGBDeviceType.Mousepad, "Firefly Hyperflux", LedMappings.Mousepad, RazerEndpointType.Mousepad }, + { 0x0C00, RGBDeviceType.Mousepad, "Firefly", LedMappings.Mousepad, RazerEndpointType.Mousepad }, + { 0x0C01, RGBDeviceType.Mousepad, "Goliathus", LedMappings.Mousepad, RazerEndpointType.ChromaLink }, + { 0x0C02, RGBDeviceType.Mousepad, "Goliathus Extended", LedMappings.Mousepad, RazerEndpointType.ChromaLink }, + { 0x0C04, RGBDeviceType.Mousepad, "Firefly v2", LedMappings.Mousepad, RazerEndpointType.Mousepad }, + + // Headsets + { 0x0501, RGBDeviceType.Headset, "Kraken 7.1", LedMappings.Headset, RazerEndpointType.Headset }, + { 0x0504, RGBDeviceType.Headset, "Kraken 7.1 Chroma", LedMappings.Headset, RazerEndpointType.Headset }, + { 0x0506, RGBDeviceType.Headset, "Kraken 7.1", LedMappings.Headset, RazerEndpointType.Headset }, + { 0x0510, RGBDeviceType.Headset, "Kraken 7.1 V2", LedMappings.Headset, RazerEndpointType.Headset }, + { 0x051A, RGBDeviceType.Headset, "Nari Ultimate", LedMappings.Headset, RazerEndpointType.Headset }, + { 0x0527, RGBDeviceType.Headset, "Kraken Ultimate", LedMappings.Headset, RazerEndpointType.Headset }, + { 0x0F19, RGBDeviceType.Headset, "Kraken Kitty Edition", LedMappings.Headset, RazerEndpointType.Headset }, + + // Keypads + { 0x0111, RGBDeviceType.Keypad, "Nostromo", LedMappings.Keypad, RazerEndpointType.Keypad }, + { 0x0113, RGBDeviceType.Keypad, "Orbweaver", LedMappings.Keypad, RazerEndpointType.Keypad }, + { 0x0201, RGBDeviceType.Keypad, "Tartarus", LedMappings.Keypad, RazerEndpointType.Keypad }, + { 0x0207, RGBDeviceType.Keypad, "Orbweaver Chroma", LedMappings.Keypad, RazerEndpointType.Keypad }, + { 0x0208, RGBDeviceType.Keypad, "Tartarus Chroma", LedMappings.Keypad, RazerEndpointType.Keypad }, + { 0x022B, RGBDeviceType.Keypad, "Tartarus V2", LedMappings.Keypad, RazerEndpointType.Keypad }, + { 0x0244, RGBDeviceType.Keypad, "Tartarus Pro", LedMappings.Keypad, RazerEndpointType.Keypad }, + + // Misc - guessing these are through ChromaLink + { 0x0215, RGBDeviceType.GraphicsCard, "Core", LedMappings.ChromaLink, RazerEndpointType.ChromaLink }, + { 0x0F08, RGBDeviceType.HeadsetStand, "Base Station Chroma", LedMappings.Mousepad, RazerEndpointType.Mousepad }, // DarthAffe 16.12.2022: Not tested but based on the V2 I assume this is also a mousepad + { 0x0F20, RGBDeviceType.HeadsetStand, "Base Station V2 Chroma", LedMappings.Mousepad, RazerEndpointType.Mousepad }, // DarthAffe 16.12.2022: Not sure why, but it's handled as a mousepad + { 0x0517, RGBDeviceType.Speaker, "Nommo Chroma", LedMappings.ChromaLink, RazerEndpointType.ChromaLink }, + { 0x0518, RGBDeviceType.Speaker, "Nommo Pro", LedMappings.ChromaLink, RazerEndpointType.ChromaLink }, + { 0x0F07, RGBDeviceType.Unknown, "Chroma Mug Holder", LedMappings.ChromaLink, RazerEndpointType.ChromaLink }, + { 0x0F09, RGBDeviceType.Unknown, "Chroma Hardware Development Kit (HDK)", LedMappings.ChromaLink, RazerEndpointType.ChromaLink }, + { 0x0F13, RGBDeviceType.Unknown, "Lian Li O11", LedMappings.ChromaLink, RazerEndpointType.ChromaLink }, + { 0x0F1D, RGBDeviceType.Unknown, "Mouse Bungee V3 Chroma", LedMappings.ChromaLink, RazerEndpointType.ChromaLink }, + { 0x0F1F, RGBDeviceType.Unknown, "Addressable RGB Controller", LedMappings.ChromaLink, RazerEndpointType.ChromaLink } + }; + + #endregion + + #region Constructors - UpdateTrigger = new DeviceUpdateTrigger(); - } + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public RazerDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(RazerDeviceProvider)}"); + _instance = this; + } - #endregion + #endregion - #region Methods + #region Methods - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - if (IsInitialized) - TryUnInit(); + /// + protected override void InitializeSDK() + { + TryUnInit(); - IsInitialized = false; + _RazerSDK.Reload(); - try - { - UpdateTrigger?.Stop(); - - _RazerSDK.Reload(); - - RazerError error; - if (((error = _RazerSDK.Init()) != RazerError.Success) - && Enum.IsDefined(typeof(RazerError), error)) //HACK DarthAffe 08.02.2018: The x86-SDK seems to have a problem here ... - ThrowRazerError(error); - - IList devices = new List(); - - if (loadFilter.HasFlag(RGBDeviceType.Keyboard)) - foreach ((Guid guid, string model) in Razer.Devices.KEYBOARDS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.KEYBOARDS.FirstOrDefault().guid != guid))) continue; - - RazerKeyboardRGBDevice device = new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo(guid, model, GetCulture())); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Mouse)) - foreach ((Guid guid, string model) in Razer.Devices.MICE) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.MICE.FirstOrDefault().guid != guid))) continue; - - RazerMouseRGBDevice device = new RazerMouseRGBDevice(new RazerMouseRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Headset)) - foreach ((Guid guid, string model) in Razer.Devices.HEADSETS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.HEADSETS.FirstOrDefault().guid != guid))) continue; - - RazerHeadsetRGBDevice device = new RazerHeadsetRGBDevice(new RazerHeadsetRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Mousepad)) - foreach ((Guid guid, string model) in Razer.Devices.MOUSEMATS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.MOUSEMATS.FirstOrDefault().guid != guid))) continue; - - RazerMousepadRGBDevice device = new RazerMousepadRGBDevice(new RazerMousepadRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Keypad)) - foreach ((Guid guid, string model) in Razer.Devices.KEYPADS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.KEYPADS.FirstOrDefault().guid != guid))) continue; - - RazerKeypadRGBDevice device = new RazerKeypadRGBDevice(new RazerKeypadRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - if (loadFilter.HasFlag(RGBDeviceType.Keyboard)) - foreach ((Guid guid, string model) in Razer.Devices.CHROMALINKS) - try - { - if (((_RazerSDK.QueryDevice(guid, out _DeviceInfo deviceInfo) != RazerError.Success) || (deviceInfo.Connected < 1)) - && (!LoadEmulatorDevices || (Razer.Devices.CHROMALINKS.FirstOrDefault().guid != guid))) continue; - - RazerChromaLinkRGBDevice device = new RazerChromaLinkRGBDevice(new RazerChromaLinkRGBDeviceInfo(guid, model)); - device.Initialize(UpdateTrigger); - devices.Add(device); - } - catch { if (throwExceptions) throw; } - - UpdateTrigger?.Start(); - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - TryUnInit(); - if (throwExceptions) throw; - return false; - } + RazerError error; + if (((error = _RazerSDK.Init()) != RazerError.Success) && Enum.IsDefined(typeof(RazerError), error)) //HACK DarthAffe 08.02.2018: The x86-SDK seems to have a problem here ... + ThrowRazerError(error, true); + } - return true; - } + /// + protected override IEnumerable GetLoadedDevices(RGBDeviceType loadFilter) + { + DeviceDefinitions.LoadFilter = loadFilter; + + IList devices = base.GetLoadedDevices(loadFilter).ToList(); - /// - public void ResetDevices() + if (LoadEmulatorDevices) { - foreach (IRGBDevice device in Devices) - ((IRazerRGBDevice)device).Reset(); + if (loadFilter.HasFlag(RGBDeviceType.Keyboard) && devices.All(d => d is not RazerKeyboardRGBDevice)) + devices.Add(new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo("Emulator Keyboard", RazerEndpointType.Keyboard), GetUpdateTrigger(), LedMappings.Keyboard)); + if (loadFilter.HasFlag(RGBDeviceType.Mouse) && devices.All(d => d is not RazerMouseRGBDevice)) + devices.Add(new RazerMouseRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Mouse, RazerEndpointType.Mouse, "Emulator Mouse"), GetUpdateTrigger(), LedMappings.Mouse)); + if (loadFilter.HasFlag(RGBDeviceType.Headset) && devices.All(d => d is not RazerHeadsetRGBDevice)) + devices.Add(new RazerHeadsetRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Headset, RazerEndpointType.Headset, "Emulator Headset"), GetUpdateTrigger())); + if (loadFilter.HasFlag(RGBDeviceType.Mousepad) && devices.All(d => d is not RazerMousepadRGBDevice)) + devices.Add(new RazerMousepadRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Mousepad, RazerEndpointType.Mousepad, "Emulator Mousepad"), GetUpdateTrigger())); + if (loadFilter.HasFlag(RGBDeviceType.Keypad) && devices.All(d => d is not RazerMousepadRGBDevice)) + devices.Add(new RazerKeypadRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Keypad, RazerEndpointType.Keypad, "Emulator Keypad"), GetUpdateTrigger())); + if (loadFilter.HasFlag(RGBDeviceType.Unknown) && devices.All(d => d is not RazerChromaLinkRGBDevice)) + devices.Add(new RazerChromaLinkRGBDevice(new RazerRGBDeviceInfo(RGBDeviceType.Unknown, RazerEndpointType.ChromaLink, "Emulator Chroma Link"), GetUpdateTrigger())); } - private void ThrowRazerError(RazerError errorCode) => throw new RazerException(errorCode); + return devices; + } - private void TryUnInit() + /// + protected override IEnumerable LoadDevices() + { + // Only take the first device of each endpoint type, the Razer SDK doesn't allow separate control over multiple devices using the same endpoint + foreach ((HIDDeviceDefinition definition, _) in DeviceDefinitions.GetConnectedDevices(x => x.CustomData == RazerEndpointType.LaptopKeyboard ? RazerEndpointType.Keyboard : x.CustomData)) { - try { _RazerSDK.UnInit(); } - catch { /* We tried our best */ } + yield return definition.CustomData switch + { + RazerEndpointType.Keyboard => new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo(definition.Name, definition.CustomData), GetUpdateTrigger(), definition.LedMapping), + RazerEndpointType.LaptopKeyboard => new RazerKeyboardRGBDevice(new RazerKeyboardRGBDeviceInfo(definition.Name, definition.CustomData), GetUpdateTrigger(), definition.LedMapping), + RazerEndpointType.Mouse => new RazerMouseRGBDevice(new RazerRGBDeviceInfo(definition.DeviceType, definition.CustomData, definition.Name), GetUpdateTrigger(), definition.LedMapping), + RazerEndpointType.Headset => new RazerHeadsetRGBDevice(new RazerRGBDeviceInfo(definition.DeviceType, definition.CustomData, definition.Name), GetUpdateTrigger()), + RazerEndpointType.Mousepad => new RazerMousepadRGBDevice(new RazerRGBDeviceInfo(definition.DeviceType, definition.CustomData, definition.Name), GetUpdateTrigger()), + RazerEndpointType.Keypad => new RazerKeypadRGBDevice(new RazerRGBDeviceInfo(definition.DeviceType, definition.CustomData, definition.Name), GetUpdateTrigger()), + RazerEndpointType.ChromaLink => new RazerChromaLinkRGBDevice(new RazerRGBDeviceInfo(definition.DeviceType, definition.CustomData, definition.Name), GetUpdateTrigger()), + _ => throw new RGBDeviceException($"Razer SDK does not support endpoint '{definition.CustomData}'") + }; } + } - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } + private void ThrowRazerError(RazerError errorCode, bool isCritical) => Throw(new RazerException(errorCode), isCritical); - TryUnInit(); + private void TryUnInit() + { + try { _RazerSDK.UnInit(); } + catch { /* We tried our best */ } + } - // DarthAffe 03.03.2020: Fails with an access-violation - verify if an unload is already triggered by uninit - //try { _RazerSDK.UnloadRazerSDK(); } - //catch { /* at least we tried */ } - } + /// + public override void Dispose() + { + base.Dispose(); - #endregion + TryUnInit(); + + // DarthAffe 03.03.2020: Fails with an access-violation - verify if an unload is already triggered by uninit + //try { _RazerSDK.UnloadRazerSDK(); } + //catch { /* at least we tried */ } } + + #endregion } diff --git a/RGB.NET.Devices.Razer/RazerDeviceProviderLoader.cs b/RGB.NET.Devices.Razer/RazerDeviceProviderLoader.cs deleted file mode 100644 index 2f3d306c..00000000 --- a/RGB.NET.Devices.Razer/RazerDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Razer -{ - /// - /// Represents a device provider loaded used to dynamically load razer devices into an application. - /// - public class RazerDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => RazerDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Roccat/Native/_ROCCATSDK.cs b/RGB.NET.Devices.Roccat/Native/_ROCCATSDK.cs deleted file mode 100644 index 21e16444..00000000 --- a/RGB.NET.Devices.Roccat/Native/_ROCCATSDK.cs +++ /dev/null @@ -1,163 +0,0 @@ -// ReSharper disable UnusedMethodReturnValue.Global -// ReSharper disable UnusedMember.Global - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices; -using RGB.NET.Core; - -namespace RGB.NET.Devices.Roccat.Native -{ - // ReSharper disable once InconsistentNaming - internal static class _RoccatSDK - { - #region Libary Management - - private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - - /// - /// Reloads the SDK. - /// - internal static void Reload() - { - UnloadRoccatSDK(); - LoadRoccatSDK(); - } - - private static void LoadRoccatSDK() - { - if (_dllHandle != IntPtr.Zero) return; - - // HACK: Load library at runtime to support both, x86 and x64 with one managed dll - List possiblePathList = Environment.Is64BitProcess ? RoccatDeviceProvider.PossibleX64NativePaths : RoccatDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); - if (dllPath == null) throw new RGBDeviceException($"Can't find the CUE-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - - _dllHandle = LoadLibrary(dllPath); - - _initSDKPointer = (InitSDKPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "InitSDK"), typeof(InitSDKPointer)); - _unloadSDKPointer = (UnloadSDKPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "UnloadSDK"), typeof(UnloadSDKPointer)); - _initRyosTalkPointer = (InitRyosTalkPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "init_ryos_talk"), typeof(InitRyosTalkPointer)); - _restoreLedRGBPointer = (RestoreLedRGBPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "RestoreLEDRGB"), typeof(RestoreLedRGBPointer)); - _setRyosKbSDKModePointer = (SetRyosKbSDKModePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "set_ryos_kb_SDKmode"), typeof(SetRyosKbSDKModePointer)); - _turnOffAllLedsPointer = (TurnOffAllLedsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "turn_off_all_LEDS"), typeof(TurnOffAllLedsPointer)); - _turnOnAllLedsPointer = (TurnOnAllLedsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "turn_on_all_LEDS"), typeof(TurnOnAllLedsPointer)); - _setLedOnPointer = (SetLedOnPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "set_LED_on"), typeof(SetLedOnPointer)); - _setLedOffPointer = (SetLedOffPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "set_LED_off"), typeof(SetLedOffPointer)); - _setAllLedsPointer = (SetAllLedsPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "Set_all_LEDS"), typeof(SetAllLedsPointer)); - _allKeyblinkingPointer = (AllKeyblinkingPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "All_Key_Blinking"), typeof(AllKeyblinkingPointer)); - _setLedRGBPointer = (SetLedRGBPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "Set_LED_RGB"), typeof(SetLedRGBPointer)); - _setAllLedSfxPointer = (SetAllLedSfxPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "Set_all_LEDSFX"), typeof(SetAllLedSfxPointer)); - } - - internal static void UnloadRoccatSDK() - { - if (_dllHandle == IntPtr.Zero) return; - - // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 20.02.2016: We might need to reduce the internal reference counter more than once to set the library free - while (FreeLibrary(_dllHandle)) ; - _dllHandle = IntPtr.Zero; - } - - [DllImport("kernel32.dll")] - private static extern IntPtr LoadLibrary(string dllToLoad); - - [DllImport("kernel32.dll")] - private static extern bool FreeLibrary(IntPtr dllHandle); - - [DllImport("kernel32.dll")] - private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); - - #endregion - - #region SDK-METHODS - - #region Pointers - - private static InitSDKPointer _initSDKPointer; - private static UnloadSDKPointer _unloadSDKPointer; - private static InitRyosTalkPointer _initRyosTalkPointer; - private static RestoreLedRGBPointer _restoreLedRGBPointer; - private static SetRyosKbSDKModePointer _setRyosKbSDKModePointer; - private static TurnOffAllLedsPointer _turnOffAllLedsPointer; - private static TurnOnAllLedsPointer _turnOnAllLedsPointer; - private static SetLedOnPointer _setLedOnPointer; - private static SetLedOffPointer _setLedOffPointer; - private static SetAllLedsPointer _setAllLedsPointer; - private static AllKeyblinkingPointer _allKeyblinkingPointer; - private static SetLedRGBPointer _setLedRGBPointer; - private static SetAllLedSfxPointer _setAllLedSfxPointer; - - #endregion - - #region Delegates - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate IntPtr InitSDKPointer(); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void UnloadSDKPointer(IntPtr handle); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool InitRyosTalkPointer(IntPtr handle); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void RestoreLedRGBPointer(IntPtr handle); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool SetRyosKbSDKModePointer(IntPtr handle, bool state); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void TurnOffAllLedsPointer(IntPtr handle); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void TurnOnAllLedsPointer(IntPtr handle); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void SetLedOnPointer(IntPtr handle, byte position); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void SetLedOffPointer(IntPtr handle, byte position); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void SetAllLedsPointer(IntPtr handle, byte led, byte country); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void AllKeyblinkingPointer(IntPtr handle, int delayTime, int loopTime); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void SetLedRGBPointer(IntPtr handle, byte zone, byte effect, byte speed, byte r, byte g, byte b); - - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate void SetAllLedSfxPointer(IntPtr handle, byte ledOnOff, byte r, byte g, byte b, byte layout); - - #endregion - - // ReSharper disable EventExceptionNotDocumented - - internal static IntPtr InitSDK() => _initSDKPointer(); - internal static void UnloadSDK(IntPtr handle) => _unloadSDKPointer(handle); - internal static bool InitRyosTalk(IntPtr handle) => _initRyosTalkPointer(handle); - internal static void RestoreLedRGB(IntPtr handle) => _restoreLedRGBPointer(handle); - internal static bool SetRyosKbSDKMode(IntPtr handle, bool state) => _setRyosKbSDKModePointer(handle, state); - internal static void TurnOffAllLeds(IntPtr handle) => _turnOffAllLedsPointer(handle); - internal static void TurnOnAllLeds(IntPtr handle) => _turnOnAllLedsPointer(handle); - internal static void SetLedOn(IntPtr handle, byte position) => _setLedOnPointer(handle, position); - internal static void SetLedOff(IntPtr handle, byte position) => _setLedOffPointer(handle, position); - internal static void SetAllLeds(IntPtr handle, byte led, byte country) => _setAllLedsPointer(handle, led, country); - internal static void AllKeyblinking(IntPtr handle, int delayTime, int loopTime) => _allKeyblinkingPointer(handle, delayTime, loopTime); - internal static void SetLedRGB(IntPtr handle, byte zone, byte effect, byte speed, byte r, byte g, byte b) => _setLedRGBPointer(handle, zone, effect, speed, r, g, b); - internal static void SetAllLedSfx(IntPtr handle, byte ledOnOff, byte r, byte g, byte b, byte layout) => _setAllLedSfxPointer(handle, ledOnOff, r, g, b, layout); - - // ReSharper restore EventExceptionNotDocumented - - #endregion - } -} diff --git a/RGB.NET.Devices.Roccat/RGB.NET.Devices.Roccat.csproj b/RGB.NET.Devices.Roccat/RGB.NET.Devices.Roccat.csproj deleted file mode 100644 index f83e1c4f..00000000 --- a/RGB.NET.Devices.Roccat/RGB.NET.Devices.Roccat.csproj +++ /dev/null @@ -1,68 +0,0 @@ - - - netstandard2.0;net45 - win7-x86;win7-x64 - - Darth Affe - Wyrez - en-US - en-US - RGB.NET.Devices.Roccat - RGB.NET.Devices.Roccat - RGB.NET.Devices.Roccat - RGB.NET.Devices.Roccat - RGB.NET.Devices.Roccat - Roccat-Device-Implementations of RGB.NET - Roccat-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png - https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE - Github - https://github.com/DarthAffe/RGB.NET - False - - - - 0.0.1 - 0.0.1 - 0.0.1 - - ..\bin\ - true - True - True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL - - - - $(DefineConstants);TRACE;DEBUG - true - full - false - - - - pdbonly - true - $(NoWarn);CS1591;CS1572;CS1573 - $(DefineConstants);RELEASE - - - - - - - - - - \ No newline at end of file diff --git a/RGB.NET.Devices.Roccat/RoccatDeviceProvider.cs b/RGB.NET.Devices.Roccat/RoccatDeviceProvider.cs deleted file mode 100644 index 4ad9a9ed..00000000 --- a/RGB.NET.Devices.Roccat/RoccatDeviceProvider.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using RGB.NET.Core; -using RGB.NET.Devices.Roccat.Native; - -namespace RGB.NET.Devices.Roccat -{ - /// - /// - /// Represents a device provider responsible for roccat (TalkFX)devices. - /// - public class RoccatDeviceProvider : IRGBDeviceProvider - { - #region Properties & Fields - - private static RoccatDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static RoccatDeviceProvider Instance => _instance ?? new RoccatDeviceProvider(); - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. - /// The first match will be used. - /// - public static List PossibleX86NativePaths { get; } = new List { "x86/RoccatTalkSDKWrapper.dll" }; - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. - /// The first match will be used. - /// - public static List PossibleX64NativePaths { get; } = new List { "x64/RoccatTalkSDKWrapper.dll" }; - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _RoccatSDK.LoadedArchitecture; - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - private IntPtr _sdkHandle; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public RoccatDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(RoccatDeviceProvider)}"); - _instance = this; - } - - #endregion - - #region Methods - - /// - /// Thrown if the SDK is already initialized or if the SDK is not compatible to CUE. - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - IsInitialized = false; - - try - { - _sdkHandle = _RoccatSDK.InitSDK(); - - IList devices = new List(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) throw; - return false; - } - - return true; - } - - /// - public void ResetDevices() - { } - - /// - public void Dispose() - { - if (_sdkHandle != IntPtr.Zero) - { - try { _RoccatSDK.RestoreLedRGB(_sdkHandle); } - catch { /* We tried our best */} - - try { _RoccatSDK.SetRyosKbSDKMode(_sdkHandle, false); } - catch { /* We tried our best */} - - try { _RoccatSDK.UnloadSDK(_sdkHandle); } - catch { /* We tried our best */} - } - - try { _RoccatSDK.UnloadRoccatSDK(); } - catch { /* at least we tried */ } - } - - #endregion - } -} diff --git a/RGB.NET.Devices.Roccat/RoccatDeviceProviderLoader.cs b/RGB.NET.Devices.Roccat/RoccatDeviceProviderLoader.cs deleted file mode 100644 index 261de13f..00000000 --- a/RGB.NET.Devices.Roccat/RoccatDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Roccat -{ - /// - /// Represents a device provider loaded used to dynamically load roccat devices into an application. - /// - public class RoccatDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => RoccatDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.SoIP/Client/SoIPClientDeviceDefinition.cs b/RGB.NET.Devices.SoIP/Client/SoIPClientDeviceDefinition.cs deleted file mode 100644 index 470df745..00000000 --- a/RGB.NET.Devices.SoIP/Client/SoIPClientDeviceDefinition.cs +++ /dev/null @@ -1,41 +0,0 @@ -using RGB.NET.Devices.SoIP.Generic; - -namespace RGB.NET.Devices.SoIP.Client -{ - public class SoIPClientDeviceDefinition : ISoIPDeviceDefinition - { - #region Properties & Fields - - /// - /// Gets or sets the hostname of the device. - /// - public string Hostname { get; set; } - - /// - /// Gets or sets the port to device is listening to. - /// - public int Port { get; set; } - - /// - /// Gets or sets the manufacturer of the device. - /// - public string Manufacturer { get; set; } = "Unknown"; - - /// - /// Gets or sets the model name of the device. - /// - public string Model { get; set; } = "Generic SoIP-Device"; - - #endregion - - #region Constructors - - public SoIPClientDeviceDefinition(string hostname, int port) - { - this.Hostname = hostname; - this.Port = port; - } - - #endregion - } -} diff --git a/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDevice.cs b/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDevice.cs deleted file mode 100644 index 38ef9a86..00000000 --- a/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDevice.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using RGB.NET.Core; -using RGB.NET.Devices.SoIP.Generic; -using SimpleTCP; - -namespace RGB.NET.Devices.SoIP.Client -{ - public class SoIPClientRGBDevice : AbstractRGBDevice, ISoIPRGBDevice, IUnknownDevice - { - #region Properties & Fields - - private readonly Dictionary _syncbackCache = new Dictionary(); - private readonly SimpleTcpClient _tcpClient; - - public override SoIPClientRGBDeviceInfo DeviceInfo { get; } - - #endregion - - #region Constructors - - public SoIPClientRGBDevice(SoIPClientRGBDeviceInfo deviceInfo) - { - this.DeviceInfo = deviceInfo; - - _tcpClient = new SimpleTcpClient(); - _tcpClient.DelimiterDataReceived += TcpClientOnDelimiterDataReceived; - } - - #endregion - - #region Methods - - void ISoIPRGBDevice.Initialize(IDeviceUpdateTrigger updateTrigger) - { - _tcpClient.Connect(DeviceInfo.Hostname, DeviceInfo.Port); - } - - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) - { } - - /// - public override void SyncBack() - { - lock (_syncbackCache) - { - foreach (KeyValuePair cacheEntry in _syncbackCache) - { - LedId ledId = cacheEntry.Key; - Color color = cacheEntry.Value; - - if (!LedMapping.TryGetValue(ledId, out Led led)) - led = InitializeLed(cacheEntry.Key, new Rectangle(0, 0, 10, 10)); //TODO DarthAffe 10.06.2018: Send layout with initial package - - SetLedColorWithoutRequest(led, color); - } - - _syncbackCache.Clear(); - } - } - - private void TcpClientOnDelimiterDataReceived(object sender, Message message) - { - List<(LedId, Color)> leds = message.MessageString.Split(';').Select(x => - { - string[] led = x.Split('|'); - return ((LedId)Enum.Parse(typeof(LedId), led[0]), RGBColor.FromHexString(led[1])); - }).ToList(); - lock (_syncbackCache) - foreach ((LedId ledId, Color color) in leds) - _syncbackCache[ledId] = color; - } - - /// - public override void Dispose() - { - base.Dispose(); - - _tcpClient.Disconnect(); - _tcpClient.Dispose(); - } - - #endregion - } -} diff --git a/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDeviceInfo.cs b/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDeviceInfo.cs deleted file mode 100644 index 99f8099a..00000000 --- a/RGB.NET.Devices.SoIP/Client/SoIPClientRGBDeviceInfo.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.SoIP.Client -{ - /// - /// - /// Represents device information for a />. - /// - public class SoIPClientRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields - - /// - public RGBDeviceType DeviceType => RGBDeviceType.Unknown; - - /// - public string DeviceName { get; } - - /// - public string Manufacturer { get; } - - /// - public string Model { get; } - - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.None; - - /// - public bool SupportsSyncBack => true; - - /// - public Uri Image { get; set; } - - /// - /// The hostname of the device. - /// - public string Hostname { get; } - - /// - /// The port of the device. - /// - public int Port { get; } - - #endregion - - #region Constructors - - internal SoIPClientRGBDeviceInfo(SoIPClientDeviceDefinition deviceDefinition) - { - this.Manufacturer = deviceDefinition.Manufacturer; - this.Model = deviceDefinition.Model; - this.Hostname = deviceDefinition.Hostname; - this.Port = deviceDefinition.Port; - - DeviceName = $"{Manufacturer} {Model}"; - } - - #endregion - } -} diff --git a/RGB.NET.Devices.SoIP/FodyWeavers.xml b/RGB.NET.Devices.SoIP/FodyWeavers.xml deleted file mode 100644 index 7e25d148..00000000 --- a/RGB.NET.Devices.SoIP/FodyWeavers.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/RGB.NET.Devices.SoIP/FodyWeavers.xsd b/RGB.NET.Devices.SoIP/FodyWeavers.xsd deleted file mode 100644 index 44a53744..00000000 --- a/RGB.NET.Devices.SoIP/FodyWeavers.xsd +++ /dev/null @@ -1,111 +0,0 @@ - - - - - - - - - - - - A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks - - - - - A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. - - - - - A list of unmanaged 32 bit assembly names to include, delimited with line breaks. - - - - - A list of unmanaged 64 bit assembly names to include, delimited with line breaks. - - - - - The order of preloaded assemblies, delimited with line breaks. - - - - - - This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. - - - - - Controls if .pdbs for reference assemblies are also embedded. - - - - - Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. - - - - - As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. - - - - - Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. - - - - - Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. - - - - - A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | - - - - - A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. - - - - - A list of unmanaged 32 bit assembly names to include, delimited with |. - - - - - A list of unmanaged 64 bit assembly names to include, delimited with |. - - - - - The order of preloaded assemblies, delimited with |. - - - - - - - - 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. - - - - - A comma-separated list of error codes that can be safely ignored in assembly verification. - - - - - 'false' to turn off automatic generation of the XML Schema file. - - - - - \ No newline at end of file diff --git a/RGB.NET.Devices.SoIP/Generic/ISoIPDeviceDefinition.cs b/RGB.NET.Devices.SoIP/Generic/ISoIPDeviceDefinition.cs deleted file mode 100644 index 5c6dba88..00000000 --- a/RGB.NET.Devices.SoIP/Generic/ISoIPDeviceDefinition.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace RGB.NET.Devices.SoIP.Generic -{ - /// - /// Marker interface for SoIP device definitions. - /// - public interface ISoIPDeviceDefinition - { } -} diff --git a/RGB.NET.Devices.SoIP/Generic/ISoIPRGBDevice.cs b/RGB.NET.Devices.SoIP/Generic/ISoIPRGBDevice.cs deleted file mode 100644 index d7d67434..00000000 --- a/RGB.NET.Devices.SoIP/Generic/ISoIPRGBDevice.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.SoIP.Generic -{ - // ReSharper disable once InconsistentNaming - internal interface ISoIPRGBDevice : IRGBDevice, IDisposable - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } -} diff --git a/RGB.NET.Devices.SoIP/RGB.NET.Devices.SoIP.csproj b/RGB.NET.Devices.SoIP/RGB.NET.Devices.SoIP.csproj deleted file mode 100644 index 0816d25d..00000000 --- a/RGB.NET.Devices.SoIP/RGB.NET.Devices.SoIP.csproj +++ /dev/null @@ -1,77 +0,0 @@ - - - netstandard2.0;net45 - win7-x86;win7-x64 - - Darth Affe - Wyrez - en-US - en-US - RGB.NET.Devices.SoIP - RGB.NET.Devices.SoIP - RGB.NET.Devices.SoIP - RGB.NET.Devices.SoIP - RGB.NET.Devices.SoIP - SoIP-Device-Implementations of RGB.NET - SoIP-Device-Implementations of RGB.NET, a C# (.NET) library - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png - https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE - Github - https://github.com/DarthAffe/RGB.NET - True - - - - 0.0.1 - 0.0.1 - 0.0.1 - - ..\bin\ - true - True - True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL - - - - $(DefineConstants);TRACE;DEBUG - true - full - false - - - - pdbonly - true - $(NoWarn);CS1591;CS1572;CS1573 - $(DefineConstants);RELEASE - - - - - - all - runtime; build; native; contentfiles; analyzers - - - - - - - - - - - - \ No newline at end of file diff --git a/RGB.NET.Devices.SoIP/Server/SoIPServerDeviceDefinition.cs b/RGB.NET.Devices.SoIP/Server/SoIPServerDeviceDefinition.cs deleted file mode 100644 index 2eff475d..00000000 --- a/RGB.NET.Devices.SoIP/Server/SoIPServerDeviceDefinition.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using RGB.NET.Core; -using RGB.NET.Devices.SoIP.Generic; - -namespace RGB.NET.Devices.SoIP.Server -{ - public class SoIPServerDeviceDefinition : ISoIPDeviceDefinition - { - #region Properties & Fields - - /// - /// Gets or sets the port to device is listening to. - /// - public int Port { get; set; } - - /// - /// Gets or sets the manufacturer of the device. - /// - public string Manufacturer { get; set; } = "Unknown"; - - /// - /// Gets or sets the model name of the device. - /// - public string Model { get; set; } = "Generic SoIP-Device"; - - /// - /// Gets the IDs of the leds represented by this device. - /// - public List Leds { get; } - - #endregion - - #region Constructors - - public SoIPServerDeviceDefinition(int port, params LedId[] ledIds) - { - this.Port = port; - this.Leds = ledIds.ToList(); - } - - #endregion - } -} diff --git a/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs b/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs deleted file mode 100644 index 5908a1bf..00000000 --- a/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDevice.cs +++ /dev/null @@ -1,79 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using System.Net.Sockets; -using RGB.NET.Core; -using RGB.NET.Devices.SoIP.Generic; -using SimpleTCP; - -namespace RGB.NET.Devices.SoIP.Server -{ - public class SoIPServerRGBDevice : AbstractRGBDevice, ISoIPRGBDevice, IUnknownDevice - { - #region Properties & Fields - - private readonly List _leds; - private readonly SimpleTcpServer _tcpServer; - private SoIPServerUpdateQueue _updateQueue; - - public override SoIPServerRGBDeviceInfo DeviceInfo { get; } - - #endregion - - #region Constructors - - public SoIPServerRGBDevice(SoIPServerRGBDeviceInfo deviceInfo, List leds) - { - this.DeviceInfo = deviceInfo; - this._leds = leds; - - _tcpServer = new SimpleTcpServer(); - _tcpServer.ClientConnected += TcpServerOnClientConnected; - } - - #endregion - - #region Methods - - void ISoIPRGBDevice.Initialize(IDeviceUpdateTrigger updateTrigger) - { - int count = 0; - foreach (LedId id in _leds) - InitializeLed(id, new Rectangle((count++) * 10, 0, 10, 10)); - - //TODO DarthAffe 10.06.2018: Allow to load a layout. - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - - _tcpServer.Start(DeviceInfo.Port); - _updateQueue = new SoIPServerUpdateQueue(updateTrigger, _tcpServer); - } - - protected override void UpdateLeds(IEnumerable ledsToUpdate) => _updateQueue.SetData(ledsToUpdate); - - private void TcpServerOnClientConnected(object sender, TcpClient tcpClient) - { - string message = GetLedString(LedMapping.Values); - byte[] messageData = _tcpServer.StringEncoder.GetBytes(message + _tcpServer.StringEncoder.GetString(new[] { _tcpServer.Delimiter })); - tcpClient.GetStream().WriteAsync(messageData, 0, messageData.Length); - } - - private string GetLedString(IEnumerable leds) => string.Join(";", leds.Select(x => x.Id.ToString() + "|" + x.Color.AsARGBHexString(false))); - - /// - public override void Dispose() - { - try { _updateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - - _tcpServer.Stop(); - } - - #endregion - } -} diff --git a/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDeviceInfo.cs b/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDeviceInfo.cs deleted file mode 100644 index 10ff143d..00000000 --- a/RGB.NET.Devices.SoIP/Server/SoIPServerRGBDeviceInfo.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using RGB.NET.Core; - -namespace RGB.NET.Devices.SoIP.Server -{ - /// - /// - /// Represents device information for a />. - /// - public class SoIPServerRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields - - /// - public RGBDeviceType DeviceType => RGBDeviceType.Unknown; - - /// - public string DeviceName { get; } - - /// - public string Manufacturer { get; } - - /// - public string Model { get; } - - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; - - /// - public bool SupportsSyncBack => false; - - /// - public Uri Image { get; set; } - - /// - /// The port of the device. - /// - public int Port { get; } - - #endregion - - #region Constructors - - internal SoIPServerRGBDeviceInfo(SoIPServerDeviceDefinition deviceDefinition) - { - this.Manufacturer = deviceDefinition.Manufacturer; - this.Model = deviceDefinition.Model; - this.Port = deviceDefinition.Port; - - DeviceName = $"{Manufacturer} {Model}"; - } - - #endregion - } -} diff --git a/RGB.NET.Devices.SoIP/Server/SoIPServerUpdateQueue.cs b/RGB.NET.Devices.SoIP/Server/SoIPServerUpdateQueue.cs deleted file mode 100644 index 1d100cea..00000000 --- a/RGB.NET.Devices.SoIP/Server/SoIPServerUpdateQueue.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using RGB.NET.Core; -using SimpleTCP; - -namespace RGB.NET.Devices.SoIP.Server -{ - /// - /// - /// Represents the update-queue performing updates for E131-DMX devices. - /// - public class SoIPServerUpdateQueue : UpdateQueue - { - #region Properties & Fields - - private readonly SimpleTcpServer _tcpServer; - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The hostname of the device this queue is performing updates for. - public SoIPServerUpdateQueue(IDeviceUpdateTrigger updateTrigger, SimpleTcpServer tcpServer) - : base(updateTrigger) - { - this._tcpServer = tcpServer; - } - - #endregion - - #region Methods - - /// - protected override void Update(Dictionary dataSet) - { - if ((dataSet != null) && (dataSet.Count > 0)) - { - string m = GetLedString(dataSet); - _tcpServer.BroadcastLine(m); - } - } - - private string GetLedString(Dictionary dataSet) => string.Join(";", dataSet.Select(x => x.Key.ToString() + "|" + x.Value.AsARGBHexString(false))); - - #endregion - } -} diff --git a/RGB.NET.Devices.SoIP/SoIPDeviceProvider.cs b/RGB.NET.Devices.SoIP/SoIPDeviceProvider.cs deleted file mode 100644 index 9755cc2b..00000000 --- a/RGB.NET.Devices.SoIP/SoIPDeviceProvider.cs +++ /dev/null @@ -1,139 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedMember.Global - -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using RGB.NET.Core; -using RGB.NET.Devices.SoIP.Client; -using RGB.NET.Devices.SoIP.Generic; -using RGB.NET.Devices.SoIP.Server; - -namespace RGB.NET.Devices.SoIP -{ - /// - /// - /// Represents a device provider responsible for debug devices. - /// - public class SoIPDeviceProvider : IRGBDeviceProvider - { - #region Properties & Fields - - private static SoIPDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static SoIPDeviceProvider Instance => _instance ?? new SoIPDeviceProvider(); - - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - public bool HasExclusiveAccess => false; - - /// - /// Gets a list of all defined device-definitions. - /// - public List DeviceDefinitions { get; } = new List(); - - /// - /// The used to trigger the updates for dmx devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public SoIPDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(SoIPDeviceProvider)}"); - _instance = this; - - UpdateTrigger = new DeviceUpdateTrigger(); - } - - #endregion - - #region Methods - - /// - /// Adds the given to this device-provider. - /// - /// The to add. - public void AddDeviceDefinition(ISoIPDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); - - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - - IsInitialized = false; - - try - { - UpdateTrigger.Stop(); - - IList devices = new List(); - - foreach (ISoIPDeviceDefinition deviceDefinition in DeviceDefinitions) - { - try - { - ISoIPRGBDevice device = null; - - switch (deviceDefinition) - { - case SoIPServerDeviceDefinition serverDeviceDefinition: - if (serverDeviceDefinition.Leds.Count > 0) - device = new SoIPServerRGBDevice(new SoIPServerRGBDeviceInfo(serverDeviceDefinition), serverDeviceDefinition.Leds); - break; - - case SoIPClientDeviceDefinition clientDeviceDefinition: - device = new SoIPClientRGBDevice(new SoIPClientRGBDeviceInfo(clientDeviceDefinition)); - break; - } - - if (device != null) - { - device.Initialize(UpdateTrigger); - devices.Add(device); - } - } - catch { if (throwExceptions) throw; } - } - - UpdateTrigger.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) throw; - return false; - } - - return true; - } - - /// - public void ResetDevices() - { } - - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } - } - - #endregion - } -} diff --git a/RGB.NET.Devices.SoIP/SoIPDeviceProviderLoader.cs b/RGB.NET.Devices.SoIP/SoIPDeviceProviderLoader.cs deleted file mode 100644 index ead10101..00000000 --- a/RGB.NET.Devices.SoIP/SoIPDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.SoIP -{ - /// - /// Represents a device provider loaded used to dynamically load SoIP (syncback over IP) devices into an application. - /// - public class SoIPDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => true; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => SoIPDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.SteelSeries/API/Model/CoreProps.cs b/RGB.NET.Devices.SteelSeries/API/Model/CoreProps.cs index a3f1f854..c5cc9709 100644 --- a/RGB.NET.Devices.SteelSeries/API/Model/CoreProps.cs +++ b/RGB.NET.Devices.SteelSeries/API/Model/CoreProps.cs @@ -1,10 +1,9 @@ -using Newtonsoft.Json; +using System.Text.Json.Serialization; -namespace RGB.NET.Devices.SteelSeries.API.Model +namespace RGB.NET.Devices.SteelSeries.API.Model; + +internal class CoreProps { - internal class CoreProps - { - [JsonProperty(PropertyName = "address")] - public string Address { get; set; } - } -} + [JsonPropertyName("address")] + public string? Address { get; set; } +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/API/Model/Event.cs b/RGB.NET.Devices.SteelSeries/API/Model/Event.cs index ba3eb603..4aa335e5 100644 --- a/RGB.NET.Devices.SteelSeries/API/Model/Event.cs +++ b/RGB.NET.Devices.SteelSeries/API/Model/Event.cs @@ -1,34 +1,34 @@ using System.Collections.Generic; -using Newtonsoft.Json; +using System.Text.Json.Serialization; -namespace RGB.NET.Devices.SteelSeries.API.Model -{ - internal class Event - { - #region Properties & Fields +namespace RGB.NET.Devices.SteelSeries.API.Model; - [JsonProperty("game")] - public string Game { get; set; } +internal class Event +{ + #region Properties & Fields - [JsonProperty("event")] - public string Name { get; set; } + [JsonPropertyName("game")] + public string? Game { get; set; } - [JsonProperty("data")] - public Dictionary Data { get; } = new Dictionary(); + [JsonPropertyName("event")] + public string? Name { get; set; } - #endregion + // ReSharper disable once CollectionNeverQueried.Global + [JsonPropertyName("data")] + public Dictionary Data { get; } = new(); - #region Constructors + #endregion - public Event() - { } + #region Constructors - public Event(Game game, string name) - { - this.Name = name; - Game = game.Name; - } + public Event() + { } - #endregion + public Event(Game game, string name) + { + this.Name = name; + Game = game.Name; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/API/Model/Game.cs b/RGB.NET.Devices.SteelSeries/API/Model/Game.cs index d93c7e4b..b22cb1f8 100644 --- a/RGB.NET.Devices.SteelSeries/API/Model/Game.cs +++ b/RGB.NET.Devices.SteelSeries/API/Model/Game.cs @@ -1,30 +1,29 @@ -using Newtonsoft.Json; +using System.Text.Json.Serialization; -namespace RGB.NET.Devices.SteelSeries.API.Model -{ - internal class Game - { - #region Properties & Fields +namespace RGB.NET.Devices.SteelSeries.API.Model; - [JsonProperty("game")] - public string Name { get; set; } +internal class Game +{ + #region Properties & Fields - [JsonProperty("game_display_name")] - public string DisplayName { get; set; } + [JsonPropertyName("game")] + public string? Name { get; set; } - #endregion + [JsonPropertyName("game_display_name")] + public string? DisplayName { get; set; } - #region Constructors + #endregion - public Game() - { } + #region Constructors - public Game(string name, string displayName) - { - Name = name; - DisplayName = displayName; - } + public Game() + { } - #endregion + public Game(string name, string displayName) + { + Name = name; + DisplayName = displayName; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/API/Model/GoLispHandler.cs b/RGB.NET.Devices.SteelSeries/API/Model/GoLispHandler.cs index 27d5315f..3cd2ec4c 100644 --- a/RGB.NET.Devices.SteelSeries/API/Model/GoLispHandler.cs +++ b/RGB.NET.Devices.SteelSeries/API/Model/GoLispHandler.cs @@ -1,30 +1,29 @@ -using Newtonsoft.Json; +using System.Text.Json.Serialization; -namespace RGB.NET.Devices.SteelSeries.API.Model -{ - internal class GoLispHandler - { - #region Properties & Fields +namespace RGB.NET.Devices.SteelSeries.API.Model; - [JsonProperty("game")] - public string Game { get; set; } +internal class GoLispHandler +{ + #region Properties & Fields - [JsonProperty("golisp")] - public string Handler { get; set; } + [JsonPropertyName("game")] + public string? Game { get; set; } - #endregion + [JsonPropertyName("golisp")] + public string? Handler { get; set; } - #region Constructors + #endregion - public GoLispHandler() - { } + #region Constructors - public GoLispHandler(Game game, string handler) - { - this.Handler = handler; - Game = game.Name; - } + public GoLispHandler() + { } - #endregion + public GoLispHandler(Game game, string handler) + { + this.Handler = handler; + Game = game.Name; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs b/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs index bf82309f..557148db 100644 --- a/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs +++ b/RGB.NET.Devices.SteelSeries/API/SteelSeriesSDK.cs @@ -5,19 +5,19 @@ using System.Net.Http; using System.Runtime.InteropServices; using System.Text; -using Newtonsoft.Json; +using System.Text.Json; using RGB.NET.Devices.SteelSeries.API.Model; -namespace RGB.NET.Devices.SteelSeries.API +namespace RGB.NET.Devices.SteelSeries.API; + +internal static class SteelSeriesSDK { - internal static class SteelSeriesSDK - { - #region Constants + #region Constants - private const string GAME_NAME = "RGBNET"; - private const string GAME_DISPLAYNAME = "RGB.NET"; - private const string EVENT_NAME = "UPDATELEDS"; - private static readonly string HANDLER = $@"(define (getZone x) + private const string GAME_NAME = "RGBNET"; + private const string GAME_DISPLAYNAME = "RGB.NET"; + private const string EVENT_NAME = "UPDATELEDS"; + private static readonly string HANDLER = $@"(define (getZone x) (case x {string.Join(Environment.NewLine, Enum.GetValues(typeof(SteelSeriesLedId)) .Cast() @@ -41,40 +41,48 @@ internal static class SteelSeriesSDK (add-event-zone-use-with-specifier ""{EVENT_NAME}"" ""all"" ""rgb-6-zone"") (add-event-zone-use-with-specifier ""{EVENT_NAME}"" ""all"" ""rgb-7-zone"") (add-event-zone-use-with-specifier ""{EVENT_NAME}"" ""all"" ""rgb-8-zone"") +(add-event-zone-use-with-specifier ""{EVENT_NAME}"" ""all"" ""rgb-10-zone"") (add-event-zone-use-with-specifier ""{EVENT_NAME}"" ""all"" ""rgb-12-zone"") (add-event-zone-use-with-specifier ""{EVENT_NAME}"" ""all"" ""rgb-17-zone"") (add-event-zone-use-with-specifier ""{EVENT_NAME}"" ""all"" ""rgb-24-zone"") -(add-event-zone-use-with-specifier ""{EVENT_NAME}"" ""all"" ""rgb-103-zone"")"; +(add-event-zone-use-with-specifier ""{EVENT_NAME}"" ""all"" ""rgb-103-zone"") + +(add-custom-zone '(""non-us-backslash"" 100)) +(add-custom-zone '(""num-5"" 93)) +(add-custom-zone '(""fn"" 240)) +(add-custom-zone '(""power"" 102))"; //HACK DarthAffe 07.10.2021: Custom zone to workaround a SDK-issue (https://github.com/SteelSeries/gamesense-sdk/issues/85) - private const string CORE_PROPS_WINDOWS = "%PROGRAMDATA%/SteelSeries/SteelSeries Engine 3/coreProps.json"; - private const string CORE_PROPS_OSX = "/Library/Application Support/SteelSeries Engine 3/coreProps.json"; + private const string CORE_PROPS_WINDOWS = "%PROGRAMDATA%/SteelSeries/SteelSeries Engine 3/coreProps.json"; + private const string CORE_PROPS_OSX = "/Library/Application Support/SteelSeries Engine 3/coreProps.json"; - #endregion + #endregion - #region Properties & Fields - // ReSharper disable InconsistentNaming + #region Properties & Fields + // ReSharper disable InconsistentNaming - private static readonly HttpClient _client = new HttpClient(); - private static readonly Game _game = new Game(GAME_NAME, GAME_DISPLAYNAME); - private static readonly Event _event = new Event(_game, EVENT_NAME); - private static string _baseUrl; + private static readonly HttpClient _client = new(); + private static readonly Game _game = new(GAME_NAME, GAME_DISPLAYNAME); + private static readonly Event _event = new(_game, EVENT_NAME); + private static string? _baseUrl; - internal static bool IsInitialized => !string.IsNullOrWhiteSpace(_baseUrl); + internal static bool IsInitialized => !string.IsNullOrWhiteSpace(_baseUrl); - // ReSharper restore InconsistentNaming - #endregion + // ReSharper restore InconsistentNaming + #endregion - #region Methods + #region Methods - internal static bool Initialize() + internal static bool Initialize() + { + try { - try + string corePropsPath = GetCorePropsPath(); + if (!string.IsNullOrWhiteSpace(corePropsPath) && File.Exists(corePropsPath)) { - string corePropsPath = GetCorePropsPath(); - if (!string.IsNullOrWhiteSpace(corePropsPath) && File.Exists(corePropsPath)) + CoreProps? coreProps = JsonSerializer.Deserialize(File.ReadAllText(corePropsPath)); + _baseUrl = coreProps?.Address; + if (_baseUrl != null) { - CoreProps coreProps = JsonConvert.DeserializeObject(File.ReadAllText(corePropsPath)); - _baseUrl = coreProps.Address; if (!_baseUrl.StartsWith("http://", StringComparison.Ordinal)) _baseUrl = "http://" + _baseUrl; @@ -82,61 +90,67 @@ internal static bool Initialize() RegisterGoLispHandler(new GoLispHandler(_game, HANDLER)); } } - catch - { - _baseUrl = null; - } - return IsInitialized; } - - internal static void UpdateLeds(string device, Dictionary data) + catch { - _event.Data.Clear(); - _event.Data.Add("value", device); - _event.Data.Add("colors", data.Values.ToList()); - _event.Data.Add("zones", data.Keys.ToList()); - - TriggerEvent(_event); + _baseUrl = null; } + return IsInitialized; + } - internal static void SendHeartbeat() => SendHeartbeat(_game); + internal static void UpdateLeds(string device, IList<(string zone, int[] color)> data) + { + _event.Data.Clear(); + _event.Data.Add("value", device); + _event.Data.Add("colors", data.Select(x => x.color).ToList()); + _event.Data.Add("zones", data.Select(x => x.zone).ToList()); - internal static void ResetLeds() => StopGame(_game); + TriggerEvent(_event); + } - internal static void Dispose() - { - if (IsInitialized) - ResetLeds(); + internal static void SendHeartbeat() => SendHeartbeat(_game); - _client.Dispose(); - } + internal static void ResetLeds() => StopGame(_game); - private static string TriggerEvent(Event e) => PostJson("/game_event", e); - private static string RegisterGoLispHandler(GoLispHandler handler) => PostJson("/load_golisp_handlers", handler); - private static string RegisterEvent(Event e) => PostJson("/register_game_event", e); - private static string UnregisterEvent(Event e) => PostJson("/remove_game_event", e); - private static string RegisterGame(Game game) => PostJson("/game_metadata", game); - private static string UnregisterGame(Game game) => PostJson("/remove_game", game); - private static string StopGame(Game game) => PostJson("/stop_game", game); - private static string SendHeartbeat(Game game) => PostJson("/game_heartbeat", game); + internal static void Dispose() + { + if (IsInitialized) + ResetLeds(); - private static string PostJson(string urlSuffix, object o) - { - string payload = JsonConvert.SerializeObject(o); - return _client.PostAsync(_baseUrl + urlSuffix, new StringContent(payload, Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Result; - } + _client.Dispose(); + } - private static string GetCorePropsPath() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - return Environment.ExpandEnvironmentVariables(CORE_PROPS_WINDOWS); +#pragma warning disable IDE0051 // Remove unused private members + // ReSharper disable UnusedMethodReturnValue.Local + // ReSharper disable UnusedMember.Local + private static string TriggerEvent(Event e) => PostJson("/game_event", e); + private static string RegisterGoLispHandler(GoLispHandler handler) => PostJson("/load_golisp_handlers", handler); + private static string RegisterEvent(Event e) => PostJson("/register_game_event", e); + private static string UnregisterEvent(Event e) => PostJson("/remove_game_event", e); + private static string RegisterGame(Game game) => PostJson("/game_metadata", game); + private static string UnregisterGame(Game game) => PostJson("/remove_game", game); + private static string StopGame(Game game) => PostJson("/stop_game", game); + private static string SendHeartbeat(Game game) => PostJson("/game_heartbeat", game); + // ReSharper restore UnusedMember.Local + // ReSharper restore UnusedMethodReturnValue.Local +#pragma warning restore IDE0051 // Remove unused private members + + private static string PostJson(string urlSuffix, object o) + { + string payload = JsonSerializer.Serialize(o); + return _client.PostAsync(_baseUrl + urlSuffix, new StringContent(payload, Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Result; + } - if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - return CORE_PROPS_OSX; + private static string GetCorePropsPath() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + return Environment.ExpandEnvironmentVariables(CORE_PROPS_WINDOWS); - throw new InvalidOperationException("Unknown operating system."); - } + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + return CORE_PROPS_OSX; - #endregion + throw new InvalidOperationException("Unknown operating system."); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/Attribute/APIName.cs b/RGB.NET.Devices.SteelSeries/Attribute/APIName.cs index 50911452..dbf99311 100644 --- a/RGB.NET.Devices.SteelSeries/Attribute/APIName.cs +++ b/RGB.NET.Devices.SteelSeries/Attribute/APIName.cs @@ -1,20 +1,19 @@ -namespace RGB.NET.Devices.SteelSeries -{ - internal class APIName : System.Attribute - { - #region Properties & Fields +namespace RGB.NET.Devices.SteelSeries; - public string Name { get; set; } +internal class APIName : System.Attribute +{ + #region Properties & Fields - #endregion + public string Name { get; set; } - #region Constructors + #endregion - public APIName(string name) - { - this.Name = name; - } + #region Constructors - #endregion + public APIName(string name) + { + this.Name = name; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/Attribute/SteelSeriesEnumExtension.cs b/RGB.NET.Devices.SteelSeries/Attribute/SteelSeriesEnumExtension.cs index 3331a500..aef597b8 100644 --- a/RGB.NET.Devices.SteelSeries/Attribute/SteelSeriesEnumExtension.cs +++ b/RGB.NET.Devices.SteelSeries/Attribute/SteelSeriesEnumExtension.cs @@ -3,44 +3,43 @@ using System.Linq; using System.Reflection; -namespace RGB.NET.Devices.SteelSeries -{ - internal static class SteelSeriesEnumExtension - { - #region Properties & Fields - // ReSharper disable InconsistentNaming +namespace RGB.NET.Devices.SteelSeries; - private static readonly Dictionary _deviceTypeNames = new Dictionary(); - private static readonly Dictionary _ledIdNames = new Dictionary(); +internal static class SteelSeriesEnumExtension +{ + #region Properties & Fields + // ReSharper disable InconsistentNaming - // ReSharper restore InconsistentNaming - #endregion + private static readonly Dictionary _deviceTypeNames = new(); + private static readonly Dictionary _ledIdNames = new(); - #region Methods + // ReSharper restore InconsistentNaming + #endregion - internal static string GetAPIName(this SteelSeriesDeviceType deviceType) - { - if (!_deviceTypeNames.TryGetValue(deviceType, out string apiName)) - _deviceTypeNames.Add(deviceType, apiName = GetAPIName(typeof(SteelSeriesDeviceType), deviceType)); + #region Methods - return apiName; - } + internal static string? GetAPIName(this SteelSeriesDeviceType deviceType) + { + if (!_deviceTypeNames.TryGetValue(deviceType, out string? apiName)) + _deviceTypeNames.Add(deviceType, apiName = GetAPIName(typeof(SteelSeriesDeviceType), deviceType)); - internal static string GetAPIName(this SteelSeriesLedId ledId) - { - if (!_ledIdNames.TryGetValue(ledId, out string apiName)) - _ledIdNames.Add(ledId, apiName = GetAPIName(typeof(SteelSeriesLedId), ledId)); + return apiName; + } - return apiName; - } + internal static string? GetAPIName(this SteelSeriesLedId ledId) + { + if (!_ledIdNames.TryGetValue(ledId, out string? apiName)) + _ledIdNames.Add(ledId, apiName = GetAPIName(typeof(SteelSeriesLedId), ledId)); - private static string GetAPIName(Type type, Enum value) - { - MemberInfo[] memInfo = type.GetMember(value.ToString()); - if (memInfo.Length == 0) return null; - return (memInfo.FirstOrDefault()?.GetCustomAttributes(typeof(APIName), false).FirstOrDefault() as APIName)?.Name; - } + return apiName; + } - #endregion + private static string? GetAPIName(Type type, Enum value) + { + MemberInfo[] memInfo = type.GetMember(value.ToString()); + if (memInfo.Length == 0) return null; + return (memInfo.FirstOrDefault()?.GetCustomAttributes(typeof(APIName), false).FirstOrDefault() as APIName)?.Name; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/Enum/SteelSeriesDeviceType.cs b/RGB.NET.Devices.SteelSeries/Enum/SteelSeriesDeviceType.cs index 3e682263..f7774e89 100644 --- a/RGB.NET.Devices.SteelSeries/Enum/SteelSeriesDeviceType.cs +++ b/RGB.NET.Devices.SteelSeries/Enum/SteelSeriesDeviceType.cs @@ -1,45 +1,49 @@ -namespace RGB.NET.Devices.SteelSeries +#pragma warning disable 1591 + +namespace RGB.NET.Devices.SteelSeries; + +// DarthAffe 09.07.2020: Review the LISP-Handler in SteelSeriesSDK after adding new device-types! They need to be initialized. +public enum SteelSeriesDeviceType { - // DarthAffe 09.07.2020: Review the LISP-Handler in SteelSeriesSDK after adding new device-types! They need to be initialized. - public enum SteelSeriesDeviceType - { - [APIName("rgb-per-key-zones")] - PerKey, + [APIName("rgb-per-key-zones")] + PerKey, + + [APIName("rgb-1-zone")] + OneZone, - [APIName("rgb-1-zone")] - OneZone, + [APIName("rgb-2-zone")] + TwoZone, - [APIName("rgb-2-zone")] - TwoZone, + [APIName("rgb-3-zone")] + ThreeZone, - [APIName("rgb-3-zone")] - ThreeZone, + [APIName("rgb-4-zone")] + FourZone, - [APIName("rgb-4-zone")] - FourZone, + [APIName("rgb-5-zone")] + FiveZone, - [APIName("rgb-5-zone")] - FiveZone, + [APIName("rgb-6-zone")] + SixZone, - [APIName("rgb-6-zone")] - SixZone, + [APIName("rgb-7-zone")] + SevenZone, - [APIName("rgb-7-zone")] - SevenZone, + [APIName("rgb-8-zone")] + EightZone, - [APIName("rgb-8-zone")] - EightZone, + [APIName("rgb-10-zone")] + TenZone, - [APIName("rgb-12-zone")] - TwelveZone, + [APIName("rgb-12-zone")] + TwelveZone, - [APIName("rgb-17-zone")] - SeventeenZone, + [APIName("rgb-17-zone")] + SeventeenZone, - [APIName("rgb-24-zone")] - TwentyfourZone, + [APIName("rgb-24-zone")] + TwentyfourZone, - [APIName("rgb-103-zone")] - OneHundredAndThreeZone - } -} + [APIName("rgb-103-zone")] + OneHundredAndThreeZone +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/Enum/SteelSeriesLedId.cs b/RGB.NET.Devices.SteelSeries/Enum/SteelSeriesLedId.cs index 4c3baa1d..2402fcad 100644 --- a/RGB.NET.Devices.SteelSeries/Enum/SteelSeriesLedId.cs +++ b/RGB.NET.Devices.SteelSeries/Enum/SteelSeriesLedId.cs @@ -1,439 +1,450 @@ -namespace RGB.NET.Devices.SteelSeries +// ReSharper disable InconsistentNaming +#pragma warning disable 1591 + +namespace RGB.NET.Devices.SteelSeries; + +/// +/// Contains a list of Steel Series LED IDs +/// +public enum SteelSeriesLedId { - public enum SteelSeriesLedId - { - [APIName("one")] - ZoneOne, - [APIName("two")] - ZoneTwo, - [APIName("three")] - ZoneThree, - [APIName("four")] - ZoneFour, - [APIName("five")] - ZoneFive, - [APIName("six")] - ZoneSix, - [APIName("seven")] - ZoneSeven, - [APIName("eight")] - ZoneEight, - [APIName("nine")] - ZoneNine, - [APIName("ten")] - ZoneTen, - [APIName("eleven")] - ZoneEleven, - [APIName("twelve")] - ZoneTwelve, - [APIName("thirteen")] - ZoneThirteen, - [APIName("fourteen")] - ZoneFourteen, - [APIName("fifteen")] - ZoneFifteen, - [APIName("sixteen")] - ZoneSixteen, - [APIName("seventeen")] - ZoneSeventeen, - [APIName("eighteen")] - ZoneEighteen, - [APIName("nineteen")] - ZoneNineteen, - [APIName("twenty")] - ZoneTwenty, - [APIName("twenty-one")] - ZoneTwentyOne, - [APIName("twenty-two")] - ZoneTwentyTwo, - [APIName("twenty-three")] - ZoneTwentyThree, - [APIName("twenty-four")] - ZoneTwentyFour, - [APIName("twenty-five")] - ZoneTwentyFive, - [APIName("twenty-six")] - ZoneTwentySix, - [APIName("twenty-seven")] - ZoneTwentySeven, - [APIName("twenty-eight")] - ZoneTwentyEight, - [APIName("twenty-nine")] - ZoneTwentyNine, - [APIName("thirty")] - ZoneThirty, - [APIName("thirty-one")] - ZoneThirtyOne, - [APIName("thirty-two")] - ZoneThirtyTwo, - [APIName("thirty-three")] - ZoneThirtyThree, - [APIName("thirty-four")] - ZoneThirtyFour, - [APIName("thirty-five")] - ZoneThirtyFive, - [APIName("thirty-six")] - ZoneThirtySix, - [APIName("thirty-seven")] - ZoneThirtySeven, - [APIName("thirty-eight")] - ZoneThirtyEight, - [APIName("thirty-nine")] - ZoneThirtyNine, - [APIName("forty")] - ZoneForty, - [APIName("forty-one")] - ZoneFortyOne, - [APIName("forty-two")] - ZoneFortyTwo, - [APIName("forty-three")] - ZoneFortyThree, - [APIName("forty-four")] - ZoneFortyFour, - [APIName("forty-five")] - ZoneFortyFive, - [APIName("forty-six")] - ZoneFortySix, - [APIName("forty-seven")] - ZoneFortySeven, - [APIName("forty-eight")] - ZoneFortyEight, - [APIName("forty-nine")] - ZoneFortyNine, - [APIName("fifty")] - ZoneFifty, - [APIName("fifty-one")] - ZoneFiftyOne, - [APIName("fifty-two")] - ZoneFiftyTwo, - [APIName("fifty-three")] - ZoneFiftyThree, - [APIName("fifty-four")] - ZoneFiftyFour, - [APIName("fifty-five")] - ZoneFiftyFive, - [APIName("fifty-six")] - ZoneFiftySix, - [APIName("fifty-seven")] - ZoneFiftySeven, - [APIName("fifty-eight")] - ZoneFiftyEight, - [APIName("fifty-nine")] - ZoneFiftyNine, - [APIName("sixty")] - ZoneSixty, - [APIName("sixty-one")] - ZoneSixtyOne, - [APIName("sixty-two")] - ZoneSixtyTwo, - [APIName("sixty-three")] - ZoneSixtyThree, - [APIName("sixty-four")] - ZoneSixtyFour, - [APIName("sixty-five")] - ZoneSixtyFive, - [APIName("sixty-six")] - ZoneSixtySix, - [APIName("sixty-seven")] - ZoneSixtySeven, - [APIName("sixty-eight")] - ZoneSixtyEight, - [APIName("sixty-nine")] - ZoneSixtyNine, - [APIName("seventy")] - ZoneSeventy, - [APIName("seventy-one")] - ZoneSeventyOne, - [APIName("seventy-two")] - ZoneSeventyTwo, - [APIName("seventy-three")] - ZoneSeventyThree, - [APIName("seventy-four")] - ZoneSeventyFour, - [APIName("seventy-five")] - ZoneSeventyFive, - [APIName("seventy-six")] - ZoneSeventySix, - [APIName("seventy-seven")] - ZoneSeventySeven, - [APIName("seventy-eight")] - ZoneSeventyEight, - [APIName("seventy-nine")] - ZoneSeventyNine, - [APIName("eighty")] - ZoneEighty, - [APIName("eighty-one")] - ZoneEightyOne, - [APIName("eighty-two")] - ZoneEightyTwo, - [APIName("eighty-three")] - ZoneEightyThree, - [APIName("eighty-four")] - ZoneEightyFour, - [APIName("eighty-five")] - ZoneEightyFive, - [APIName("eighty-six")] - ZoneEightySix, - [APIName("eighty-seven")] - ZoneEightySeven, - [APIName("eighty-eight")] - ZoneEightyEight, - [APIName("eighty-nine")] - ZoneEightyNine, - [APIName("ninety")] - ZoneNinety, - [APIName("ninety-one")] - ZoneNinetyOne, - [APIName("ninety-two")] - ZoneNinetyTwo, - [APIName("ninety-three")] - ZoneNinetyThree, - [APIName("ninety-four")] - ZoneNinetyFour, - [APIName("ninety-five")] - ZoneNinetyFive, - [APIName("ninety-six")] - ZoneNinetySix, - [APIName("ninety-seven")] - ZoneNinetySeven, - [APIName("ninety-eight")] - ZoneNinetyEight, - [APIName("ninety-nine")] - ZoneNinetyNine, - [APIName("one-hundred")] - ZoneOneHundred, - [APIName("one-hundred-one")] - ZoneOneHundredOne, - [APIName("one-hundred-two")] - ZoneOneHundredTwo, - [APIName("one-hundred-three")] - ZoneOneHundredThree, + [APIName("one")] + ZoneOne, + [APIName("two")] + ZoneTwo, + [APIName("three")] + ZoneThree, + [APIName("four")] + ZoneFour, + [APIName("five")] + ZoneFive, + [APIName("six")] + ZoneSix, + [APIName("seven")] + ZoneSeven, + [APIName("eight")] + ZoneEight, + [APIName("nine")] + ZoneNine, + [APIName("ten")] + ZoneTen, + [APIName("eleven")] + ZoneEleven, + [APIName("twelve")] + ZoneTwelve, + [APIName("thirteen")] + ZoneThirteen, + [APIName("fourteen")] + ZoneFourteen, + [APIName("fifteen")] + ZoneFifteen, + [APIName("sixteen")] + ZoneSixteen, + [APIName("seventeen")] + ZoneSeventeen, + [APIName("eighteen")] + ZoneEighteen, + [APIName("nineteen")] + ZoneNineteen, + [APIName("twenty")] + ZoneTwenty, + [APIName("twenty-one")] + ZoneTwentyOne, + [APIName("twenty-two")] + ZoneTwentyTwo, + [APIName("twenty-three")] + ZoneTwentyThree, + [APIName("twenty-four")] + ZoneTwentyFour, + [APIName("twenty-five")] + ZoneTwentyFive, + [APIName("twenty-six")] + ZoneTwentySix, + [APIName("twenty-seven")] + ZoneTwentySeven, + [APIName("twenty-eight")] + ZoneTwentyEight, + [APIName("twenty-nine")] + ZoneTwentyNine, + [APIName("thirty")] + ZoneThirty, + [APIName("thirty-one")] + ZoneThirtyOne, + [APIName("thirty-two")] + ZoneThirtyTwo, + [APIName("thirty-three")] + ZoneThirtyThree, + [APIName("thirty-four")] + ZoneThirtyFour, + [APIName("thirty-five")] + ZoneThirtyFive, + [APIName("thirty-six")] + ZoneThirtySix, + [APIName("thirty-seven")] + ZoneThirtySeven, + [APIName("thirty-eight")] + ZoneThirtyEight, + [APIName("thirty-nine")] + ZoneThirtyNine, + [APIName("forty")] + ZoneForty, + [APIName("forty-one")] + ZoneFortyOne, + [APIName("forty-two")] + ZoneFortyTwo, + [APIName("forty-three")] + ZoneFortyThree, + [APIName("forty-four")] + ZoneFortyFour, + [APIName("forty-five")] + ZoneFortyFive, + [APIName("forty-six")] + ZoneFortySix, + [APIName("forty-seven")] + ZoneFortySeven, + [APIName("forty-eight")] + ZoneFortyEight, + [APIName("forty-nine")] + ZoneFortyNine, + [APIName("fifty")] + ZoneFifty, + [APIName("fifty-one")] + ZoneFiftyOne, + [APIName("fifty-two")] + ZoneFiftyTwo, + [APIName("fifty-three")] + ZoneFiftyThree, + [APIName("fifty-four")] + ZoneFiftyFour, + [APIName("fifty-five")] + ZoneFiftyFive, + [APIName("fifty-six")] + ZoneFiftySix, + [APIName("fifty-seven")] + ZoneFiftySeven, + [APIName("fifty-eight")] + ZoneFiftyEight, + [APIName("fifty-nine")] + ZoneFiftyNine, + [APIName("sixty")] + ZoneSixty, + [APIName("sixty-one")] + ZoneSixtyOne, + [APIName("sixty-two")] + ZoneSixtyTwo, + [APIName("sixty-three")] + ZoneSixtyThree, + [APIName("sixty-four")] + ZoneSixtyFour, + [APIName("sixty-five")] + ZoneSixtyFive, + [APIName("sixty-six")] + ZoneSixtySix, + [APIName("sixty-seven")] + ZoneSixtySeven, + [APIName("sixty-eight")] + ZoneSixtyEight, + [APIName("sixty-nine")] + ZoneSixtyNine, + [APIName("seventy")] + ZoneSeventy, + [APIName("seventy-one")] + ZoneSeventyOne, + [APIName("seventy-two")] + ZoneSeventyTwo, + [APIName("seventy-three")] + ZoneSeventyThree, + [APIName("seventy-four")] + ZoneSeventyFour, + [APIName("seventy-five")] + ZoneSeventyFive, + [APIName("seventy-six")] + ZoneSeventySix, + [APIName("seventy-seven")] + ZoneSeventySeven, + [APIName("seventy-eight")] + ZoneSeventyEight, + [APIName("seventy-nine")] + ZoneSeventyNine, + [APIName("eighty")] + ZoneEighty, + [APIName("eighty-one")] + ZoneEightyOne, + [APIName("eighty-two")] + ZoneEightyTwo, + [APIName("eighty-three")] + ZoneEightyThree, + [APIName("eighty-four")] + ZoneEightyFour, + [APIName("eighty-five")] + ZoneEightyFive, + [APIName("eighty-six")] + ZoneEightySix, + [APIName("eighty-seven")] + ZoneEightySeven, + [APIName("eighty-eight")] + ZoneEightyEight, + [APIName("eighty-nine")] + ZoneEightyNine, + [APIName("ninety")] + ZoneNinety, + [APIName("ninety-one")] + ZoneNinetyOne, + [APIName("ninety-two")] + ZoneNinetyTwo, + [APIName("ninety-three")] + ZoneNinetyThree, + [APIName("ninety-four")] + ZoneNinetyFour, + [APIName("ninety-five")] + ZoneNinetyFive, + [APIName("ninety-six")] + ZoneNinetySix, + [APIName("ninety-seven")] + ZoneNinetySeven, + [APIName("ninety-eight")] + ZoneNinetyEight, + [APIName("ninety-nine")] + ZoneNinetyNine, + [APIName("one-hundred")] + ZoneOneHundred, + [APIName("one-hundred-one")] + ZoneOneHundredOne, + [APIName("one-hundred-two")] + ZoneOneHundredTwo, + [APIName("one-hundred-three")] + ZoneOneHundredThree, - [APIName("logo")] - Logo, - [APIName("a")] - A, - [APIName("b")] - B, - [APIName("c")] - C, - [APIName("d")] - D, - [APIName("e")] - E, - [APIName("f")] - F, - [APIName("g")] - G, - [APIName("h")] - H, - [APIName("i")] - I, - [APIName("j")] - J, - [APIName("k")] - K, - [APIName("l")] - L, - [APIName("m")] - M, - [APIName("n")] - N, - [APIName("o")] - O, - [APIName("p")] - P, - [APIName("q")] - Q, - [APIName("r")] - R, - [APIName("s")] - S, - [APIName("t")] - T, - [APIName("u")] - U, - [APIName("v")] - V, - [APIName("w")] - W, - [APIName("x")] - X, - [APIName("y")] - Y, - [APIName("z")] - Z, - [APIName("keyboard-1")] - Keyboard1, - [APIName("keyboard-2")] - Keyboard2, - [APIName("keyboard-3")] - Keyboard3, - [APIName("keyboard-4")] - Keyboard4, - [APIName("keyboard-5")] - Keyboard5, - [APIName("keyboard-6")] - Keyboard6, - [APIName("keyboard-7")] - Keyboard7, - [APIName("keyboard-8")] - Keyboard8, - [APIName("keyboard-9")] - Keyboard9, - [APIName("keyboard-0")] - Keyboard0, - [APIName("return")] - Return, - [APIName("escape")] - Escape, - [APIName("backspace")] - Backspace, - [APIName("tab")] - Tab, - [APIName("spacebar")] - Spacebar, - [APIName("caps")] - Caps, - [APIName("dash")] - Dash, - [APIName("equal")] - Equal, - [APIName("l-bracket")] - LBracket, - [APIName("r-bracket")] - RBracket, - [APIName("backslash")] - Backslash, - [APIName("pound")] - Pound, - [APIName("semicolon")] - Semicolon, - [APIName("quote")] - Quote, - [APIName("backquote")] - Backqoute, - [APIName("comma")] - Comma, - [APIName("period")] - Period, - [APIName("slash")] - Slash, - [APIName("f1")] - F1, - [APIName("f2")] - F2, - [APIName("f3")] - F3, - [APIName("f4")] - F4, - [APIName("f5")] - F5, - [APIName("f6")] - F6, - [APIName("f7")] - F7, - [APIName("f8")] - F8, - [APIName("f9")] - F9, - [APIName("f10")] - F10, - [APIName("f11")] - F11, - [APIName("f12")] - F12, - [APIName("printscreen")] - PrintScreen, - [APIName("scrolllock")] - ScrollLock, - [APIName("pause")] - Pause, - [APIName("insert")] - Insert, - [APIName("home")] - Home, - [APIName("pageup")] - PageUp, - [APIName("delete")] - Delete, - [APIName("end")] - End, - [APIName("pagedown")] - PageDown, - [APIName("rightarrow")] - RightArrow, - [APIName("leftarrow")] - LeftArrow, - [APIName("downarrow")] - DownArrow, - [APIName("uparrow")] - UpArrow, - [APIName("keypad-num-lock")] - KeypadNumLock, - [APIName("keypad-divide")] - KeypadDivide, - [APIName("keypad-times")] - KeypadTimes, - [APIName("keypad-minus")] - KeypadMinus, - [APIName("keypad-plus")] - KeypadPlus, - [APIName("keypad-enter")] - KeypadEnter, - [APIName("keypad-period")] - KeypadPeriod, - [APIName("keypad-1")] - Keypad1, - [APIName("keypad-2")] - Keypad2, - [APIName("keypad-3")] - Keypad3, - [APIName("keypad-4")] - Keypad4, - [APIName("keypad-5")] - Keypad5, - [APIName("keypad-6")] - Keypad6, - [APIName("keypad-7")] - Keypad7, - [APIName("keypad-8")] - Keypad8, - [APIName("keypad-9")] - Keypad9, - [APIName("keypad-0")] - Keypad0, - [APIName("l-ctrl")] - LCtrl, - [APIName("l-shift")] - LShift, - [APIName("l-alt")] - LAlt, - [APIName("l-win")] - LWin, - [APIName("r-ctrl")] - RCtrl, - [APIName("r-shift")] - RShift, - [APIName("r-alt")] - RAlt, - [APIName("r-win")] - RWin, - [APIName("ss-key")] - SSKey, - [APIName("win-menu")] - WinMenu, - [APIName("m0")] - M0, - [APIName("m1")] - M1, - [APIName("m2")] - M2, - [APIName("m3")] - M3, - [APIName("m4")] - M4, - [APIName("m5")] - M5, - } -} + [APIName("logo")] + Logo, + [APIName("a")] + A, + [APIName("b")] + B, + [APIName("c")] + C, + [APIName("d")] + D, + [APIName("e")] + E, + [APIName("f")] + F, + [APIName("g")] + G, + [APIName("h")] + H, + [APIName("i")] + I, + [APIName("j")] + J, + [APIName("k")] + K, + [APIName("l")] + L, + [APIName("m")] + M, + [APIName("n")] + N, + [APIName("o")] + O, + [APIName("p")] + P, + [APIName("q")] + Q, + [APIName("r")] + R, + [APIName("s")] + S, + [APIName("t")] + T, + [APIName("u")] + U, + [APIName("v")] + V, + [APIName("w")] + W, + [APIName("x")] + X, + [APIName("y")] + Y, + [APIName("z")] + Z, + [APIName("keyboard-1")] + Keyboard1, + [APIName("keyboard-2")] + Keyboard2, + [APIName("keyboard-3")] + Keyboard3, + [APIName("keyboard-4")] + Keyboard4, + [APIName("keyboard-5")] + Keyboard5, + [APIName("keyboard-6")] + Keyboard6, + [APIName("keyboard-7")] + Keyboard7, + [APIName("keyboard-8")] + Keyboard8, + [APIName("keyboard-9")] + Keyboard9, + [APIName("keyboard-0")] + Keyboard0, + [APIName("return")] + Return, + [APIName("escape")] + Escape, + [APIName("backspace")] + Backspace, + [APIName("tab")] + Tab, + [APIName("spacebar")] + Spacebar, + [APIName("caps")] + Caps, + [APIName("dash")] + Dash, + [APIName("equal")] + Equal, + [APIName("l-bracket")] + LBracket, + [APIName("r-bracket")] + RBracket, + [APIName("backslash")] + Backslash, + [APIName("non-us-backslash")] + NonUsBackslash, // DarthAffe 22.02.2022: Custom name since that one is missing in the original key names + [APIName("pound")] + Pound, + [APIName("semicolon")] + Semicolon, + [APIName("quote")] + Quote, + [APIName("backquote")] + Backqoute, + [APIName("comma")] + Comma, + [APIName("period")] + Period, + [APIName("slash")] + Slash, + [APIName("f1")] + F1, + [APIName("f2")] + F2, + [APIName("f3")] + F3, + [APIName("f4")] + F4, + [APIName("f5")] + F5, + [APIName("f6")] + F6, + [APIName("f7")] + F7, + [APIName("f8")] + F8, + [APIName("f9")] + F9, + [APIName("f10")] + F10, + [APIName("f11")] + F11, + [APIName("f12")] + F12, + [APIName("printscreen")] + PrintScreen, + [APIName("scrolllock")] + ScrollLock, + [APIName("pause")] + Pause, + [APIName("insert")] + Insert, + [APIName("home")] + Home, + [APIName("pageup")] + PageUp, + [APIName("delete")] + Delete, + [APIName("end")] + End, + [APIName("pagedown")] + PageDown, + [APIName("rightarrow")] + RightArrow, + [APIName("leftarrow")] + LeftArrow, + [APIName("downarrow")] + DownArrow, + [APIName("uparrow")] + UpArrow, + [APIName("keypad-num-lock")] + KeypadNumLock, + [APIName("keypad-divide")] + KeypadDivide, + [APIName("keypad-times")] + KeypadTimes, + [APIName("keypad-minus")] + KeypadMinus, + [APIName("keypad-plus")] + KeypadPlus, + [APIName("keypad-enter")] + KeypadEnter, + [APIName("keypad-period")] + KeypadPeriod, + [APIName("keypad-1")] + Keypad1, + [APIName("keypad-2")] + Keypad2, + [APIName("keypad-3")] + Keypad3, + [APIName("keypad-4")] + Keypad4, + [APIName("num-5")] //HACK DarthAffe 07.10.2021: Custom name to workaround a SDK-issue (https://github.com/SteelSeries/gamesense-sdk/issues/85) should normally be 'keypad-5' + Keypad5, + [APIName("keypad-6")] + Keypad6, + [APIName("keypad-7")] + Keypad7, + [APIName("keypad-8")] + Keypad8, + [APIName("keypad-9")] + Keypad9, + [APIName("keypad-0")] + Keypad0, + [APIName("l-ctrl")] + LCtrl, + [APIName("l-shift")] + LShift, + [APIName("l-alt")] + LAlt, + [APIName("l-win")] + LWin, + [APIName("r-ctrl")] + RCtrl, + [APIName("r-shift")] + RShift, + [APIName("r-alt")] + RAlt, + [APIName("r-win")] + RWin, + [APIName("ss-key")] + SSKey, + [APIName("win-menu")] + WinMenu, + [APIName("m0")] + M0, + [APIName("m1")] + M1, + [APIName("m2")] + M2, + [APIName("m3")] + M3, + [APIName("m4")] + M4, + [APIName("m5")] + M5, + [APIName("fn")] + Fn, + [APIName("power")] + Power, +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs b/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs index 57364d9d..86948692 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/ISteelSeriesRGBDevice.cs @@ -1,13 +1,9 @@ -using System.Collections.Generic; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.SteelSeries -{ - /// - /// Represents a steelseries RGB-device. - /// - internal interface ISteelSeriesRGBDevice : IRGBDevice - { - void Initialize(UpdateQueue updateQueue, Dictionary ledMapping); - } -} +namespace RGB.NET.Devices.SteelSeries; + +/// +/// Represents a steelseries RGB-device. +/// +internal interface ISteelSeriesRGBDevice : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/Generic/LedMappings.cs b/RGB.NET.Devices.SteelSeries/Generic/LedMappings.cs new file mode 100644 index 00000000..da55ac2d --- /dev/null +++ b/RGB.NET.Devices.SteelSeries/Generic/LedMappings.cs @@ -0,0 +1,523 @@ +using RGB.NET.Core; + +namespace RGB.NET.Devices.SteelSeries; + +/// +/// Contains mappings for to . +/// +public static class LedMappings +{ + /// + /// Gets the uk-mapping for keyboards. + /// + public static LedMapping KeyboardMappingUk { get; } = new() + { + { LedId.Logo, SteelSeriesLedId.Logo }, + { LedId.Keyboard_Escape, SteelSeriesLedId.Escape }, + { LedId.Keyboard_F1, SteelSeriesLedId.F1 }, + { LedId.Keyboard_F2, SteelSeriesLedId.F2 }, + { LedId.Keyboard_F3, SteelSeriesLedId.F3 }, + { LedId.Keyboard_F4, SteelSeriesLedId.F4 }, + { LedId.Keyboard_F5, SteelSeriesLedId.F5 }, + { LedId.Keyboard_F6, SteelSeriesLedId.F6 }, + { LedId.Keyboard_F7, SteelSeriesLedId.F7 }, + { LedId.Keyboard_F8, SteelSeriesLedId.F8 }, + { LedId.Keyboard_F9, SteelSeriesLedId.F9 }, + { LedId.Keyboard_F10, SteelSeriesLedId.F10 }, + { LedId.Keyboard_F11, SteelSeriesLedId.F11 }, + { LedId.Keyboard_GraveAccentAndTilde, SteelSeriesLedId.Backqoute }, + { LedId.Keyboard_1, SteelSeriesLedId.Keyboard1 }, + { LedId.Keyboard_2, SteelSeriesLedId.Keyboard2 }, + { LedId.Keyboard_3, SteelSeriesLedId.Keyboard3 }, + { LedId.Keyboard_4, SteelSeriesLedId.Keyboard4 }, + { LedId.Keyboard_5, SteelSeriesLedId.Keyboard5 }, + { LedId.Keyboard_6, SteelSeriesLedId.Keyboard6 }, + { LedId.Keyboard_7, SteelSeriesLedId.Keyboard7 }, + { LedId.Keyboard_8, SteelSeriesLedId.Keyboard8 }, + { LedId.Keyboard_9, SteelSeriesLedId.Keyboard9 }, + { LedId.Keyboard_0, SteelSeriesLedId.Keyboard0 }, + { LedId.Keyboard_MinusAndUnderscore, SteelSeriesLedId.Dash }, + { LedId.Keyboard_Tab, SteelSeriesLedId.Tab }, + { LedId.Keyboard_Q, SteelSeriesLedId.Q }, + { LedId.Keyboard_W, SteelSeriesLedId.W }, + { LedId.Keyboard_E, SteelSeriesLedId.E }, + { LedId.Keyboard_R, SteelSeriesLedId.R }, + { LedId.Keyboard_T, SteelSeriesLedId.T }, + { LedId.Keyboard_Y, SteelSeriesLedId.Y }, + { LedId.Keyboard_U, SteelSeriesLedId.U }, + { LedId.Keyboard_I, SteelSeriesLedId.I }, + { LedId.Keyboard_O, SteelSeriesLedId.O }, + { LedId.Keyboard_P, SteelSeriesLedId.P }, + { LedId.Keyboard_BracketLeft, SteelSeriesLedId.LBracket }, + { LedId.Keyboard_CapsLock, SteelSeriesLedId.Caps }, + { LedId.Keyboard_A, SteelSeriesLedId.A }, + { LedId.Keyboard_S, SteelSeriesLedId.S }, + { LedId.Keyboard_D, SteelSeriesLedId.D }, + { LedId.Keyboard_F, SteelSeriesLedId.F }, + { LedId.Keyboard_G, SteelSeriesLedId.G }, + { LedId.Keyboard_H, SteelSeriesLedId.H }, + { LedId.Keyboard_J, SteelSeriesLedId.J }, + { LedId.Keyboard_K, SteelSeriesLedId.K }, + { LedId.Keyboard_L, SteelSeriesLedId.L }, + { LedId.Keyboard_SemicolonAndColon, SteelSeriesLedId.Semicolon }, + { LedId.Keyboard_ApostropheAndDoubleQuote, SteelSeriesLedId.Quote }, + { LedId.Keyboard_LeftShift, SteelSeriesLedId.LShift }, + { LedId.Keyboard_NonUsTilde, SteelSeriesLedId.Pound }, + { LedId.Keyboard_NonUsBackslash, SteelSeriesLedId.NonUsBackslash }, + { LedId.Keyboard_Z, SteelSeriesLedId.Z }, + { LedId.Keyboard_X, SteelSeriesLedId.X }, + { LedId.Keyboard_C, SteelSeriesLedId.C }, + { LedId.Keyboard_V, SteelSeriesLedId.V }, + { LedId.Keyboard_B, SteelSeriesLedId.B }, + { LedId.Keyboard_N, SteelSeriesLedId.N }, + { LedId.Keyboard_M, SteelSeriesLedId.M }, + { LedId.Keyboard_CommaAndLessThan, SteelSeriesLedId.Comma }, + { LedId.Keyboard_PeriodAndBiggerThan, SteelSeriesLedId.Period }, + { LedId.Keyboard_SlashAndQuestionMark, SteelSeriesLedId.Slash }, + { LedId.Keyboard_LeftCtrl, SteelSeriesLedId.LCtrl }, + { LedId.Keyboard_LeftGui, SteelSeriesLedId.LWin }, + { LedId.Keyboard_LeftAlt, SteelSeriesLedId.LAlt }, + { LedId.Keyboard_Space, SteelSeriesLedId.Spacebar }, + { LedId.Keyboard_RightAlt, SteelSeriesLedId.RAlt }, + { LedId.Keyboard_RightGui, SteelSeriesLedId.RWin }, + { LedId.Keyboard_Application, SteelSeriesLedId.SSKey }, + { LedId.Keyboard_F12, SteelSeriesLedId.F12 }, + { LedId.Keyboard_PrintScreen, SteelSeriesLedId.PrintScreen }, + { LedId.Keyboard_ScrollLock, SteelSeriesLedId.ScrollLock }, + { LedId.Keyboard_PauseBreak, SteelSeriesLedId.Pause }, + { LedId.Keyboard_Insert, SteelSeriesLedId.Insert }, + { LedId.Keyboard_Home, SteelSeriesLedId.Home }, + { LedId.Keyboard_PageUp, SteelSeriesLedId.PageUp }, + { LedId.Keyboard_BracketRight, SteelSeriesLedId.RBracket }, + { LedId.Keyboard_Backslash, SteelSeriesLedId.Backslash }, + { LedId.Keyboard_Enter, SteelSeriesLedId.Return }, + { LedId.Keyboard_EqualsAndPlus, SteelSeriesLedId.Equal }, + { LedId.Keyboard_Backspace, SteelSeriesLedId.Backspace }, + { LedId.Keyboard_Delete, SteelSeriesLedId.Delete }, + { LedId.Keyboard_End, SteelSeriesLedId.End }, + { LedId.Keyboard_PageDown, SteelSeriesLedId.PageDown }, + { LedId.Keyboard_RightShift, SteelSeriesLedId.RShift }, + { LedId.Keyboard_RightCtrl, SteelSeriesLedId.RCtrl }, + { LedId.Keyboard_ArrowUp, SteelSeriesLedId.UpArrow }, + { LedId.Keyboard_ArrowLeft, SteelSeriesLedId.LeftArrow }, + { LedId.Keyboard_ArrowDown, SteelSeriesLedId.DownArrow }, + { LedId.Keyboard_ArrowRight, SteelSeriesLedId.RightArrow }, + { LedId.Keyboard_NumLock, SteelSeriesLedId.KeypadNumLock }, + { LedId.Keyboard_NumSlash, SteelSeriesLedId.KeypadDivide }, + { LedId.Keyboard_NumAsterisk, SteelSeriesLedId.KeypadTimes }, + { LedId.Keyboard_NumMinus, SteelSeriesLedId.KeypadMinus }, + { LedId.Keyboard_NumPlus, SteelSeriesLedId.KeypadPlus }, + { LedId.Keyboard_NumEnter, SteelSeriesLedId.KeypadEnter }, + { LedId.Keyboard_Num7, SteelSeriesLedId.Keypad7 }, + { LedId.Keyboard_Num8, SteelSeriesLedId.Keypad8 }, + { LedId.Keyboard_Num9, SteelSeriesLedId.Keypad9 }, + { LedId.Keyboard_Num4, SteelSeriesLedId.Keypad4 }, + { LedId.Keyboard_Num5, SteelSeriesLedId.Keypad5 }, + { LedId.Keyboard_Num6, SteelSeriesLedId.Keypad6 }, + { LedId.Keyboard_Num1, SteelSeriesLedId.Keypad1 }, + { LedId.Keyboard_Num2, SteelSeriesLedId.Keypad2 }, + { LedId.Keyboard_Num3, SteelSeriesLedId.Keypad3 }, + { LedId.Keyboard_Num0, SteelSeriesLedId.Keypad0 }, + { LedId.Keyboard_NumPeriodAndDelete, SteelSeriesLedId.KeypadPeriod } + }; + + /// + /// Gets the uk-tkl-mapping for keyboards. + /// + public static LedMapping KeyboardTklMappingUk { get; } = new() + { + { LedId.Logo, SteelSeriesLedId.Logo }, + { LedId.Keyboard_Escape, SteelSeriesLedId.Escape }, + { LedId.Keyboard_F1, SteelSeriesLedId.F1 }, + { LedId.Keyboard_F2, SteelSeriesLedId.F2 }, + { LedId.Keyboard_F3, SteelSeriesLedId.F3 }, + { LedId.Keyboard_F4, SteelSeriesLedId.F4 }, + { LedId.Keyboard_F5, SteelSeriesLedId.F5 }, + { LedId.Keyboard_F6, SteelSeriesLedId.F6 }, + { LedId.Keyboard_F7, SteelSeriesLedId.F7 }, + { LedId.Keyboard_F8, SteelSeriesLedId.F8 }, + { LedId.Keyboard_F9, SteelSeriesLedId.F9 }, + { LedId.Keyboard_F10, SteelSeriesLedId.F10 }, + { LedId.Keyboard_F11, SteelSeriesLedId.F11 }, + { LedId.Keyboard_GraveAccentAndTilde, SteelSeriesLedId.Backqoute }, + { LedId.Keyboard_1, SteelSeriesLedId.Keyboard1 }, + { LedId.Keyboard_2, SteelSeriesLedId.Keyboard2 }, + { LedId.Keyboard_3, SteelSeriesLedId.Keyboard3 }, + { LedId.Keyboard_4, SteelSeriesLedId.Keyboard4 }, + { LedId.Keyboard_5, SteelSeriesLedId.Keyboard5 }, + { LedId.Keyboard_6, SteelSeriesLedId.Keyboard6 }, + { LedId.Keyboard_7, SteelSeriesLedId.Keyboard7 }, + { LedId.Keyboard_8, SteelSeriesLedId.Keyboard8 }, + { LedId.Keyboard_9, SteelSeriesLedId.Keyboard9 }, + { LedId.Keyboard_0, SteelSeriesLedId.Keyboard0 }, + { LedId.Keyboard_MinusAndUnderscore, SteelSeriesLedId.Dash }, + { LedId.Keyboard_Tab, SteelSeriesLedId.Tab }, + { LedId.Keyboard_Q, SteelSeriesLedId.Q }, + { LedId.Keyboard_W, SteelSeriesLedId.W }, + { LedId.Keyboard_E, SteelSeriesLedId.E }, + { LedId.Keyboard_R, SteelSeriesLedId.R }, + { LedId.Keyboard_T, SteelSeriesLedId.T }, + { LedId.Keyboard_Y, SteelSeriesLedId.Y }, + { LedId.Keyboard_U, SteelSeriesLedId.U }, + { LedId.Keyboard_I, SteelSeriesLedId.I }, + { LedId.Keyboard_O, SteelSeriesLedId.O }, + { LedId.Keyboard_P, SteelSeriesLedId.P }, + { LedId.Keyboard_BracketLeft, SteelSeriesLedId.LBracket }, + { LedId.Keyboard_CapsLock, SteelSeriesLedId.Caps }, + { LedId.Keyboard_A, SteelSeriesLedId.A }, + { LedId.Keyboard_S, SteelSeriesLedId.S }, + { LedId.Keyboard_D, SteelSeriesLedId.D }, + { LedId.Keyboard_F, SteelSeriesLedId.F }, + { LedId.Keyboard_G, SteelSeriesLedId.G }, + { LedId.Keyboard_H, SteelSeriesLedId.H }, + { LedId.Keyboard_J, SteelSeriesLedId.J }, + { LedId.Keyboard_K, SteelSeriesLedId.K }, + { LedId.Keyboard_L, SteelSeriesLedId.L }, + { LedId.Keyboard_SemicolonAndColon, SteelSeriesLedId.Semicolon }, + { LedId.Keyboard_ApostropheAndDoubleQuote, SteelSeriesLedId.Quote }, + { LedId.Keyboard_LeftShift, SteelSeriesLedId.LShift }, + { LedId.Keyboard_NonUsTilde, SteelSeriesLedId.Pound }, + { LedId.Keyboard_Z, SteelSeriesLedId.Z }, + { LedId.Keyboard_X, SteelSeriesLedId.X }, + { LedId.Keyboard_C, SteelSeriesLedId.C }, + { LedId.Keyboard_V, SteelSeriesLedId.V }, + { LedId.Keyboard_B, SteelSeriesLedId.B }, + { LedId.Keyboard_N, SteelSeriesLedId.N }, + { LedId.Keyboard_M, SteelSeriesLedId.M }, + { LedId.Keyboard_CommaAndLessThan, SteelSeriesLedId.Comma }, + { LedId.Keyboard_PeriodAndBiggerThan, SteelSeriesLedId.Period }, + { LedId.Keyboard_SlashAndQuestionMark, SteelSeriesLedId.Slash }, + { LedId.Keyboard_LeftCtrl, SteelSeriesLedId.LCtrl }, + { LedId.Keyboard_LeftGui, SteelSeriesLedId.LWin }, + { LedId.Keyboard_LeftAlt, SteelSeriesLedId.LAlt }, + { LedId.Keyboard_Space, SteelSeriesLedId.Spacebar }, + { LedId.Keyboard_RightAlt, SteelSeriesLedId.RAlt }, + { LedId.Keyboard_RightGui, SteelSeriesLedId.RWin }, + { LedId.Keyboard_Application, SteelSeriesLedId.SSKey }, + { LedId.Keyboard_F12, SteelSeriesLedId.F12 }, + { LedId.Keyboard_PrintScreen, SteelSeriesLedId.PrintScreen }, + { LedId.Keyboard_ScrollLock, SteelSeriesLedId.ScrollLock }, + { LedId.Keyboard_PauseBreak, SteelSeriesLedId.Pause }, + { LedId.Keyboard_Insert, SteelSeriesLedId.Insert }, + { LedId.Keyboard_Home, SteelSeriesLedId.Home }, + { LedId.Keyboard_PageUp, SteelSeriesLedId.PageUp }, + { LedId.Keyboard_BracketRight, SteelSeriesLedId.RBracket }, + { LedId.Keyboard_Backslash, SteelSeriesLedId.Backslash }, + { LedId.Keyboard_Enter, SteelSeriesLedId.Return }, + { LedId.Keyboard_EqualsAndPlus, SteelSeriesLedId.Equal }, + { LedId.Keyboard_Backspace, SteelSeriesLedId.Backspace }, + { LedId.Keyboard_Delete, SteelSeriesLedId.Delete }, + { LedId.Keyboard_End, SteelSeriesLedId.End }, + { LedId.Keyboard_PageDown, SteelSeriesLedId.PageDown }, + { LedId.Keyboard_RightShift, SteelSeriesLedId.RShift }, + { LedId.Keyboard_RightCtrl, SteelSeriesLedId.RCtrl }, + { LedId.Keyboard_ArrowUp, SteelSeriesLedId.UpArrow }, + { LedId.Keyboard_ArrowLeft, SteelSeriesLedId.LeftArrow }, + { LedId.Keyboard_ArrowDown, SteelSeriesLedId.DownArrow }, + { LedId.Keyboard_ArrowRight, SteelSeriesLedId.RightArrow } + }; + + /// + /// Gets the uk-notebook-mapping for keyboards. + /// + public static LedMapping KeyboardNotebookMappingUk { get; } = new() + { + { LedId.Logo, SteelSeriesLedId.Logo }, + { LedId.Keyboard_Escape, SteelSeriesLedId.Escape }, + { LedId.Keyboard_F1, SteelSeriesLedId.F1 }, + { LedId.Keyboard_F2, SteelSeriesLedId.F2 }, + { LedId.Keyboard_F3, SteelSeriesLedId.F3 }, + { LedId.Keyboard_F4, SteelSeriesLedId.F4 }, + { LedId.Keyboard_F5, SteelSeriesLedId.F5 }, + { LedId.Keyboard_F6, SteelSeriesLedId.F6 }, + { LedId.Keyboard_F7, SteelSeriesLedId.F7 }, + { LedId.Keyboard_F8, SteelSeriesLedId.F8 }, + { LedId.Keyboard_F9, SteelSeriesLedId.F9 }, + { LedId.Keyboard_F10, SteelSeriesLedId.F10 }, + { LedId.Keyboard_F11, SteelSeriesLedId.F11 }, + { LedId.Keyboard_GraveAccentAndTilde, SteelSeriesLedId.Backqoute }, + { LedId.Keyboard_1, SteelSeriesLedId.Keyboard1 }, + { LedId.Keyboard_2, SteelSeriesLedId.Keyboard2 }, + { LedId.Keyboard_3, SteelSeriesLedId.Keyboard3 }, + { LedId.Keyboard_4, SteelSeriesLedId.Keyboard4 }, + { LedId.Keyboard_5, SteelSeriesLedId.Keyboard5 }, + { LedId.Keyboard_6, SteelSeriesLedId.Keyboard6 }, + { LedId.Keyboard_7, SteelSeriesLedId.Keyboard7 }, + { LedId.Keyboard_8, SteelSeriesLedId.Keyboard8 }, + { LedId.Keyboard_9, SteelSeriesLedId.Keyboard9 }, + { LedId.Keyboard_0, SteelSeriesLedId.Keyboard0 }, + { LedId.Keyboard_MinusAndUnderscore, SteelSeriesLedId.Dash }, + { LedId.Keyboard_Tab, SteelSeriesLedId.Tab }, + { LedId.Keyboard_Q, SteelSeriesLedId.Q }, + { LedId.Keyboard_W, SteelSeriesLedId.W }, + { LedId.Keyboard_E, SteelSeriesLedId.E }, + { LedId.Keyboard_R, SteelSeriesLedId.R }, + { LedId.Keyboard_T, SteelSeriesLedId.T }, + { LedId.Keyboard_Y, SteelSeriesLedId.Y }, + { LedId.Keyboard_U, SteelSeriesLedId.U }, + { LedId.Keyboard_I, SteelSeriesLedId.I }, + { LedId.Keyboard_O, SteelSeriesLedId.O }, + { LedId.Keyboard_P, SteelSeriesLedId.P }, + { LedId.Keyboard_BracketLeft, SteelSeriesLedId.LBracket }, + { LedId.Keyboard_CapsLock, SteelSeriesLedId.Caps }, + { LedId.Keyboard_A, SteelSeriesLedId.A }, + { LedId.Keyboard_S, SteelSeriesLedId.S }, + { LedId.Keyboard_D, SteelSeriesLedId.D }, + { LedId.Keyboard_F, SteelSeriesLedId.F }, + { LedId.Keyboard_G, SteelSeriesLedId.G }, + { LedId.Keyboard_H, SteelSeriesLedId.H }, + { LedId.Keyboard_J, SteelSeriesLedId.J }, + { LedId.Keyboard_K, SteelSeriesLedId.K }, + { LedId.Keyboard_L, SteelSeriesLedId.L }, + { LedId.Keyboard_SemicolonAndColon, SteelSeriesLedId.Semicolon }, + { LedId.Keyboard_ApostropheAndDoubleQuote, SteelSeriesLedId.Quote }, + { LedId.Keyboard_LeftShift, SteelSeriesLedId.LShift }, + { LedId.Keyboard_NonUsTilde, SteelSeriesLedId.Pound }, + { LedId.Keyboard_Z, SteelSeriesLedId.Z }, + { LedId.Keyboard_X, SteelSeriesLedId.X }, + { LedId.Keyboard_C, SteelSeriesLedId.C }, + { LedId.Keyboard_V, SteelSeriesLedId.V }, + { LedId.Keyboard_B, SteelSeriesLedId.B }, + { LedId.Keyboard_N, SteelSeriesLedId.N }, + { LedId.Keyboard_M, SteelSeriesLedId.M }, + { LedId.Keyboard_CommaAndLessThan, SteelSeriesLedId.Comma }, + { LedId.Keyboard_PeriodAndBiggerThan, SteelSeriesLedId.Period }, + { LedId.Keyboard_SlashAndQuestionMark, SteelSeriesLedId.Slash }, + { LedId.Keyboard_LeftCtrl, SteelSeriesLedId.LCtrl }, + { LedId.Keyboard_LeftGui, SteelSeriesLedId.LWin }, + { LedId.Keyboard_LeftAlt, SteelSeriesLedId.LAlt }, + { LedId.Keyboard_Space, SteelSeriesLedId.Spacebar }, + { LedId.Keyboard_RightAlt, SteelSeriesLedId.RAlt }, + { LedId.Keyboard_RightGui, SteelSeriesLedId.RWin }, + { LedId.Keyboard_Application, SteelSeriesLedId.SSKey }, + { LedId.Keyboard_F12, SteelSeriesLedId.F12 }, + { LedId.Keyboard_PrintScreen, SteelSeriesLedId.PrintScreen }, + { LedId.Keyboard_ScrollLock, SteelSeriesLedId.ScrollLock }, + { LedId.Keyboard_PauseBreak, SteelSeriesLedId.Pause }, + { LedId.Keyboard_Insert, SteelSeriesLedId.Insert }, + { LedId.Keyboard_Home, SteelSeriesLedId.Home }, + { LedId.Keyboard_PageUp, SteelSeriesLedId.PageUp }, + { LedId.Keyboard_BracketRight, SteelSeriesLedId.RBracket }, + { LedId.Keyboard_Backslash, SteelSeriesLedId.Backslash }, + { LedId.Keyboard_Enter, SteelSeriesLedId.Return }, + { LedId.Keyboard_EqualsAndPlus, SteelSeriesLedId.Equal }, + { LedId.Keyboard_Backspace, SteelSeriesLedId.Backspace }, + { LedId.Keyboard_Delete, SteelSeriesLedId.Delete }, + { LedId.Keyboard_End, SteelSeriesLedId.End }, + { LedId.Keyboard_PageDown, SteelSeriesLedId.PageDown }, + { LedId.Keyboard_RightShift, SteelSeriesLedId.RShift }, + { LedId.Keyboard_RightCtrl, SteelSeriesLedId.RCtrl }, + { LedId.Keyboard_ArrowUp, SteelSeriesLedId.UpArrow }, + { LedId.Keyboard_ArrowLeft, SteelSeriesLedId.LeftArrow }, + { LedId.Keyboard_ArrowDown, SteelSeriesLedId.DownArrow }, + { LedId.Keyboard_ArrowRight, SteelSeriesLedId.RightArrow }, + { LedId.Keyboard_Function, SteelSeriesLedId.Fn }, + { LedId.Keyboard_Custom1, SteelSeriesLedId.Power }, + }; + + /// + /// Gets the mapping for one-zone mice. + /// + public static LedMapping MouseOneZone { get; } = new() + { + { LedId.Mouse1, SteelSeriesLedId.ZoneOne } + }; + + /// + /// Gets the mapping for two-zone mice. + /// + public static LedMapping MouseTwoZone { get; } = new() + { + { LedId.Mouse1, SteelSeriesLedId.ZoneOne }, + { LedId.Mouse2, SteelSeriesLedId.ZoneTwo } + }; + + /// + /// Gets the mapping for three-zone mice. + /// + public static LedMapping MouseThreeZone { get; } = new() + { + { LedId.Mouse1, SteelSeriesLedId.ZoneOne }, + { LedId.Mouse2, SteelSeriesLedId.ZoneTwo }, + { LedId.Mouse3, SteelSeriesLedId.ZoneThree } + }; + + /// + /// Gets the mapping for eight-zone mice. + /// + public static LedMapping MouseEightZone { get; } = new() + { + { LedId.Mouse1, SteelSeriesLedId.ZoneOne }, + { LedId.Mouse2, SteelSeriesLedId.ZoneTwo }, + { LedId.Mouse3, SteelSeriesLedId.ZoneThree }, + { LedId.Mouse4, SteelSeriesLedId.ZoneFour }, + { LedId.Mouse5, SteelSeriesLedId.ZoneFive }, + { LedId.Mouse6, SteelSeriesLedId.ZoneSix }, + { LedId.Mouse7, SteelSeriesLedId.ZoneSeven }, + { LedId.Mouse8, SteelSeriesLedId.ZoneEight } + }; + + /// + /// Gets the mapping for ten-zone mice. + /// + public static LedMapping MouseTenZone { get; } = new() + { + { LedId.Mouse1, SteelSeriesLedId.ZoneOne }, + { LedId.Mouse2, SteelSeriesLedId.ZoneTwo }, + { LedId.Mouse3, SteelSeriesLedId.ZoneThree }, + { LedId.Mouse4, SteelSeriesLedId.ZoneFour }, + { LedId.Mouse5, SteelSeriesLedId.ZoneFive }, + { LedId.Mouse6, SteelSeriesLedId.ZoneSix }, + { LedId.Mouse7, SteelSeriesLedId.ZoneSeven }, + { LedId.Mouse8, SteelSeriesLedId.ZoneEight }, + { LedId.Mouse9, SteelSeriesLedId.ZoneNine }, + { LedId.Mouse10, SteelSeriesLedId.ZoneTen } + }; + + /// + /// Gets the mapping for two-zone headsets. + /// + public static LedMapping HeadsetTwoZone { get; } = new() + { + { LedId.Headset1, SteelSeriesLedId.ZoneOne }, + { LedId.Headset2, SteelSeriesLedId.ZoneTwo } + }; + + /// + /// Gets the mapping for twelve-zone mousepads + /// + public static LedMapping MousepadTwelveZone { get; } = new() + { + { LedId.Mousepad1, SteelSeriesLedId.ZoneOne }, + { LedId.Mousepad2, SteelSeriesLedId.ZoneTwo }, + { LedId.Mousepad3, SteelSeriesLedId.ZoneThree }, + { LedId.Mousepad4, SteelSeriesLedId.ZoneFour }, + { LedId.Mousepad5, SteelSeriesLedId.ZoneFive }, + { LedId.Mousepad6, SteelSeriesLedId.ZoneSix }, + { LedId.Mousepad7, SteelSeriesLedId.ZoneSeven }, + { LedId.Mousepad8, SteelSeriesLedId.ZoneEight }, + { LedId.Mousepad9, SteelSeriesLedId.ZoneNine }, + { LedId.Mousepad10, SteelSeriesLedId.ZoneTen }, + { LedId.Mousepad11, SteelSeriesLedId.ZoneEleven }, + { LedId.Mousepad12, SteelSeriesLedId.ZoneTwelve }, + }; + + /// + /// Gets the mapping for two-zone mousepads + /// + public static LedMapping MousepadTwoZone { get; } = new() + { + { LedId.Mousepad1, SteelSeriesLedId.ZoneOne }, + { LedId.Mousepad2, SteelSeriesLedId.ZoneTwo } + }; + + /// + /// Gets the mapping for 103-zone led strip devices (monitor). + /// + public static LedMapping MonitorOnehundredandthreeZone { get; } = new() + { + { LedId.LedStripe1, SteelSeriesLedId.ZoneOne }, + { LedId.LedStripe2, SteelSeriesLedId.ZoneTwo }, + { LedId.LedStripe3, SteelSeriesLedId.ZoneThree }, + { LedId.LedStripe4, SteelSeriesLedId.ZoneFour }, + { LedId.LedStripe5, SteelSeriesLedId.ZoneFive }, + { LedId.LedStripe6, SteelSeriesLedId.ZoneSix }, + { LedId.LedStripe7, SteelSeriesLedId.ZoneSeven }, + { LedId.LedStripe8, SteelSeriesLedId.ZoneEight }, + { LedId.LedStripe9, SteelSeriesLedId.ZoneNine }, + { LedId.LedStripe10, SteelSeriesLedId.ZoneTen }, + { LedId.LedStripe11, SteelSeriesLedId.ZoneEleven }, + { LedId.LedStripe12, SteelSeriesLedId.ZoneTwelve }, + { LedId.LedStripe13, SteelSeriesLedId.ZoneThirteen }, + { LedId.LedStripe14, SteelSeriesLedId.ZoneFourteen }, + { LedId.LedStripe15, SteelSeriesLedId.ZoneFifteen }, + { LedId.LedStripe16, SteelSeriesLedId.ZoneSixteen }, + { LedId.LedStripe17, SteelSeriesLedId.ZoneSeventeen }, + { LedId.LedStripe18, SteelSeriesLedId.ZoneEighteen }, + { LedId.LedStripe19, SteelSeriesLedId.ZoneNineteen }, + { LedId.LedStripe20, SteelSeriesLedId.ZoneTwenty }, + { LedId.LedStripe21, SteelSeriesLedId.ZoneTwentyOne }, + { LedId.LedStripe22, SteelSeriesLedId.ZoneTwentyTwo }, + { LedId.LedStripe23, SteelSeriesLedId.ZoneTwentyThree }, + { LedId.LedStripe24, SteelSeriesLedId.ZoneTwentyFour }, + { LedId.LedStripe25, SteelSeriesLedId.ZoneTwentyFive }, + { LedId.LedStripe26, SteelSeriesLedId.ZoneTwentySix }, + { LedId.LedStripe27, SteelSeriesLedId.ZoneTwentySeven }, + { LedId.LedStripe28, SteelSeriesLedId.ZoneTwentyEight }, + { LedId.LedStripe29, SteelSeriesLedId.ZoneTwentyNine }, + { LedId.LedStripe30, SteelSeriesLedId.ZoneThirty }, + { LedId.LedStripe31, SteelSeriesLedId.ZoneThirtyOne }, + { LedId.LedStripe32, SteelSeriesLedId.ZoneThirtyTwo }, + { LedId.LedStripe33, SteelSeriesLedId.ZoneThirtyThree }, + { LedId.LedStripe34, SteelSeriesLedId.ZoneThirtyFour }, + { LedId.LedStripe35, SteelSeriesLedId.ZoneThirtyFive }, + { LedId.LedStripe36, SteelSeriesLedId.ZoneThirtySix }, + { LedId.LedStripe37, SteelSeriesLedId.ZoneThirtySeven }, + { LedId.LedStripe38, SteelSeriesLedId.ZoneThirtyEight }, + { LedId.LedStripe39, SteelSeriesLedId.ZoneThirtyNine }, + { LedId.LedStripe40, SteelSeriesLedId.ZoneForty }, + { LedId.LedStripe41, SteelSeriesLedId.ZoneFortyOne }, + { LedId.LedStripe42, SteelSeriesLedId.ZoneFortyTwo }, + { LedId.LedStripe43, SteelSeriesLedId.ZoneFortyThree }, + { LedId.LedStripe44, SteelSeriesLedId.ZoneFortyFour }, + { LedId.LedStripe45, SteelSeriesLedId.ZoneFortyFive }, + { LedId.LedStripe46, SteelSeriesLedId.ZoneFortySix }, + { LedId.LedStripe47, SteelSeriesLedId.ZoneFortySeven }, + { LedId.LedStripe48, SteelSeriesLedId.ZoneFortyEight }, + { LedId.LedStripe49, SteelSeriesLedId.ZoneFortyNine }, + { LedId.LedStripe50, SteelSeriesLedId.ZoneFifty }, + { LedId.LedStripe51, SteelSeriesLedId.ZoneFiftyOne }, + { LedId.LedStripe52, SteelSeriesLedId.ZoneFiftyTwo }, + { LedId.LedStripe53, SteelSeriesLedId.ZoneFiftyThree }, + { LedId.LedStripe54, SteelSeriesLedId.ZoneFiftyFour }, + { LedId.LedStripe55, SteelSeriesLedId.ZoneFiftyFive }, + { LedId.LedStripe56, SteelSeriesLedId.ZoneFiftySix }, + { LedId.LedStripe57, SteelSeriesLedId.ZoneFiftySeven }, + { LedId.LedStripe58, SteelSeriesLedId.ZoneFiftyEight }, + { LedId.LedStripe59, SteelSeriesLedId.ZoneFiftyNine }, + { LedId.LedStripe60, SteelSeriesLedId.ZoneSixty }, + { LedId.LedStripe61, SteelSeriesLedId.ZoneSixtyOne }, + { LedId.LedStripe62, SteelSeriesLedId.ZoneSixtyTwo }, + { LedId.LedStripe63, SteelSeriesLedId.ZoneSixtyThree }, + { LedId.LedStripe64, SteelSeriesLedId.ZoneSixtyFour }, + { LedId.LedStripe65, SteelSeriesLedId.ZoneSixtyFive }, + { LedId.LedStripe66, SteelSeriesLedId.ZoneSixtySix }, + { LedId.LedStripe67, SteelSeriesLedId.ZoneSixtySeven }, + { LedId.LedStripe68, SteelSeriesLedId.ZoneSixtyEight }, + { LedId.LedStripe69, SteelSeriesLedId.ZoneSixtyNine }, + { LedId.LedStripe70, SteelSeriesLedId.ZoneSeventy }, + { LedId.LedStripe71, SteelSeriesLedId.ZoneSeventyOne }, + { LedId.LedStripe72, SteelSeriesLedId.ZoneSeventyTwo }, + { LedId.LedStripe73, SteelSeriesLedId.ZoneSeventyThree }, + { LedId.LedStripe74, SteelSeriesLedId.ZoneSeventyFour }, + { LedId.LedStripe75, SteelSeriesLedId.ZoneSeventyFive }, + { LedId.LedStripe76, SteelSeriesLedId.ZoneSeventySix }, + { LedId.LedStripe77, SteelSeriesLedId.ZoneSeventySeven }, + { LedId.LedStripe78, SteelSeriesLedId.ZoneSeventyEight }, + { LedId.LedStripe79, SteelSeriesLedId.ZoneSeventyNine }, + { LedId.LedStripe80, SteelSeriesLedId.ZoneEighty }, + { LedId.LedStripe81, SteelSeriesLedId.ZoneEightyOne }, + { LedId.LedStripe82, SteelSeriesLedId.ZoneEightyTwo }, + { LedId.LedStripe83, SteelSeriesLedId.ZoneEightyThree }, + { LedId.LedStripe84, SteelSeriesLedId.ZoneEightyFour }, + { LedId.LedStripe85, SteelSeriesLedId.ZoneEightyFive }, + { LedId.LedStripe86, SteelSeriesLedId.ZoneEightySix }, + { LedId.LedStripe87, SteelSeriesLedId.ZoneEightySeven }, + { LedId.LedStripe88, SteelSeriesLedId.ZoneEightyEight }, + { LedId.LedStripe89, SteelSeriesLedId.ZoneEightyNine }, + { LedId.LedStripe90, SteelSeriesLedId.ZoneNinety }, + { LedId.LedStripe91, SteelSeriesLedId.ZoneNinetyOne }, + { LedId.LedStripe92, SteelSeriesLedId.ZoneNinetyTwo }, + { LedId.LedStripe93, SteelSeriesLedId.ZoneNinetyThree }, + { LedId.LedStripe94, SteelSeriesLedId.ZoneNinetyFour }, + { LedId.LedStripe95, SteelSeriesLedId.ZoneNinetyFive }, + { LedId.LedStripe96, SteelSeriesLedId.ZoneNinetySix }, + { LedId.LedStripe97, SteelSeriesLedId.ZoneNinetySeven }, + { LedId.LedStripe98, SteelSeriesLedId.ZoneNinetyEight }, + { LedId.LedStripe99, SteelSeriesLedId.ZoneNinetyNine }, + { LedId.LedStripe100, SteelSeriesLedId.ZoneOneHundred }, + { LedId.LedStripe101, SteelSeriesLedId.ZoneOneHundredOne }, + { LedId.LedStripe102, SteelSeriesLedId.ZoneOneHundredTwo }, + { LedId.LedStripe103, SteelSeriesLedId.ZoneOneHundredThree } + }; +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs index c2befb65..67c39a40 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateQueue.cs @@ -1,52 +1,51 @@ -using System.Collections.Generic; +using System; using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.SteelSeries.API; using RGB.NET.Devices.SteelSeries.Helper; -namespace RGB.NET.Devices.SteelSeries +namespace RGB.NET.Devices.SteelSeries; + +/// +/// +/// Represents the update-queue performing updates for steelseries devices. +/// +internal class SteelSeriesDeviceUpdateQueue : UpdateQueue { - /// - /// - /// Represents the update-queue performing updates for steelseries devices. - /// - internal class SteelSeriesDeviceUpdateQueue : UpdateQueue - { - #region Properties & Fields + #region Properties & Fields - private string _deviceType; + private readonly string _deviceType; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The device type used to identify the device. - public SteelSeriesDeviceUpdateQueue(IDeviceUpdateTrigger updateTrigger, string deviceType) - : base(updateTrigger) - { - this._deviceType = deviceType; - } + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The device type used to identify the device. + public SteelSeriesDeviceUpdateQueue(IDeviceUpdateTrigger updateTrigger, string deviceType) + : base(updateTrigger) + { + this._deviceType = deviceType; + } - #endregion + #endregion - #region Methods + #region Methods - protected override void OnUpdate(object sender, CustomUpdateData customData) - { - if ((customData != null) && (customData["refresh"] as bool? ?? false)) - SteelSeriesSDK.SendHeartbeat(); - else - base.OnUpdate(sender, customData); - } + protected override void OnUpdate(object? sender, CustomUpdateData customData) + { + if (customData[CustomUpdateDataIndex.HEARTBEAT] as bool? ?? false) + SteelSeriesSDK.SendHeartbeat(); + else + base.OnUpdate(sender, customData); + } - /// - protected override void Update(Dictionary dataSet) - => SteelSeriesSDK.UpdateLeds(_deviceType, dataSet.ToDictionary(x => ((SteelSeriesLedId)x.Key).GetAPIName(), x => x.Value.ToIntArray())); + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + => SteelSeriesSDK.UpdateLeds(_deviceType, dataSet.ToArray().Select(x => (((SteelSeriesLedId)x.key).GetAPIName(), x.color.ToIntArray())).Where(x => x.Item1 != null).ToList()!); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateTrigger.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateTrigger.cs deleted file mode 100644 index c6a6823e..00000000 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesDeviceUpdateTrigger.cs +++ /dev/null @@ -1,82 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global - -using System; -using System.Diagnostics; -using System.Threading; -using RGB.NET.Core; - -namespace RGB.NET.Devices.SteelSeries -{ - /// - /// Represents an update-trigger used to update SteelSeries devices - /// - public class SteelSeriesDeviceUpdateTrigger : DeviceUpdateTrigger - { - #region Constants - - private const long FLUSH_TIMER = 5 * 1000 * TimeSpan.TicksPerMillisecond; // flush the device every 5 seconds to prevent timeouts - - #endregion - - #region Properties & Fields - - private long _lastUpdateTimestamp; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - public SteelSeriesDeviceUpdateTrigger() - { } - - /// - /// Initializes a new instance of the class. - /// - /// The hard limit of the update rate of this trigger. - public SteelSeriesDeviceUpdateTrigger(double updateRateHardLimit) - : base(updateRateHardLimit) - { } - - #endregion - - #region Methods - - /// - protected override void UpdateLoop() - { - OnStartup(); - - while (!UpdateToken.IsCancellationRequested) - { - if (HasDataEvent.WaitOne(Timeout)) - { - long preUpdateTicks = Stopwatch.GetTimestamp(); - - OnUpdate(); - - if (UpdateFrequency > 0) - { - double lastUpdateTime = ((_lastUpdateTimestamp - preUpdateTicks) / (double)TimeSpan.TicksPerMillisecond); - int sleep = (int)((UpdateFrequency * 1000.0) - lastUpdateTime); - if (sleep > 0) - Thread.Sleep(sleep); - } - } - else if ((_lastUpdateTimestamp > 0) && ((Stopwatch.GetTimestamp() - _lastUpdateTimestamp) > FLUSH_TIMER)) - OnUpdate(new CustomUpdateData(("refresh", true))); - } - } - - /// - protected override void OnUpdate(CustomUpdateData updateData = null) - { - base.OnUpdate(updateData); - _lastUpdateTimestamp = Stopwatch.GetTimestamp(); - } - - #endregion - } -} diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs index ec59fd37..debe441c 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDevice.cs @@ -1,97 +1,50 @@ using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.SteelSeries -{ - /// - /// - /// - /// Represents a SteelSeries-device. (keyboard, mouse, headset, mousepad). - /// - public class SteelSeriesRGBDevice : AbstractRGBDevice, ISteelSeriesRGBDevice, IUnknownDevice//TODO DarthAffe 18.04.2020: It's know which kind of device this is, but they would need to be separated - { - #region Properties & Fields - - private Dictionary _ledMapping; - - /// - /// - /// Gets information about the . - /// - public override SteelSeriesRGBDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected UpdateQueue UpdateQueue { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by SteelSeries for the device. - internal SteelSeriesRGBDevice(SteelSeriesRGBDeviceInfo info) - { - this.DeviceInfo = info; - } +namespace RGB.NET.Devices.SteelSeries; - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - void ISteelSeriesRGBDevice.Initialize(UpdateQueue updateQueue, Dictionary ledMapping) - { - _ledMapping = ledMapping; +/// +/// +/// +/// Represents a SteelSeries-device. (keyboard, mouse, headset, mousepad). +/// +public class SteelSeriesRGBDevice : AbstractRGBDevice, ISteelSeriesRGBDevice, IUnknownDevice//TODO DarthAffe 18.04.2020: It's know which kind of device this is, but they would need to be separated +{ + #region Properties & Fields - int counter = 0; - foreach (KeyValuePair mapping in ledMapping) - InitializeLed(mapping.Key, new Rectangle((counter++) * 10, 0, 10, 10)); + private readonly LedMapping _ledMapping; - InitializeLayout(); + #endregion - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } + #region Constructors - UpdateQueue = updateQueue; - } + /// + /// Initializes a new instance of the class. + /// + internal SteelSeriesRGBDevice(SteelSeriesRGBDeviceInfo info, string apiName, LedMapping ledMapping, IDeviceUpdateTrigger updateTrigger) + : base(info, new SteelSeriesDeviceUpdateQueue(updateTrigger, apiName)) + { + this._ledMapping = ledMapping; - protected override object CreateLedCustomData(LedId ledId) => _ledMapping[ledId]; + InitializeLayout(); + } - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + #endregion - /// - /// Initializes the and of the device. - /// - protected virtual void InitializeLayout() - { - if (!(DeviceInfo is SteelSeriesRGBDeviceInfo info)) return; + #region Methods - string layout = info.ImageLayout; - string layoutPath = info.LayoutPath; - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, @"Layouts\SteelSeries", $"{layoutPath}.xml"), layout, true); - } + private void InitializeLayout() + { + int counter = 0; + foreach ((LedId ledId, _) in _ledMapping) + AddLed(ledId, new Point((counter++) * 10, 0), new Size(10, 10)); + } - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } + /// + protected override object GetLedCustomData(LedId ledId) => _ledMapping[ledId]; - base.Dispose(); - } + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDeviceInfo.cs b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDeviceInfo.cs index afb2e7d2..fe1f747b 100644 --- a/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDeviceInfo.cs +++ b/RGB.NET.Devices.SteelSeries/Generic/SteelSeriesRGBDeviceInfo.cs @@ -1,72 +1,53 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.SteelSeries -{ - /// - /// - /// Represents a generic information for a SteelSeries-. - /// - public class SteelSeriesRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields - - /// - public RGBDeviceType DeviceType { get; } +namespace RGB.NET.Devices.SteelSeries; - /// - public string DeviceName { get; } - - /// - public string Manufacturer => "SteelSeries"; - - /// - public string Model { get; } - - /// - public Uri Image { get; set; } +/// +/// +/// Represents a generic information for a SteelSeries-. +/// +public class SteelSeriesRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public RGBDeviceType DeviceType { get; } - /// - public bool SupportsSyncBack => false; + /// + public string DeviceName { get; } - public SteelSeriesDeviceType SteelSeriesDeviceType { get; } + /// + public string Manufacturer => "SteelSeries"; - /// - /// Gets the layout used to decide which images to load. - /// - internal string ImageLayout { get; } + /// + public string Model { get; } - /// - /// Gets the path/name of the layout-file. - /// - internal string LayoutPath { get; } + /// + public object? LayoutMetadata { get; set; } - #endregion + /// + /// Gets the type of this device used in the SDK. + /// + public SteelSeriesDeviceType SteelSeriesDeviceType { get; } - #region Constructors + #endregion - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The represented device model. - /// The lighting-capabilities of the device. - /// The layout used to decide which images to load. - /// The path/name of the layout-file. - internal SteelSeriesRGBDeviceInfo(RGBDeviceType deviceType, string model, SteelSeriesDeviceType steelSeriesDeviceType, string imageLayout, string layoutPath) - { - this.DeviceType = deviceType; - this.Model = model; - this.SteelSeriesDeviceType = steelSeriesDeviceType; - this.ImageLayout = imageLayout; - this.LayoutPath = layoutPath; + #region Constructors - DeviceName = $"{Manufacturer} {Model}"; - } + /// + /// Internal constructor of managed . + /// + /// The type of the . + /// The represented device model. + /// The type of this device used in the SDK. + internal SteelSeriesRGBDeviceInfo(RGBDeviceType deviceType, string model, SteelSeriesDeviceType steelSeriesDeviceType) + { + this.DeviceType = deviceType; + this.Model = model; + this.SteelSeriesDeviceType = steelSeriesDeviceType; - #endregion + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/HID/DeviceChecker.cs b/RGB.NET.Devices.SteelSeries/HID/DeviceChecker.cs deleted file mode 100644 index 8dda21a2..00000000 --- a/RGB.NET.Devices.SteelSeries/HID/DeviceChecker.cs +++ /dev/null @@ -1,295 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using HidSharp; -using RGB.NET.Core; -using DeviceDataList = System.Collections.Generic.List<(string model, RGB.NET.Core.RGBDeviceType deviceType, int id, RGB.NET.Devices.SteelSeries.SteelSeriesDeviceType steelSeriesDeviceType, string imageLayout, string layoutPath, System.Collections.Generic.Dictionary ledMapping)>; -using LedMapping = System.Collections.Generic.Dictionary; - -namespace RGB.NET.Devices.SteelSeries.HID -{ - internal static class DeviceChecker - { - #region Constants - - private static readonly LedMapping KEYBOARD_MAPPING_UK = new LedMapping - { - { LedId.Logo, SteelSeriesLedId.Logo }, - { LedId.Keyboard_Escape, SteelSeriesLedId.Escape }, - { LedId.Keyboard_F1, SteelSeriesLedId.F1 }, - { LedId.Keyboard_F2, SteelSeriesLedId.F2 }, - { LedId.Keyboard_F3, SteelSeriesLedId.F3 }, - { LedId.Keyboard_F4, SteelSeriesLedId.F4 }, - { LedId.Keyboard_F5, SteelSeriesLedId.F5 }, - { LedId.Keyboard_F6, SteelSeriesLedId.F6 }, - { LedId.Keyboard_F7, SteelSeriesLedId.F7 }, - { LedId.Keyboard_F8, SteelSeriesLedId.F8 }, - { LedId.Keyboard_F9, SteelSeriesLedId.F9 }, - { LedId.Keyboard_F10, SteelSeriesLedId.F10 }, - { LedId.Keyboard_F11, SteelSeriesLedId.F11 }, - { LedId.Keyboard_GraveAccentAndTilde, SteelSeriesLedId.Backqoute }, - { LedId.Keyboard_1, SteelSeriesLedId.Keyboard1 }, - { LedId.Keyboard_2, SteelSeriesLedId.Keyboard2 }, - { LedId.Keyboard_3, SteelSeriesLedId.Keyboard3 }, - { LedId.Keyboard_4, SteelSeriesLedId.Keyboard4 }, - { LedId.Keyboard_5, SteelSeriesLedId.Keyboard5 }, - { LedId.Keyboard_6, SteelSeriesLedId.Keyboard6 }, - { LedId.Keyboard_7, SteelSeriesLedId.Keyboard7 }, - { LedId.Keyboard_8, SteelSeriesLedId.Keyboard8 }, - { LedId.Keyboard_9, SteelSeriesLedId.Keyboard9 }, - { LedId.Keyboard_0, SteelSeriesLedId.Keyboard0 }, - { LedId.Keyboard_MinusAndUnderscore, SteelSeriesLedId.Dash }, - { LedId.Keyboard_Tab, SteelSeriesLedId.Tab }, - { LedId.Keyboard_Q, SteelSeriesLedId.Q }, - { LedId.Keyboard_W, SteelSeriesLedId.W }, - { LedId.Keyboard_E, SteelSeriesLedId.E }, - { LedId.Keyboard_R, SteelSeriesLedId.R }, - { LedId.Keyboard_T, SteelSeriesLedId.T }, - { LedId.Keyboard_Y, SteelSeriesLedId.Y }, - { LedId.Keyboard_U, SteelSeriesLedId.U }, - { LedId.Keyboard_I, SteelSeriesLedId.I }, - { LedId.Keyboard_O, SteelSeriesLedId.O }, - { LedId.Keyboard_P, SteelSeriesLedId.P }, - { LedId.Keyboard_BracketLeft, SteelSeriesLedId.LBracket }, - { LedId.Keyboard_CapsLock, SteelSeriesLedId.Caps }, - { LedId.Keyboard_A, SteelSeriesLedId.A }, - { LedId.Keyboard_S, SteelSeriesLedId.S }, - { LedId.Keyboard_D, SteelSeriesLedId.D }, - { LedId.Keyboard_F, SteelSeriesLedId.F }, - { LedId.Keyboard_G, SteelSeriesLedId.G }, - { LedId.Keyboard_H, SteelSeriesLedId.H }, - { LedId.Keyboard_J, SteelSeriesLedId.J }, - { LedId.Keyboard_K, SteelSeriesLedId.K }, - { LedId.Keyboard_L, SteelSeriesLedId.L }, - { LedId.Keyboard_SemicolonAndColon, SteelSeriesLedId.Semicolon }, - { LedId.Keyboard_ApostropheAndDoubleQuote, SteelSeriesLedId.Quote }, - { LedId.Keyboard_LeftShift, SteelSeriesLedId.LShift }, - { LedId.Keyboard_NonUsTilde, SteelSeriesLedId.Pound }, - { LedId.Keyboard_Z, SteelSeriesLedId.Z }, - { LedId.Keyboard_X, SteelSeriesLedId.X }, - { LedId.Keyboard_C, SteelSeriesLedId.C }, - { LedId.Keyboard_V, SteelSeriesLedId.V }, - { LedId.Keyboard_B, SteelSeriesLedId.B }, - { LedId.Keyboard_N, SteelSeriesLedId.N }, - { LedId.Keyboard_M, SteelSeriesLedId.M }, - { LedId.Keyboard_CommaAndLessThan, SteelSeriesLedId.Comma }, - { LedId.Keyboard_PeriodAndBiggerThan, SteelSeriesLedId.Period }, - { LedId.Keyboard_SlashAndQuestionMark, SteelSeriesLedId.Slash }, - { LedId.Keyboard_LeftCtrl, SteelSeriesLedId.LCtrl }, - { LedId.Keyboard_LeftGui, SteelSeriesLedId.LWin }, - { LedId.Keyboard_LeftAlt, SteelSeriesLedId.LAlt }, - { LedId.Keyboard_Space, SteelSeriesLedId.Spacebar }, - { LedId.Keyboard_RightAlt, SteelSeriesLedId.RAlt }, - { LedId.Keyboard_RightGui, SteelSeriesLedId.RWin }, - { LedId.Keyboard_Application, SteelSeriesLedId.SSKey }, - { LedId.Keyboard_F12, SteelSeriesLedId.F12 }, - { LedId.Keyboard_PrintScreen, SteelSeriesLedId.PrintScreen }, - { LedId.Keyboard_ScrollLock, SteelSeriesLedId.ScrollLock }, - { LedId.Keyboard_PauseBreak, SteelSeriesLedId.Pause }, - { LedId.Keyboard_Insert, SteelSeriesLedId.Insert }, - { LedId.Keyboard_Home, SteelSeriesLedId.Home }, - { LedId.Keyboard_PageUp, SteelSeriesLedId.PageUp }, - { LedId.Keyboard_BracketRight, SteelSeriesLedId.RBracket }, - { LedId.Keyboard_Backslash, SteelSeriesLedId.Backslash }, - { LedId.Keyboard_Enter, SteelSeriesLedId.Return }, - { LedId.Keyboard_EqualsAndPlus, SteelSeriesLedId.Equal }, - { LedId.Keyboard_Backspace, SteelSeriesLedId.Backspace }, - { LedId.Keyboard_Delete, SteelSeriesLedId.Delete }, - { LedId.Keyboard_End, SteelSeriesLedId.End }, - { LedId.Keyboard_PageDown, SteelSeriesLedId.PageDown }, - { LedId.Keyboard_RightShift, SteelSeriesLedId.RShift }, - { LedId.Keyboard_RightCtrl, SteelSeriesLedId.RCtrl }, - { LedId.Keyboard_ArrowUp, SteelSeriesLedId.UpArrow }, - { LedId.Keyboard_ArrowLeft, SteelSeriesLedId.LeftArrow }, - { LedId.Keyboard_ArrowDown, SteelSeriesLedId.DownArrow }, - { LedId.Keyboard_ArrowRight, SteelSeriesLedId.RightArrow }, - { LedId.Keyboard_NumLock, SteelSeriesLedId.KeypadNumLock }, - { LedId.Keyboard_NumSlash, SteelSeriesLedId.KeypadDivide }, - { LedId.Keyboard_NumAsterisk, SteelSeriesLedId.KeypadTimes }, - { LedId.Keyboard_NumMinus, SteelSeriesLedId.KeypadMinus }, - { LedId.Keyboard_NumPlus, SteelSeriesLedId.KeypadPlus }, - { LedId.Keyboard_NumEnter, SteelSeriesLedId.KeypadEnter }, - { LedId.Keyboard_Num7, SteelSeriesLedId.Keypad7 }, - { LedId.Keyboard_Num8, SteelSeriesLedId.Keypad8 }, - { LedId.Keyboard_Num9, SteelSeriesLedId.Keypad9 }, - { LedId.Keyboard_Num4, SteelSeriesLedId.Keypad4 }, - { LedId.Keyboard_Num5, SteelSeriesLedId.Keypad5 }, - { LedId.Keyboard_Num6, SteelSeriesLedId.Keypad6 }, - { LedId.Keyboard_Num1, SteelSeriesLedId.Keypad1 }, - { LedId.Keyboard_Num2, SteelSeriesLedId.Keypad2 }, - { LedId.Keyboard_Num3, SteelSeriesLedId.Keypad3 }, - { LedId.Keyboard_Num0, SteelSeriesLedId.Keypad0 }, - { LedId.Keyboard_NumPeriodAndDelete, SteelSeriesLedId.KeypadPeriod } - }; - - private static readonly LedMapping KEYBOARD_TKL_MAPPING_UK = new LedMapping - { - { LedId.Logo, SteelSeriesLedId.Logo }, - { LedId.Keyboard_Escape, SteelSeriesLedId.Escape }, - { LedId.Keyboard_F1, SteelSeriesLedId.F1 }, - { LedId.Keyboard_F2, SteelSeriesLedId.F2 }, - { LedId.Keyboard_F3, SteelSeriesLedId.F3 }, - { LedId.Keyboard_F4, SteelSeriesLedId.F4 }, - { LedId.Keyboard_F5, SteelSeriesLedId.F5 }, - { LedId.Keyboard_F6, SteelSeriesLedId.F6 }, - { LedId.Keyboard_F7, SteelSeriesLedId.F7 }, - { LedId.Keyboard_F8, SteelSeriesLedId.F8 }, - { LedId.Keyboard_F9, SteelSeriesLedId.F9 }, - { LedId.Keyboard_F10, SteelSeriesLedId.F10 }, - { LedId.Keyboard_F11, SteelSeriesLedId.F11 }, - { LedId.Keyboard_GraveAccentAndTilde, SteelSeriesLedId.Backqoute }, - { LedId.Keyboard_1, SteelSeriesLedId.Keyboard1 }, - { LedId.Keyboard_2, SteelSeriesLedId.Keyboard2 }, - { LedId.Keyboard_3, SteelSeriesLedId.Keyboard3 }, - { LedId.Keyboard_4, SteelSeriesLedId.Keyboard4 }, - { LedId.Keyboard_5, SteelSeriesLedId.Keyboard5 }, - { LedId.Keyboard_6, SteelSeriesLedId.Keyboard6 }, - { LedId.Keyboard_7, SteelSeriesLedId.Keyboard7 }, - { LedId.Keyboard_8, SteelSeriesLedId.Keyboard8 }, - { LedId.Keyboard_9, SteelSeriesLedId.Keyboard9 }, - { LedId.Keyboard_0, SteelSeriesLedId.Keyboard0 }, - { LedId.Keyboard_MinusAndUnderscore, SteelSeriesLedId.Dash }, - { LedId.Keyboard_Tab, SteelSeriesLedId.Tab }, - { LedId.Keyboard_Q, SteelSeriesLedId.Q }, - { LedId.Keyboard_W, SteelSeriesLedId.W }, - { LedId.Keyboard_E, SteelSeriesLedId.E }, - { LedId.Keyboard_R, SteelSeriesLedId.R }, - { LedId.Keyboard_T, SteelSeriesLedId.T }, - { LedId.Keyboard_Y, SteelSeriesLedId.Y }, - { LedId.Keyboard_U, SteelSeriesLedId.U }, - { LedId.Keyboard_I, SteelSeriesLedId.I }, - { LedId.Keyboard_O, SteelSeriesLedId.O }, - { LedId.Keyboard_P, SteelSeriesLedId.P }, - { LedId.Keyboard_BracketLeft, SteelSeriesLedId.LBracket }, - { LedId.Keyboard_CapsLock, SteelSeriesLedId.Caps }, - { LedId.Keyboard_A, SteelSeriesLedId.A }, - { LedId.Keyboard_S, SteelSeriesLedId.S }, - { LedId.Keyboard_D, SteelSeriesLedId.D }, - { LedId.Keyboard_F, SteelSeriesLedId.F }, - { LedId.Keyboard_G, SteelSeriesLedId.G }, - { LedId.Keyboard_H, SteelSeriesLedId.H }, - { LedId.Keyboard_J, SteelSeriesLedId.J }, - { LedId.Keyboard_K, SteelSeriesLedId.K }, - { LedId.Keyboard_L, SteelSeriesLedId.L }, - { LedId.Keyboard_SemicolonAndColon, SteelSeriesLedId.Semicolon }, - { LedId.Keyboard_ApostropheAndDoubleQuote, SteelSeriesLedId.Quote }, - { LedId.Keyboard_LeftShift, SteelSeriesLedId.LShift }, - { LedId.Keyboard_NonUsTilde, SteelSeriesLedId.Pound }, - { LedId.Keyboard_Z, SteelSeriesLedId.Z }, - { LedId.Keyboard_X, SteelSeriesLedId.X }, - { LedId.Keyboard_C, SteelSeriesLedId.C }, - { LedId.Keyboard_V, SteelSeriesLedId.V }, - { LedId.Keyboard_B, SteelSeriesLedId.B }, - { LedId.Keyboard_N, SteelSeriesLedId.N }, - { LedId.Keyboard_M, SteelSeriesLedId.M }, - { LedId.Keyboard_CommaAndLessThan, SteelSeriesLedId.Comma }, - { LedId.Keyboard_PeriodAndBiggerThan, SteelSeriesLedId.Period }, - { LedId.Keyboard_SlashAndQuestionMark, SteelSeriesLedId.Slash }, - { LedId.Keyboard_LeftCtrl, SteelSeriesLedId.LCtrl }, - { LedId.Keyboard_LeftGui, SteelSeriesLedId.LWin }, - { LedId.Keyboard_LeftAlt, SteelSeriesLedId.LAlt }, - { LedId.Keyboard_Space, SteelSeriesLedId.Spacebar }, - { LedId.Keyboard_RightAlt, SteelSeriesLedId.RAlt }, - { LedId.Keyboard_RightGui, SteelSeriesLedId.RWin }, - { LedId.Keyboard_Application, SteelSeriesLedId.SSKey }, - { LedId.Keyboard_F12, SteelSeriesLedId.F12 }, - { LedId.Keyboard_PrintScreen, SteelSeriesLedId.PrintScreen }, - { LedId.Keyboard_ScrollLock, SteelSeriesLedId.ScrollLock }, - { LedId.Keyboard_PauseBreak, SteelSeriesLedId.Pause }, - { LedId.Keyboard_Insert, SteelSeriesLedId.Insert }, - { LedId.Keyboard_Home, SteelSeriesLedId.Home }, - { LedId.Keyboard_PageUp, SteelSeriesLedId.PageUp }, - { LedId.Keyboard_BracketRight, SteelSeriesLedId.RBracket }, - { LedId.Keyboard_Backslash, SteelSeriesLedId.Backslash }, - { LedId.Keyboard_Enter, SteelSeriesLedId.Return }, - { LedId.Keyboard_EqualsAndPlus, SteelSeriesLedId.Equal }, - { LedId.Keyboard_Backspace, SteelSeriesLedId.Backspace }, - { LedId.Keyboard_Delete, SteelSeriesLedId.Delete }, - { LedId.Keyboard_End, SteelSeriesLedId.End }, - { LedId.Keyboard_PageDown, SteelSeriesLedId.PageDown }, - { LedId.Keyboard_RightShift, SteelSeriesLedId.RShift }, - { LedId.Keyboard_RightCtrl, SteelSeriesLedId.RCtrl }, - { LedId.Keyboard_ArrowUp, SteelSeriesLedId.UpArrow }, - { LedId.Keyboard_ArrowLeft, SteelSeriesLedId.LeftArrow }, - { LedId.Keyboard_ArrowDown, SteelSeriesLedId.DownArrow }, - { LedId.Keyboard_ArrowRight, SteelSeriesLedId.RightArrow } - }; - - private static readonly LedMapping MOUSE_TWO_ZONE = new LedMapping - { - {LedId.Mouse1, SteelSeriesLedId.ZoneOne}, - {LedId.Mouse2, SteelSeriesLedId.ZoneTwo} - }; - - private static readonly LedMapping MOUSE_THREE_ZONE = new LedMapping - { - {LedId.Mouse1, SteelSeriesLedId.ZoneOne}, - {LedId.Mouse2, SteelSeriesLedId.ZoneTwo}, - {LedId.Mouse3, SteelSeriesLedId.ZoneThree} - }; - - private static readonly LedMapping MOUSE_EIGHT_ZONE = new LedMapping - { - { LedId.Mouse1, SteelSeriesLedId.ZoneOne}, - { LedId.Mouse2, SteelSeriesLedId.ZoneTwo}, - { LedId.Mouse3, SteelSeriesLedId.ZoneThree}, - { LedId.Mouse4, SteelSeriesLedId.ZoneFour}, - { LedId.Mouse5, SteelSeriesLedId.ZoneFive}, - { LedId.Mouse6, SteelSeriesLedId.ZoneSix}, - { LedId.Mouse7, SteelSeriesLedId.ZoneSeven}, - { LedId.Mouse8, SteelSeriesLedId.ZoneEight} - }; - - private static readonly LedMapping HEADSET_TWO_ZONE = new LedMapping - { - {LedId.Headset1, SteelSeriesLedId.ZoneOne}, - {LedId.Headset2, SteelSeriesLedId.ZoneTwo} - }; - - private const int VENDOR_ID = 0x1038; - - //TODO DarthAffe 16.02.2019: Add devices - private static readonly DeviceDataList DEVICES = new DeviceDataList - { - ("Rival 600", RGBDeviceType.Mouse, 0x1724, SteelSeriesDeviceType.EightZone, "default", @"Mice\Rival600", MOUSE_EIGHT_ZONE), - ("Rival 500", RGBDeviceType.Mouse, 0x170E, SteelSeriesDeviceType.TwoZone, "default", @"Mice\Rival500", MOUSE_TWO_ZONE), - ("Rival 310", RGBDeviceType.Mouse, 0x1720, SteelSeriesDeviceType.TwoZone, "default", @"Mice\Rival310", MOUSE_TWO_ZONE), - ("Rival 3 (Old Firmware)", RGBDeviceType.Mouse, 0x1824, SteelSeriesDeviceType.ThreeZone, "default", @"Mice\Rival3", MOUSE_THREE_ZONE), - ("Rival 3", RGBDeviceType.Mouse, 0x184C, SteelSeriesDeviceType.ThreeZone, "default", @"Mice\Rival3", MOUSE_THREE_ZONE), - - ("Apex 5", RGBDeviceType.Keyboard, 0x161C, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\5\UK", KEYBOARD_MAPPING_UK), - ("Apex 7", RGBDeviceType.Keyboard, 0x1612, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\7\UK", KEYBOARD_MAPPING_UK), - ("Apex 7 TKL", RGBDeviceType.Keyboard, 0x1618, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\7TKL\UK", KEYBOARD_TKL_MAPPING_UK), - ("Apex M750", RGBDeviceType.Keyboard, 0x0616, SteelSeriesDeviceType.PerKey, "UK", @"Keyboards\M750\UK", KEYBOARD_MAPPING_UK), - - ("Arctis 5", RGBDeviceType.Headset, 0x12AA, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), - ("Arctis 5 Game", RGBDeviceType.Headset, 0x1250, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), - ("Arctis 5 Game - Dota 2 edition", RGBDeviceType.Headset, 0x1251, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), - ("Arctis 5 Pro Game", RGBDeviceType.Headset, 0x1252, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), - ("Arctis 5 Game - PUBG edition", RGBDeviceType.Headset, 0x12A8, SteelSeriesDeviceType.TwoZone, "default", @"Headsets\Artis5", HEADSET_TWO_ZONE), - }; - - #endregion - - #region Properties & Fields - - public static DeviceDataList ConnectedDevices { get; } = new DeviceDataList(); - - #endregion - - #region Methods - - internal static void LoadDeviceList(RGBDeviceType loadFilter) - { - ConnectedDevices.Clear(); - - HashSet ids = new HashSet(DeviceList.Local.GetHidDevices(VENDOR_ID).Select(x => x.ProductID).Distinct()); - DeviceDataList connectedDevices = DEVICES.Where(d => ids.Contains(d.id) && loadFilter.HasFlag(d.deviceType)).ToList(); - - List connectedDeviceTypes = connectedDevices.Select(d => d.steelSeriesDeviceType).ToList(); - foreach (SteelSeriesDeviceType deviceType in connectedDeviceTypes) - ConnectedDevices.Add(connectedDevices.Where(d => d.steelSeriesDeviceType == deviceType).OrderByDescending(d => d.ledMapping.Count).First()); - } - - #endregion - } -} diff --git a/RGB.NET.Devices.SteelSeries/Helper/ColorExtensions.cs b/RGB.NET.Devices.SteelSeries/Helper/ColorExtensions.cs index c4f4bc43..b101ff70 100644 --- a/RGB.NET.Devices.SteelSeries/Helper/ColorExtensions.cs +++ b/RGB.NET.Devices.SteelSeries/Helper/ColorExtensions.cs @@ -1,9 +1,8 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.SteelSeries.Helper +namespace RGB.NET.Devices.SteelSeries.Helper; + +internal static class ColorExtensions { - internal static class ColorExtensions - { - internal static int[] ToIntArray(this Color color) => new int[] { color.GetR(), color.GetG(), color.GetB() }; - } -} + internal static int[] ToIntArray(this Color color) => new int[] { color.GetR(), color.GetG(), color.GetB() }; +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/README.md b/RGB.NET.Devices.SteelSeries/README.md new file mode 100644 index 00000000..7971dc80 --- /dev/null +++ b/RGB.NET.Devices.SteelSeries/README.md @@ -0,0 +1,14 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for Steel Series-Devices. + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(SteelSeriesDeviceProvider.Instance); +``` + +Since the Steel Series SDK does not provide device information only known devices will work. +You can add detection for additional devices by adding entires for them to the respective static `DeviceDefinitions` on the `SteelSeriesDeviceProvider`. + +# Required SDK +This provider does not require an additional SDK. diff --git a/RGB.NET.Devices.SteelSeries/RGB.NET.Devices.SteelSeries.csproj b/RGB.NET.Devices.SteelSeries/RGB.NET.Devices.SteelSeries.csproj index bf4b1e59..d8b2ab6b 100644 --- a/RGB.NET.Devices.SteelSeries/RGB.NET.Devices.SteelSeries.csproj +++ b/RGB.NET.Devices.SteelSeries/RGB.NET.Devices.SteelSeries.csproj @@ -1,7 +1,8 @@  - netstandard2.0 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.SteelSeries SteelSeries-Device-Implementations of RGB.NET SteelSeries-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,30 +35,29 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 + portable + snupkg $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE + + + + + - - + \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/RGB.NET.Devices.SteelSeries.csproj.DotSettings b/RGB.NET.Devices.SteelSeries/RGB.NET.Devices.SteelSeries.csproj.DotSettings index 20d47924..a98175df 100644 --- a/RGB.NET.Devices.SteelSeries/RGB.NET.Devices.SteelSeries.csproj.DotSettings +++ b/RGB.NET.Devices.SteelSeries/RGB.NET.Devices.SteelSeries.csproj.DotSettings @@ -1,4 +1,5 @@  True True - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs index 21402dd2..7144da60 100644 --- a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs +++ b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProvider.cs @@ -1,129 +1,143 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using RGB.NET.Core; using RGB.NET.Devices.SteelSeries.API; -using RGB.NET.Devices.SteelSeries.HID; +using RGB.NET.HID; -namespace RGB.NET.Devices.SteelSeries +namespace RGB.NET.Devices.SteelSeries; + +/// +/// +/// Represents a device provider responsible for SteelSeries-devices. +/// +public class SteelSeriesDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Constants + + private static readonly int HEARTBEAT_TIMER = 5000; // flush the device every 5 seconds to prevent timeouts + + #endregion + + #region Properties & Fields + + private static SteelSeriesDeviceProvider? _instance; + /// + /// Gets the singleton instance. + /// + public static SteelSeriesDeviceProvider Instance => _instance ?? new SteelSeriesDeviceProvider(); + + private const int VENDOR_ID = 0x1038; + /// - /// Represents a device provider responsible for SteelSeries- devices. + /// Gets the HID-definitions for SteelSeries-devices. /// - public class SteelSeriesDeviceProvider : IRGBDeviceProvider + public static HIDLoader DeviceDefinitions { get; } = new(VENDOR_ID) { - #region Properties & Fields - - private static SteelSeriesDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static SteelSeriesDeviceProvider Instance => _instance ?? new SteelSeriesDeviceProvider(); - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess => false; - - /// - public IEnumerable Devices { get; private set; } - - /// - /// The used to trigger the updates for SteelSeries devices. - /// - public SteelSeriesDeviceUpdateTrigger UpdateTrigger { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public SteelSeriesDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(SteelSeriesDeviceProvider)}"); - _instance = this; + //Mice + { 0x1836, RGBDeviceType.Mouse, "Aerox 3", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone }, + { 0x183A, RGBDeviceType.Mouse, "Aerox 3 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone }, + { 0x1702, RGBDeviceType.Mouse, "Rival 100", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone }, + { 0x1814, RGBDeviceType.Mouse, "Rival 105", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone }, + { 0x1816, RGBDeviceType.Mouse, "Rival 106", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone }, + { 0x1729, RGBDeviceType.Mouse, "Rival 110", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone }, + { 0x0472, RGBDeviceType.Mouse, "Rival 150", LedMappings.MouseOneZone, SteelSeriesDeviceType.OneZone }, + { 0x1710, RGBDeviceType.Mouse, "Rival 300", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x1720, RGBDeviceType.Mouse, "Rival 310", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x1722, RGBDeviceType.Mouse, "Sensei 310", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x170E, RGBDeviceType.Mouse, "Rival 500", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x1724, RGBDeviceType.Mouse, "Rival 600", LedMappings.MouseEightZone, SteelSeriesDeviceType.EightZone }, + { 0x1726, RGBDeviceType.Mouse, "Rival 650", LedMappings.MouseEightZone, SteelSeriesDeviceType.EightZone }, + { 0x172B, RGBDeviceType.Mouse, "Rival 650", LedMappings.MouseEightZone, SteelSeriesDeviceType.EightZone }, + { 0x1700, RGBDeviceType.Mouse, "Rival 700", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x1824, RGBDeviceType.Mouse, "Rival 3 (Old Firmware)", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone }, + { 0x184C, RGBDeviceType.Mouse, "Rival 3", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone }, + { 0x1830, RGBDeviceType.Mouse, "Rival 3 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone }, + { 0x1832, RGBDeviceType.Mouse, "Sensei Ten", LedMappings.MouseTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x1838, RGBDeviceType.Mouse, "Aerox 3 Wireless", LedMappings.MouseThreeZone, SteelSeriesDeviceType.ThreeZone }, + { 0x183C, RGBDeviceType.Mouse, "Rival 5", LedMappings.MouseTenZone, SteelSeriesDeviceType.TenZone }, + + //Keyboards + { 0x161C, RGBDeviceType.Keyboard, "Apex 5", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey }, + { 0x1612, RGBDeviceType.Keyboard, "Apex 7", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey }, + { 0x1618, RGBDeviceType.Keyboard, "Apex 7 TKL", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey }, + { 0x0616, RGBDeviceType.Keyboard, "Apex M750", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey }, + { 0x1600, RGBDeviceType.Keyboard, "Apex M800", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey }, + { 0x1610, RGBDeviceType.Keyboard, "Apex Pro", LedMappings.KeyboardMappingUk, SteelSeriesDeviceType.PerKey }, + { 0x1614, RGBDeviceType.Keyboard, "Apex Pro TKL", LedMappings.KeyboardTklMappingUk, SteelSeriesDeviceType.PerKey }, + { 0x2036, RGBDeviceType.Keyboard, "MSI Notebook", LedMappings.KeyboardNotebookMappingUk, SteelSeriesDeviceType.PerKey }, + + //Headsets + { 0x12AA, RGBDeviceType.Headset, "Arctis 5", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x1250, RGBDeviceType.Headset, "Arctis 5 Game", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x1251, RGBDeviceType.Headset, "Arctis 5 Game - Dota 2 edition", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x12A8, RGBDeviceType.Headset, "Arctis 5 Game - PUBG edition", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone }, + { 0x1252, RGBDeviceType.Headset, "Arctis Pro Game", LedMappings.HeadsetTwoZone, SteelSeriesDeviceType.TwoZone }, + + //Mousepads + { 0x1507, RGBDeviceType.Mousepad, "QCK Prism", LedMappings.MousepadTwelveZone, SteelSeriesDeviceType.TwelveZone }, + { 0x150D, RGBDeviceType.Mousepad, "QCK Prism Cloth", LedMappings.MousepadTwoZone, SteelSeriesDeviceType.TwoZone }, + + //Monitors + { 0x1126, RGBDeviceType.Monitor, "MGP27C", LedMappings.MonitorOnehundredandthreeZone, SteelSeriesDeviceType.OneHundredAndThreeZone }, + }; + + #endregion + + #region Constructors - UpdateTrigger = new SteelSeriesDeviceUpdateTrigger(); - } + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public SteelSeriesDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(SteelSeriesDeviceProvider)}"); + _instance = this; + } - #endregion + #endregion - #region Methods + #region Methods - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - try - { - IsInitialized = false; - - UpdateTrigger?.Stop(); - - if (!SteelSeriesSDK.IsInitialized) - SteelSeriesSDK.Initialize(); - - IList devices = new List(); - DeviceChecker.LoadDeviceList(loadFilter); - - try - { - foreach ((string model, RGBDeviceType deviceType, int _, SteelSeriesDeviceType steelSeriesDeviceType, string imageLayout, string layoutPath, Dictionary ledMapping) in DeviceChecker.ConnectedDevices) - { - ISteelSeriesRGBDevice device = new SteelSeriesRGBDevice(new SteelSeriesRGBDeviceInfo(deviceType, model, steelSeriesDeviceType, imageLayout, layoutPath)); - SteelSeriesDeviceUpdateQueue updateQueue = new SteelSeriesDeviceUpdateQueue(UpdateTrigger, steelSeriesDeviceType.GetAPIName()); - device.Initialize(updateQueue, ledMapping); - devices.Add(device); - } - } - catch { if (throwExceptions) throw; } - - UpdateTrigger?.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - IsInitialized = false; - if (throwExceptions) throw; - return false; - } - - return true; - } + /// + protected override void InitializeSDK() + { + if (!SteelSeriesSDK.IsInitialized) + SteelSeriesSDK.Initialize(); + } - /// - public void ResetDevices() + /// + protected override IEnumerable GetLoadedDevices(RGBDeviceType loadFilter) + { + DeviceDefinitions.LoadFilter = loadFilter; + + return base.GetLoadedDevices(loadFilter); + } + + /// + protected override IEnumerable LoadDevices() + { + foreach ((HIDDeviceDefinition definition, _) in DeviceDefinitions.GetConnectedDevices(x => x.CustomData)) { - if (IsInitialized) - try - { - SteelSeriesSDK.ResetLeds(); - } - catch {/* shit happens */} + string? apiName = definition.CustomData.GetAPIName(); + if (apiName == null) + Throw(new RGBDeviceException($"Missing API-name for device {definition.Name}")); + else + yield return new SteelSeriesRGBDevice(new SteelSeriesRGBDeviceInfo(definition.DeviceType, definition.Name, definition.CustomData), apiName, definition.LedMapping, GetUpdateTrigger()); } + } - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } + /// + protected override IDeviceUpdateTrigger CreateUpdateTrigger(int id, double updateRateHardLimit) => new DeviceUpdateTrigger(updateRateHardLimit) { HeartbeatTimer = HEARTBEAT_TIMER }; - try { SteelSeriesSDK.Dispose(); } - catch { /* shit happens */ } - } + /// + public override void Dispose() + { + base.Dispose(); - #endregion + try { SteelSeriesSDK.Dispose(); } + catch { /* shit happens */ } } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProviderLoader.cs b/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProviderLoader.cs deleted file mode 100644 index ffe1938a..00000000 --- a/RGB.NET.Devices.SteelSeries/SteelSeriesDeviceProviderLoader.cs +++ /dev/null @@ -1,25 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.SteelSeries -{ - /// - /// Represents a device provider loaded used to dynamically load steelseries devices into an application. - /// - // ReSharper disable once UnusedMember.Global - public class SteelSeriesDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => SteelSeriesDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs index c940db48..8d3d2909 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDevice.cs @@ -5,83 +5,57 @@ using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.Arduino +namespace RGB.NET.Devices.WS281X.Arduino; + +// ReSharper disable once InconsistentNaming +/// +/// Represents an arduino WS2812 device. +/// +public class ArduinoWS2812USBDevice : AbstractRGBDevice, ILedStripe { - // ReSharper disable once InconsistentNaming - /// + #region Properties & Fields /// - /// Represents an arduino WS2812 device. + /// Gets the channel (as defined in the arduino-sketch) this device is attached to. /// - public class ArduinoWS2812USBDevice : AbstractRGBDevice, ILedStripe - { - #region Properties & Fields - - /// - /// Gets the update queue performing updates for this device. - /// - public ArduinoWS2812USBUpdateQueue UpdateQueue { get; } - - /// - public override ArduinoWS2812USBDeviceInfo DeviceInfo { get; } + public int Channel { get; } - /// - /// Gets the channel (as defined in the arduino-sketch) this device is attached to. - /// - public int Channel { get; } + #endregion - #endregion + #region Constructors - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The update queue performing updates for this device. - /// The channel (as defined in the arduino-sketch) this device is attached to. - public ArduinoWS2812USBDevice(ArduinoWS2812USBDeviceInfo deviceInfo, ArduinoWS2812USBUpdateQueue updateQueue, int channel) - { - this.DeviceInfo = deviceInfo; - this.UpdateQueue = updateQueue; - this.Channel = channel; - } - - #endregion - - #region Methods - - internal void Initialize(int ledCount) - { - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.LedStripe1 + i, new Rectangle(i * 10, 0, 10, 10)); + /// + /// Initializes a new instance of the class. + /// + /// The device info of this device. + /// The update queue performing updates for this device. + /// The channel (as defined in the arduino-sketch) this device is attached to. + /// The amount of leds on this device. + public ArduinoWS2812USBDevice(ArduinoWS2812USBDeviceInfo deviceInfo, ArduinoWS2812USBUpdateQueue updateQueue, int channel, int ledCount) + : base(deviceInfo, updateQueue) + { + this.Channel = channel; - //TODO DarthAffe 23.12.2018: Allow to load a layout. + InitializeLayout(ledCount); + } - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - } + #endregion - /// - protected override object CreateLedCustomData(LedId ledId) => (Channel, (int)ledId - (int)LedId.LedStripe1); + #region Methods - /// - protected override IEnumerable GetLedsToUpdate(bool flushLeds) => (flushLeds || LedMapping.Values.Any(x => x.IsDirty)) ? LedMapping.Values : null; + private void InitializeLayout(int ledCount) + { + for (int i = 0; i < ledCount; i++) + AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); + } - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + /// + protected override object GetLedCustomData(LedId ledId) => (Channel, (int)ledId - (int)LedId.LedStripe1); - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } + /// + protected override IEnumerable GetLedsToUpdate(bool flushLeds) => (flushLeds || LedMapping.Values.Any(x => x.IsDirty)) ? LedMapping.Values : Enumerable.Empty(); - base.Dispose(); - } + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDeviceInfo.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDeviceInfo.cs index c8f02821..fede95cc 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDeviceInfo.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBDeviceInfo.cs @@ -1,51 +1,43 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.Arduino -{ - // ReSharper disable once InconsistentNaming - /// - /// - /// Represents a generic information for a . - /// - public class ArduinoWS2812USBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Devices.WS281X.Arduino; - /// - public string DeviceName { get; } - - /// - public RGBDeviceType DeviceType => RGBDeviceType.LedStripe; - - /// - public string Manufacturer => "Arduino"; +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents a generic information for a . +/// +public class ArduinoWS2812USBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public string Model => "WS2812 USB"; + /// + public string DeviceName { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public RGBDeviceType DeviceType => RGBDeviceType.LedStripe; - /// - public bool SupportsSyncBack => false; + /// + public string Manufacturer => "Arduino"; - /// - public Uri Image { get; set; } + /// + public string Model => "WS2812 USB"; - #endregion + /// + public object? LayoutMetadata { get; set; } - #region Constructors + #endregion - /// - /// Initializes a new instance of the class. - /// - /// The name of this device. - public ArduinoWS2812USBDeviceInfo(string name) - { - this.DeviceName = name; - } + #region Constructors - #endregion + /// + /// Initializes a new instance of the class. + /// + /// The name of this device. + public ArduinoWS2812USBDeviceInfo(string name) + { + this.DeviceName = name; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs index 6b2c1cb7..603b6f5f 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS2812USBUpdateQueue.cs @@ -2,104 +2,102 @@ using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.Arduino +namespace RGB.NET.Devices.WS281X.Arduino; + +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents the update-queue performing updates for arduino WS2812 devices. +/// +public class ArduinoWS2812USBUpdateQueue : SerialConnectionUpdateQueue { - // ReSharper disable once InconsistentNaming - /// - /// - /// Represents the update-queue performing updates for arduino WS2812 devices. - /// - public class ArduinoWS2812USBUpdateQueue : SerialConnectionUpdateQueue - { - #region Constants + #region Constants - private static readonly byte[] COUNT_COMMAND = { 0x01 }; - private static readonly byte[] UPDATE_COMMAND = { 0x02 }; - private static readonly byte[] ASK_PROMPT_COMMAND = { 0x0F }; + private static readonly byte[] COUNT_COMMAND = { 0x01 }; + private static readonly byte[] UPDATE_COMMAND = { 0x02 }; + private static readonly byte[] ASK_PROMPT_COMMAND = { 0x0F }; - #endregion + #endregion - #region Properties & Fields + #region Properties & Fields - private readonly Dictionary _dataBuffer = new Dictionary(); + private readonly Dictionary _dataBuffer = new(); - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The name of the serial-port to connect to. - /// The baud-rate used by the serial-connection. - public ArduinoWS2812USBUpdateQueue(IDeviceUpdateTrigger updateTrigger, ISerialConnection serialConnection) - : base(updateTrigger, serialConnection) - { } + /// + /// Initializes a new instance of the class. + /// + /// The update trigger used by this queue. + /// The serial connection used to access the device. + public ArduinoWS2812USBUpdateQueue(IDeviceUpdateTrigger updateTrigger, ISerialConnection serialConnection) + : base(updateTrigger, serialConnection) + { } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void OnStartup(object sender, CustomUpdateData customData) - { - base.OnStartup(sender, customData); + /// + protected override void OnStartup(object? sender, CustomUpdateData customData) + { + base.OnStartup(sender, customData); - SendCommand(ASK_PROMPT_COMMAND); // Get initial prompt - } + SendCommand(ASK_PROMPT_COMMAND); // Get initial prompt + } - /// - protected override IEnumerable GetCommands(Dictionary dataSet) + /// + protected override IEnumerable GetCommands(IList<(object key, Color color)> dataSet) + { + foreach (IGrouping channelData in dataSet.Select(x => (((int channel, int key))x.key, x.color)) + .GroupBy(x => x.Item1.channel)) { - foreach (IGrouping channelData in dataSet.Select(x => (((int channel, int key))x.Key, x.Value)) - .GroupBy(x => x.Item1.channel)) + int channel = channelData.Key; + if (!_dataBuffer.TryGetValue(channel, out byte[]? dataBuffer) || (dataBuffer.Length != ((dataSet.Count * 3) + 1))) + _dataBuffer[channel] = dataBuffer = new byte[(dataSet.Count * 3) + 1]; + + dataBuffer[0] = (byte)((channel << 4) | UPDATE_COMMAND[0]); + int i = 1; + foreach ((byte _, byte r, byte g, byte b) in channelData.OrderBy(x => x.Item1.key) + .Select(x => x.Value.GetRGBBytes())) { - int channel = channelData.Key; - if (!_dataBuffer.TryGetValue(channel, out byte[] dataBuffer) || (dataBuffer.Length != ((dataSet.Count * 3) + 1))) - _dataBuffer[channel] = dataBuffer = new byte[(dataSet.Count * 3) + 1]; - - dataBuffer[0] = (byte)((channel << 4) | UPDATE_COMMAND[0]); - int i = 1; - foreach ((byte _, byte r, byte g, byte b) in channelData.OrderBy(x => x.Item1.key) - .Select(x => x.Value.GetRGBBytes())) - { - dataBuffer[i++] = r; - dataBuffer[i++] = g; - dataBuffer[i++] = b; - } - yield return dataBuffer; + dataBuffer[i++] = r; + dataBuffer[i++] = g; + dataBuffer[i++] = b; } - - yield return UPDATE_COMMAND; + yield return dataBuffer; } - /// - protected override void SendCommand(byte[] command) => SerialConnection.Write(command, 0, command.Length); + yield return UPDATE_COMMAND; + } - internal IEnumerable<(int channel, int ledCount)> GetChannels() - { - if (!SerialConnection.IsOpen) - SerialConnection.Open(); + /// + protected override void SendCommand(byte[] command) => SerialConnection.Write(command, 0, command.Length); - SerialConnection.DiscardInBuffer(); - SendCommand(ASK_PROMPT_COMMAND); + internal IEnumerable<(int channel, int ledCount)> GetChannels() + { + if (!SerialConnection.IsOpen) + SerialConnection.Open(); - SerialConnection.ReadTo(Prompt); - SendCommand(COUNT_COMMAND); - int channelCount = SerialConnection.ReadByte(); + SerialConnection.DiscardInBuffer(); + SendCommand(ASK_PROMPT_COMMAND); - for (int i = 1; i <= channelCount; i++) - { - SerialConnection.ReadTo(Prompt); - byte[] channelLedCountCommand = { (byte)((i << 4) | COUNT_COMMAND[0]) }; - SendCommand(channelLedCountCommand); - int ledCount = SerialConnection.ReadByte(); - if (ledCount > 0) - yield return (i, ledCount); - } - } + SerialConnection.ReadTo(Prompt); + SendCommand(COUNT_COMMAND); + int channelCount = SerialConnection.ReadByte(); - #endregion + for (int i = 1; i <= channelCount; i++) + { + SerialConnection.ReadTo(Prompt); + byte[] channelLedCountCommand = { (byte)((i << 4) | COUNT_COMMAND[0]) }; + SendCommand(channelLedCountCommand); + int ledCount = SerialConnection.ReadByte(); + if (ledCount > 0) + yield return (i, ledCount); + } } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs index ff1b88f0..612596d7 100644 --- a/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Arduino/ArduinoWS281XDeviceDefinition.cs @@ -5,80 +5,78 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.Arduino +namespace RGB.NET.Devices.WS281X.Arduino; + +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents a definition of an arduino WS2812 devices. +/// +public class ArduinoWS281XDeviceDefinition : IWS281XDeviceDefinition { - // ReSharper disable once InconsistentNaming - /// + #region Properties & Fields + /// - /// Represents a definition of an arduino WS2812 devices. + /// Gets the serial-connection used for the device. /// - public class ArduinoWS281XDeviceDefinition : IWS281XDeviceDefinition - { - #region Properties & Fields + public ISerialConnection SerialConnection { get; } - /// - /// Gets the serial-connection used for the device. - /// - public ISerialConnection SerialConnection { get; } - - /// - /// Gets the name of the serial-port to connect to. - /// - public string Port => SerialConnection?.Port; + /// + /// Gets the name of the serial-port to connect to. + /// + public string Port => SerialConnection.Port; - /// - /// Gets the baud-rate used by the serial-connection. - /// - public int BaudRate => SerialConnection?.BaudRate ?? 0; + /// + /// Gets the baud-rate used by the serial-connection. + /// + public int BaudRate => SerialConnection.BaudRate; - /// - /// Gets or sets the name used by this device. - /// This allows to use {0} as a placeholder for a incrementing number if multiple devices are created. - /// - public string Name { get; set; } + /// + /// Gets or sets the name used by this device. + /// This allows to use {0} as a placeholder for a incrementing number if multiple devices are created. + /// + public string? Name { get; set; } - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The serial connection used for the device. - public ArduinoWS281XDeviceDefinition(ISerialConnection serialConnection) - { - this.SerialConnection = serialConnection; - } + /// + /// Initializes a new instance of the class. + /// + /// The serial connection used for the device. + public ArduinoWS281XDeviceDefinition(ISerialConnection serialConnection) + { + this.SerialConnection = serialConnection; + } - /// - /// Initializes a new instance of the class. - /// - /// The name of the serial-port to connect to. - /// The baud-rate of the serial-connection. - public ArduinoWS281XDeviceDefinition(string port, int baudRate = 115200) - { - SerialConnection = new SerialPortConnection(port, baudRate); - } + /// + /// Initializes a new instance of the class. + /// + /// The name of the serial-port to connect to. + /// The baud-rate of the serial-connection. + public ArduinoWS281XDeviceDefinition(string port, int baudRate = 115200) + { + SerialConnection = new SerialPortConnection(port, baudRate); + } - #endregion + #endregion - #region Methods + #region Methods - /// - public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) + /// + public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) + { + //TODO DarthAffe 04.03.2021: one queue per device + ArduinoWS2812USBUpdateQueue queue = new(updateTrigger, SerialConnection); + IEnumerable<(int channel, int ledCount)> channels = queue.GetChannels(); + int counter = 0; + foreach ((int channel, int ledCount) in channels) { - ArduinoWS2812USBUpdateQueue queue = new ArduinoWS2812USBUpdateQueue(updateTrigger, SerialConnection); - IEnumerable<(int channel, int ledCount)> channels = queue.GetChannels(); - int counter = 0; - foreach ((int channel, int ledCount) in channels) - { - string name = string.Format(Name ?? $"Arduino WS2812 USB ({Port}) [{{0}}]", ++counter); - ArduinoWS2812USBDevice device = new ArduinoWS2812USBDevice(new ArduinoWS2812USBDeviceInfo(name), queue, channel); - device.Initialize(ledCount); - yield return device; - } + string name = string.Format(Name ?? $"Arduino WS2812 USB ({Port}) [{{0}}]", ++counter); + yield return new ArduinoWS2812USBDevice(new ArduinoWS2812USBDeviceInfo(name), queue, channel, ledCount); } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs index b9e5cf63..a1021262 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDevice.cs @@ -2,76 +2,54 @@ // ReSharper disable UnusedMember.Global using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.Bitwizard -{ - // ReSharper disable once InconsistentNaming - /// - /// - /// Represents an bitwizard WS2812 USB device. - /// - public class BitwizardWS2812USBDevice : AbstractRGBDevice, ILedStripe - { - #region Properties & Fields +namespace RGB.NET.Devices.WS281X.Bitwizard; - /// - /// Gets the update queue performing updates for this device. - /// - public BitwizardWS2812USBUpdateQueue UpdateQueue { get; } - - /// - public override BitwizardWS2812USBDeviceInfo DeviceInfo { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The update queue performing updates for this device. - public BitwizardWS2812USBDevice(BitwizardWS2812USBDeviceInfo deviceInfo, BitwizardWS2812USBUpdateQueue updateQueue) - { - this.DeviceInfo = deviceInfo; - this.UpdateQueue = updateQueue; - } +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents an bitwizard WS2812 USB device. +/// +public class BitwizardWS2812USBDevice : AbstractRGBDevice, ILedStripe +{ + #region Properties & Fields - #endregion + private readonly int _ledOffset; - #region Methods + #endregion - internal void Initialize(int ledCount) - { - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.LedStripe1 + i, new Rectangle(i * 10, 0, 10, 10)); + #region Constructors - //TODO DarthAffe 23.12.2018: Allow to load a layout. + /// + /// Initializes a new instance of the class. + /// + /// The device info of this device. + /// The update queue performing updates for this device. + /// The offset used to access the leds on this device. + /// The amount of leds on this device. + public BitwizardWS2812USBDevice(BitwizardWS2812USBDeviceInfo deviceInfo, BitwizardWS2812USBUpdateQueue updateQueue, int ledOffset, int ledCount) + : base(deviceInfo, updateQueue) + { + this._ledOffset = ledOffset; + InitializeLayout(ledCount); + } - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - } + #endregion - /// - protected override object CreateLedCustomData(LedId ledId) => (int)ledId - (int)LedId.LedStripe1; + #region Methods - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + private void InitializeLayout(int ledCount) + { + for (int i = 0; i < ledCount; i++) + AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); + } - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } + /// + protected override object GetLedCustomData(LedId ledId) => _ledOffset + ((int)ledId - (int)LedId.LedStripe1); - base.Dispose(); - } + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDeviceInfo.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDeviceInfo.cs index 7e86dae1..65f00541 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDeviceInfo.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBDeviceInfo.cs @@ -1,51 +1,43 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.Bitwizard -{ - // ReSharper disable once InconsistentNaming - /// - /// - /// Represents a generic information for a . - /// - public class BitwizardWS2812USBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Devices.WS281X.Bitwizard; - /// - public string DeviceName { get; } - - /// - public RGBDeviceType DeviceType => RGBDeviceType.LedStripe; - - /// - public string Manufacturer => "Bitwizard"; +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents a generic information for a . +/// +public class BitwizardWS2812USBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public string Model => "WS2812 USB"; + /// + public string DeviceName { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public RGBDeviceType DeviceType => RGBDeviceType.LedStripe; - /// - public bool SupportsSyncBack => false; + /// + public string Manufacturer => "Bitwizard"; - /// - public Uri Image { get; set; } + /// + public string Model => "WS2812 USB"; - #endregion + /// + public object? LayoutMetadata { get; set; } - #region Constructors + #endregion - /// - /// Initializes a new instance of the class. - /// - /// The name of this device. - public BitwizardWS2812USBDeviceInfo(string name) - { - this.DeviceName = name; - } + #region Constructors - #endregion + /// + /// Initializes a new instance of the class. + /// + /// The name of this device. + public BitwizardWS2812USBDeviceInfo(string name) + { + this.DeviceName = name; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs index dd6acc04..cb0ef7b1 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS2812USBUpdateQueue.cs @@ -1,47 +1,45 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.Bitwizard +namespace RGB.NET.Devices.WS281X.Bitwizard; + +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents the update-queue performing updates for a bitwizard WS2812 device. +/// +public class BitwizardWS2812USBUpdateQueue : SerialConnectionUpdateQueue { - // ReSharper disable once InconsistentNaming + #region Constructors + /// /// - /// Represents the update-queue performing updates for a bitwizard WS2812 device. + /// Initializes a new instance of the class. /// - public class BitwizardWS2812USBUpdateQueue : SerialConnectionUpdateQueue + /// The update trigger used by this queue. + /// The serial connection used to access the device. + public BitwizardWS2812USBUpdateQueue(IDeviceUpdateTrigger updateTrigger, ISerialConnection serialConnection) + : base(updateTrigger, serialConnection) + { } + + #endregion + + #region Methods + + /// + protected override void OnStartup(object? sender, CustomUpdateData customData) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The name of the serial-port to connect to. - /// The baud-rate used by the serial-connection. - public BitwizardWS2812USBUpdateQueue(IDeviceUpdateTrigger updateTrigger, ISerialConnection serialConnection) - : base(updateTrigger, serialConnection) - { } - - #endregion - - #region Methods - - /// - protected override void OnStartup(object sender, CustomUpdateData customData) - { - base.OnStartup(sender, customData); - - SendCommand(string.Empty); // Get initial prompt - } - - /// - protected override IEnumerable GetCommands(Dictionary dataSet) - { - foreach (KeyValuePair data in dataSet) - yield return $"pix {(int)data.Key} {data.Value.AsRGBHexString(false)}"; - } - - #endregion + base.OnStartup(sender, customData); + + SendCommand(string.Empty); // Get initial prompt } -} + + /// + protected override IEnumerable GetCommands(IList<(object key, Color color)> dataSet) + { + foreach ((object key, Color value) in dataSet) + yield return $"pix {(int)key} {value.AsRGBHexString(false)}"; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs index b7f61b34..3da22034 100644 --- a/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Bitwizard/BitwizardWS281XDeviceDefinition.cs @@ -5,79 +5,92 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.Bitwizard +namespace RGB.NET.Devices.WS281X.Bitwizard; + +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents a definition of an bitwizard WS2812 devices. +/// +public class BitwizardWS281XDeviceDefinition : IWS281XDeviceDefinition { - // ReSharper disable once InconsistentNaming - /// + #region Properties & Fields + + /// + /// Gets the serial-connection used for the device. + /// + public ISerialConnection SerialConnection { get; } + + /// + /// Gets the name of the serial-port to connect to. + /// + public string Port => SerialConnection.Port; + + /// + /// Gets the baud-rate used by the serial-connection. + /// + public int BaudRate => SerialConnection.BaudRate; + + /// + /// Gets or sets the name used by this device. + /// + public string? Name { get; set; } + + /// + /// Gets a list of LED-strips configured on this device. + /// + public List<(int pin, int stripLength)> Strips { get; } = new(); + + /// + /// Gets or sets the amount of leds controlled by one pin. + /// This only needs to be changed if the firmware on the controller is updated. + /// + public int MaxStripLength { get; set; } = 384; + + #endregion + + #region Constructors + /// - /// Represents a definition of an bitwizard WS2812 devices. + /// Initializes a new instance of the class. /// - public class BitwizardWS281XDeviceDefinition : IWS281XDeviceDefinition + /// The serial connection used for the device. + /// A list of LED-strips connected to this device. + public BitwizardWS281XDeviceDefinition(ISerialConnection serialConnection, params (int pin, int stripLength)[] strips) { - #region Properties & Fields - - /// - /// Gets the serial-connection used for the device. - /// - public ISerialConnection SerialConnection { get; } - - /// - /// Gets the name of the serial-port to connect to. - /// - public string Port => SerialConnection?.Port; - - /// - /// Gets the baud-rate used by the serial-connection. - /// - public int BaudRate => SerialConnection?.BaudRate ?? 0; - - /// - /// Gets or sets the name used by this device. - /// - public string Name { get; set; } - - /// - /// Gets or sets the amount of leds of this device. - /// - public int StripLength { get; set; } = 384; - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The serial connection used for the device. - public BitwizardWS281XDeviceDefinition(ISerialConnection serialConnection) - { - this.SerialConnection = serialConnection; - } + this.SerialConnection = serialConnection; - /// - /// Initializes a new instance of the class. - /// - /// The name of the serial-port to connect to. - /// The baud-rate of the serial-connection. - public BitwizardWS281XDeviceDefinition(string port, int baudRate = 115200) - { - SerialConnection = new SerialPortConnection(port, baudRate); - } + Strips.AddRange(strips); + } - #endregion + /// + /// Initializes a new instance of the class. + /// + /// The name of the serial-port to connect to. + /// The baud-rate of the serial-connection. + /// A list of LED-strips connected to this device. + public BitwizardWS281XDeviceDefinition(string port, int baudRate = 115200, params (int pin, int stripLength)[] strips) + { + SerialConnection = new SerialPortConnection(port, baudRate); + + Strips.AddRange(strips); + } + + #endregion - #region Methods + #region Methods - /// - public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) + /// + public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) + { + foreach ((int pin, int stripLength) in Strips) { - BitwizardWS2812USBUpdateQueue queue = new BitwizardWS2812USBUpdateQueue(updateTrigger, SerialConnection); - string name = Name ?? $"Bitwizard WS2812 USB ({Port})"; - BitwizardWS2812USBDevice device = new BitwizardWS2812USBDevice(new BitwizardWS2812USBDeviceInfo(name), queue); - device.Initialize(StripLength); - yield return device; + BitwizardWS2812USBUpdateQueue queue = new(updateTrigger, SerialConnection); + string name = Name ?? $"Bitwizard WS2812 USB ({Port}) Pin {pin}"; + int ledOffset = pin * MaxStripLength; + yield return new BitwizardWS2812USBDevice(new BitwizardWS2812USBDeviceInfo(name), queue, ledOffset, stripLength); } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Generic/ISerialConnection.cs b/RGB.NET.Devices.WS281X/Generic/ISerialConnection.cs index 5851e7a8..81bd1fed 100644 --- a/RGB.NET.Devices.WS281X/Generic/ISerialConnection.cs +++ b/RGB.NET.Devices.WS281X/Generic/ISerialConnection.cs @@ -1,62 +1,61 @@ using System; -namespace RGB.NET.Devices.WS281X +namespace RGB.NET.Devices.WS281X; + +/// +/// Represents a generic serial connection. +/// +public interface ISerialConnection : IDisposable { /// - /// Represents a generic serial connection. - /// - public interface ISerialConnection : IDisposable - { - /// - /// Gets the COM-port used by the serial connection. - /// - string Port { get; } - - /// - /// Gets the baud-rate used by the serial connection. - /// - int BaudRate { get; } - - /// - /// Gets the connection-status of the serial connection. - /// true if connected; otherwise false. - /// - bool IsOpen { get; } - - /// - /// Opens the serial connection. - /// - void Open(); - - /// - /// Discards the in-buffer of the serial connection. - /// - void DiscardInBuffer(); - - /// - /// Reads a single byte from the serial connection - /// - /// The byte read. - byte ReadByte(); - - /// - /// Blocks till the provided char is received from the serial connection. - /// - /// The target-character to read to. - void ReadTo(char target); - - /// - /// Writes the provided data to the serial connection. - /// - /// The buffer containing the data to write. - /// The offset of the data in the buffer. - /// The amount of data to write. - void Write(byte[] buffer, int offset, int length); - - /// - /// Write the provided text to the serial connection followed by a line break. - /// - /// The text to write. - void WriteLine(string line); - } -} + /// Gets the COM-port used by the serial connection. + /// + string Port { get; } + + /// + /// Gets the baud-rate used by the serial connection. + /// + int BaudRate { get; } + + /// + /// Gets the connection-status of the serial connection. + /// true if connected; otherwise false. + /// + bool IsOpen { get; } + + /// + /// Opens the serial connection. + /// + void Open(); + + /// + /// Discards the in-buffer of the serial connection. + /// + void DiscardInBuffer(); + + /// + /// Reads a single byte from the serial connection + /// + /// The byte read. + byte ReadByte(); + + /// + /// Blocks till the provided char is received from the serial connection. + /// + /// The target-character to read to. + void ReadTo(char target); + + /// + /// Writes the provided data to the serial connection. + /// + /// The buffer containing the data to write. + /// The offset of the data in the buffer. + /// The amount of data to write. + void Write(byte[] buffer, int offset, int length); + + /// + /// Write the provided text to the serial connection followed by a line break. + /// + /// The text to write. + void WriteLine(string line); +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Generic/IWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/Generic/IWS281XDeviceDefinition.cs index a6f375ee..aeb42547 100644 --- a/RGB.NET.Devices.WS281X/Generic/IWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/Generic/IWS281XDeviceDefinition.cs @@ -1,18 +1,17 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X +namespace RGB.NET.Devices.WS281X; + +/// +/// Marker interface for WS281X device definitions. +/// +// ReSharper disable once InconsistentNaming +public interface IWS281XDeviceDefinition { /// - /// Marker interface for WS281X device definitions. + /// Gets the devices defined by this definition. /// - // ReSharper disable once InconsistentNaming - public interface IWS281XDeviceDefinition - { - /// - /// Gets the devices defined by this definition. - /// - /// The initialized devices defined by this definition. - IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger); - } -} + /// The initialized devices defined by this definition. + IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger); +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Generic/SerialPortConnection.cs b/RGB.NET.Devices.WS281X/Generic/SerialPortConnection.cs index fded9dc7..7d4ea4db 100644 --- a/RGB.NET.Devices.WS281X/Generic/SerialPortConnection.cs +++ b/RGB.NET.Devices.WS281X/Generic/SerialPortConnection.cs @@ -1,63 +1,67 @@ using System.IO.Ports; -namespace RGB.NET.Devices.WS281X +namespace RGB.NET.Devices.WS281X; + +/// +/// +/// Represents a serial-connection using the default microsoft serial-port implementation. +/// +public class SerialPortConnection : ISerialConnection { - /// + #region Properties & Fields + /// - /// Represents a serial-connection using the default microsoft serial-port implementation. + /// The used for the connection. /// - public class SerialPortConnection : ISerialConnection - { - #region Properties & Fields - - /// - /// The used for the connection. - /// - public SerialPort SerialPort { get; } + public SerialPort SerialPort { get; } - /// - public string Port => SerialPort.PortName; + /// + public string Port => SerialPort.PortName; - /// - public int BaudRate => SerialPort.BaudRate; + /// + public int BaudRate => SerialPort.BaudRate; - /// - public bool IsOpen => SerialPort.IsOpen; + /// + public bool IsOpen => SerialPort.IsOpen; - #endregion + #endregion - #region Constructors + #region Constructors - public SerialPortConnection(string port, int baudRate) - { - SerialPort = new SerialPort(port, baudRate); - } + /// + /// Initializes a new instance of the class. + /// + /// The name of the serial-port to connect to. + /// The baud-rate used by the serial-connection. + public SerialPortConnection(string port, int baudRate) + { + SerialPort = new SerialPort(port, baudRate); + } - #endregion + #endregion - #region Methods + #region Methods - /// - public void Open() => SerialPort.Open(); + /// + public void Open() => SerialPort.Open(); - /// - public void DiscardInBuffer() => SerialPort.DiscardInBuffer(); + /// + public void DiscardInBuffer() => SerialPort.DiscardInBuffer(); - /// - public byte ReadByte() => (byte)SerialPort.ReadByte(); + /// + public byte ReadByte() => (byte)SerialPort.ReadByte(); - /// - public void ReadTo(char target) => SerialPort.ReadTo(target.ToString()); + /// + public void ReadTo(char target) => SerialPort.ReadTo(target.ToString()); - /// - public void Write(byte[] buffer, int offset, int length) => SerialPort.Write(buffer, offset, length); + /// + public void Write(byte[] buffer, int offset, int length) => SerialPort.Write(buffer, offset, length); - /// - public void WriteLine(string line) => SerialPort.WriteLine(line); + /// + public void WriteLine(string line) => SerialPort.WriteLine(line); - /// - public void Dispose() => SerialPort.Dispose(); + /// + public void Dispose() => SerialPort.Dispose(); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs b/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs index 0f343dae..cdd10759 100644 --- a/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/Generic/SerialPortUpdateQueue.cs @@ -1,85 +1,83 @@ -using System.Collections.Generic; -using System.IO.Ports; +using System; +using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X +namespace RGB.NET.Devices.WS281X; + +/// +/// +/// Represents a update queue for serial devices. +/// +/// The type of data sent through the serial connection. +public abstract class SerialConnectionUpdateQueue : UpdateQueue { + #region Properties & Fields + + /// + /// Gets or sets the prompt to wait for between sending commands. + /// + // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global + protected char Prompt { get; set; } = '>'; + + /// + /// Gets the serial port used by this queue. + /// + protected ISerialConnection SerialConnection { get; } + + #endregion + + #region Constructors + /// /// - /// Represents a update queue for serial devices. + /// Initializes a new instance of the class. /// - /// The type of data sent through the serial connection. - public abstract class SerialConnectionUpdateQueue : UpdateQueue + /// The update trigger used by this queue. + /// The serial connection used to access the device. + internal SerialConnectionUpdateQueue(IDeviceUpdateTrigger updateTrigger, ISerialConnection serialConnection) + : base(updateTrigger) { - #region Properties & Fields - - /// - /// Gets or sets the prompt to wait for between sending commands. - /// - // ReSharper disable once AutoPropertyCanBeMadeGetOnly.Global - protected char Prompt { get; set; } = '>'; - - /// - /// Gets the serial port used by this queue. - /// - protected ISerialConnection SerialConnection { get; } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The name of the serial-port to connect to. - /// The baud-rate used by the serial-connection. - internal SerialConnectionUpdateQueue(IDeviceUpdateTrigger updateTrigger, ISerialConnection serialConnection) - : base(updateTrigger) - { - SerialConnection = serialConnection; - } + SerialConnection = serialConnection; + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void OnStartup(object sender, CustomUpdateData customData) - { - base.OnStartup(sender, customData); + /// + protected override void OnStartup(object? sender, CustomUpdateData customData) + { + base.OnStartup(sender, customData); - if (!SerialConnection.IsOpen) - SerialConnection.Open(); + if (!SerialConnection.IsOpen) + SerialConnection.Open(); - SerialConnection.DiscardInBuffer(); - } + SerialConnection.DiscardInBuffer(); + } - /// - protected override void Update(Dictionary dataSet) + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + foreach (TData command in GetCommands(dataSet.ToArray())) { - foreach (TData command in GetCommands(dataSet)) - { - SerialConnection.ReadTo(Prompt); - SendCommand(command); - } + SerialConnection.ReadTo(Prompt); + SendCommand(command); } - - /// - /// Gets the commands that need to be sent to the device to update the requested colors. - /// - /// The set of data that needs to be updated. - /// The commands to be sent. - protected abstract IEnumerable GetCommands(Dictionary dataSet); - - /// - /// Sends a command as a string followed by a line-break to the device. - /// This most likely needs to be overwritten if the data-type isn't string. - /// - /// The command to be sent. - protected virtual void SendCommand(TData command) => SerialConnection.WriteLine((command as string) ?? string.Empty); - - #endregion } -} + + /// + /// Gets the commands that need to be sent to the device to update the requested colors. + /// + /// The set of data that needs to be updated. + /// The commands to be sent. + protected abstract IEnumerable GetCommands(IList<(object key, Color color)> dataSet); + + /// + /// Sends a command as a string followed by a line-break to the device. + /// This most likely needs to be overwritten if the data-type isn't string. + /// + /// The command to be sent. + protected virtual void SendCommand(TData command) => SerialConnection.WriteLine((command as string) ?? string.Empty); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUUpdateMode.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUUpdateMode.cs index f20bd8ef..153f36fb 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUUpdateMode.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUUpdateMode.cs @@ -1,21 +1,20 @@ -namespace RGB.NET.Devices.WS281X.NodeMCU +namespace RGB.NET.Devices.WS281X.NodeMCU; + +/// +/// Contaisn a list of possible update-modes for NodeMCU-devices. +/// +// ReSharper disable once InconsistentNaming +public enum NodeMCUUpdateMode { /// - /// Contaisn a list of possible update-modes for NodeMCU-devices. + /// Updates through the HTTP-REST-API. + /// Slow, but reliable. /// - // ReSharper disable once InconsistentNaming - public enum NodeMCUUpdateMode - { - /// - /// Updates through the HTTP-REST-API. - /// Slow, but reliable. - /// - Http, + Http, - /// - /// Updates through a UDP-connection. - /// Fast, but might skip updates if the network connection is bad. - /// - Udp - } -} + /// + /// Updates through a UDP-connection. + /// Fast, but might skip updates if the network connection is bad. + /// + Udp +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs index 4b03b817..d1a5b980 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDevice.cs @@ -5,83 +5,59 @@ using System.Linq; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.NodeMCU +namespace RGB.NET.Devices.WS281X.NodeMCU; + +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents an NodeMCU WS2812 device. +/// +public class NodeMCUWS2812USBDevice : AbstractRGBDevice, ILedStripe { - // ReSharper disable once InconsistentNaming - /// + #region Properties & Fields + /// - /// Represents an NodeMCU WS2812 device. + /// Gets the channel (as defined in the NodeMCU-sketch) this device is attached to. /// - public class NodeMCUWS2812USBDevice : AbstractRGBDevice, ILedStripe - { - #region Properties & Fields - - /// - /// Gets the update queue performing updates for this device. - /// - public NodeMCUWS2812USBUpdateQueue UpdateQueue { get; } - - /// - public override NodeMCUWS2812USBDeviceInfo DeviceInfo { get; } - - /// - /// Gets the channel (as defined in the NodeMCU-sketch) this device is attached to. - /// - public int Channel { get; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - /// The update queue performing updates for this device. - /// The channel (as defined in the NodeMCU-sketch) this device is attached to. - public NodeMCUWS2812USBDevice(NodeMCUWS2812USBDeviceInfo deviceInfo, NodeMCUWS2812USBUpdateQueue updateQueue, int channel) - { - this.DeviceInfo = deviceInfo; - this.UpdateQueue = updateQueue; - this.Channel = channel; - } + public int Channel { get; } - #endregion + #endregion - #region Methods + #region Constructors - internal void Initialize(int ledCount) - { - for (int i = 0; i < ledCount; i++) - InitializeLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); + /// + /// Initializes a new instance of the class. + /// + /// The device info of this device. + /// The update queue performing updates for this device. + /// The channel (as defined in the NodeMCU-sketch) this device is attached to. + /// The amount of leds on this device. + public NodeMCUWS2812USBDevice(NodeMCUWS2812USBDeviceInfo deviceInfo, NodeMCUWS2812USBUpdateQueue updateQueue, int channel, int ledCount) + : base(deviceInfo, updateQueue) + { + this.Channel = channel; - //TODO DarthAffe 23.12.2018: Allow to load a layout. + InitializeLayout(ledCount); + } - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - } + #endregion - /// - protected override object CreateLedCustomData(LedId ledId) => (Channel, (int)ledId - (int)LedId.LedStripe1); + #region Methods - /// - protected override IEnumerable GetLedsToUpdate(bool flushLeds) => (flushLeds || LedMapping.Values.Any(x => x.IsDirty)) ? LedMapping.Values : null; + private void InitializeLayout(int ledCount) + { + for (int i = 0; i < ledCount; i++) + AddLed(LedId.LedStripe1 + i, new Point(i * 10, 0), new Size(10, 10)); + } - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + /// + protected override object GetLedCustomData(LedId ledId) => (Channel, (int)ledId - (int)LedId.LedStripe1); - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } + /// + protected override IEnumerable GetLedsToUpdate(bool flushLeds) => (flushLeds || LedMapping.Values.Any(x => x.IsDirty)) ? LedMapping.Values : Enumerable.Empty(); - base.Dispose(); - } + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDeviceInfo.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDeviceInfo.cs index 916f5164..0caf3b6c 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDeviceInfo.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBDeviceInfo.cs @@ -1,51 +1,43 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.NodeMCU -{ - // ReSharper disable once InconsistentNaming - /// - /// - /// Represents a generic information for a . - /// - public class NodeMCUWS2812USBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Devices.WS281X.NodeMCU; - /// - public string DeviceName { get; } - - /// - public RGBDeviceType DeviceType => RGBDeviceType.LedStripe; - - /// - public string Manufacturer => "NodeMCU"; +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents a generic information for a . +/// +public class NodeMCUWS2812USBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public string Model => "WS2812 WLAN"; + /// + public string DeviceName { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public RGBDeviceType DeviceType => RGBDeviceType.LedStripe; - /// - public bool SupportsSyncBack => false; + /// + public string Manufacturer => "NodeMCU"; - /// - public Uri Image { get; set; } + /// + public string Model => "WS2812 WLAN"; - #endregion + /// + public object? LayoutMetadata { get; set; } - #region Constructors + #endregion - /// - /// Initializes a new instance of the class. - /// - /// The name of this device. - public NodeMCUWS2812USBDeviceInfo(string name) - { - this.DeviceName = name; - } + #region Constructors - #endregion + /// + /// Initializes a new instance of the class. + /// + /// The name of this device. + public NodeMCUWS2812USBDeviceInfo(string name) + { + this.DeviceName = name; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs index f5feffe9..0e7a9b72 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS2812USBUpdateQueue.cs @@ -7,178 +7,173 @@ using System.Text.RegularExpressions; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.NodeMCU +namespace RGB.NET.Devices.WS281X.NodeMCU; + +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents the update-queue performing updates for NodeMCU WS2812 devices. +/// +public class NodeMCUWS2812USBUpdateQueue : UpdateQueue { - // ReSharper disable once InconsistentNaming - /// - /// - /// Represents the update-queue performing updates for NodeMCU WS2812 devices. - /// - public class NodeMCUWS2812USBUpdateQueue : UpdateQueue - { - #region Properties & Fields + #region Properties & Fields - private readonly string _hostname; + private readonly string _hostname; - private HttpClient _httpClient = new HttpClient(); - private UdpClient _udpClient; + private HttpClient _httpClient = new(); + private UdpClient? _udpClient; - private readonly Dictionary _dataBuffer = new Dictionary(); - private readonly Dictionary _sequenceNumbers = new Dictionary(); + private readonly Dictionary _dataBuffer = new(); + private readonly Dictionary _sequenceNumbers = new(); - private readonly Action _sendDataAction; + private readonly Action _sendDataAction; - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// If this constructor is used UDP updates are disabled. - /// - /// The update trigger used by this queue. - /// The hostname to connect to. - public NodeMCUWS2812USBUpdateQueue(IDeviceUpdateTrigger updateTrigger, string hostname) - : base(updateTrigger) - { - this._hostname = hostname; + /// + /// Initializes a new instance of the class. + /// If this constructor is used UDP updates are disabled. + /// + /// The update trigger used by this queue. + /// The hostname to connect to. + public NodeMCUWS2812USBUpdateQueue(IDeviceUpdateTrigger updateTrigger, string hostname) + : base(updateTrigger) + { + this._hostname = hostname; - _sendDataAction = SendHttp; - } + _sendDataAction = SendHttp; + } - /// - /// Initializes a new instance of the class. - /// If this constructor is used UDP updates are enabled. - /// - /// The update trigger used by this queue. - /// The hostname to connect to. - /// The port used by the UDP-connection. - public NodeMCUWS2812USBUpdateQueue(IDeviceUpdateTrigger updateTrigger, string hostname, int udpPort) - : base(updateTrigger) - { - this._hostname = hostname; + /// + /// Initializes a new instance of the class. + /// If this constructor is used UDP updates are enabled. + /// + /// The update trigger used by this queue. + /// The hostname to connect to. + /// The port used by the UDP-connection. + public NodeMCUWS2812USBUpdateQueue(IDeviceUpdateTrigger updateTrigger, string hostname, int udpPort) + : base(updateTrigger) + { + this._hostname = hostname; - _udpClient = new UdpClient(); - EnableUdp(udpPort); + _udpClient = new UdpClient(); + EnableUdp(udpPort); - _sendDataAction = SendUdp; - } + _sendDataAction = SendUdp; + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void OnStartup(object sender, CustomUpdateData customData) - { - base.OnStartup(sender, customData); + /// + protected override void OnStartup(object? sender, CustomUpdateData customData) + { + base.OnStartup(sender, customData); - ResetDevice(); - } + ResetDevice(); + } - /// - protected override void Update(Dictionary dataSet) + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + foreach (IGrouping channelData in dataSet.ToArray().Select(x => (((int channel, int key))x.key, x.color)).GroupBy(x => x.Item1.channel)) { - foreach (IGrouping channelData in dataSet.Select(x => (((int channel, int key))x.Key, x.Value)) - .GroupBy(x => x.Item1.channel)) - { - byte[] buffer = GetBuffer(channelData); - _sendDataAction(buffer); - } + byte[] buffer = GetBuffer(channelData); + _sendDataAction(buffer); } + } - private void SendHttp(byte[] buffer) - { - string data = Convert.ToBase64String(buffer); - lock (_httpClient) _httpClient?.PostAsync(GetUrl("update"), new StringContent(data, Encoding.ASCII)).Wait(); - } + private void SendHttp(byte[] buffer) + { + string data = Convert.ToBase64String(buffer); + lock (_httpClient) _httpClient.PostAsync(GetUrl("update"), new StringContent(data, Encoding.ASCII)).Wait(); + } - private void SendUdp(byte[] buffer) - { - _udpClient?.Send(buffer, buffer.Length); - } + private void SendUdp(byte[] buffer) + { + _udpClient?.Send(buffer, buffer.Length); + } - private byte[] GetBuffer(IGrouping data) + private byte[] GetBuffer(IGrouping data) + { + int channel = data.Key; + byte[] buffer = _dataBuffer[channel]; + + buffer[0] = GetSequenceNumber(channel); + buffer[1] = (byte)channel; + int i = 2; + foreach ((byte _, byte r, byte g, byte b) in data.OrderBy(x => x.identifier.key) + .Select(x => x.color.GetRGBBytes())) { - int channel = data.Key; - byte[] buffer = _dataBuffer[channel]; - - buffer[0] = GetSequenceNumber(channel); - buffer[1] = (byte)channel; - int i = 2; - foreach ((byte _, byte r, byte g, byte b) in data.OrderBy(x => x.Item1.key) - .Select(x => x.Value.GetRGBBytes())) - { - buffer[i++] = r; - buffer[i++] = g; - buffer[i++] = b; - } - - return buffer; + buffer[i++] = r; + buffer[i++] = g; + buffer[i++] = b; } - internal IEnumerable<(int channel, int ledCount)> GetChannels() - { - string configString; - lock (_httpClient) configString = _httpClient.GetStringAsync(GetUrl("config")).Result; + return buffer; + } + + internal IEnumerable<(int channel, int ledCount)> GetChannels() + { + string configString; + lock (_httpClient) configString = _httpClient.GetStringAsync(GetUrl("config")).Result; - configString = configString.Replace(" ", "") - .Replace("\r", "") - .Replace("\n", ""); + configString = configString.Replace(" ", "") + .Replace("\r", "") + .Replace("\n", ""); - //HACK DarthAffe 13.07.2020: Adding a JSON-Parser dependency just for this is not really worth it right now ... - MatchCollection channelMatches = Regex.Matches(configString, "\\{\"channel\":(?\\d+),\"leds\":(?\\d+)\\}"); - foreach (Match channelMatch in channelMatches) + //HACK DarthAffe 13.07.2020: Adding a JSON-Parser dependency just for this is not really worth it right now ... + MatchCollection channelMatches = Regex.Matches(configString, "\\{\"channel\":(?\\d+),\"leds\":(?\\d+)\\}"); + foreach (Match channelMatch in channelMatches) + { + int channel = int.Parse(channelMatch.Groups["channel"].Value); + int leds = int.Parse(channelMatch.Groups["leds"].Value); + if (leds > 0) { - int channel = int.Parse(channelMatch.Groups["channel"].Value); - int leds = int.Parse(channelMatch.Groups["leds"].Value); - if (leds > 0) - { - _dataBuffer[channel] = new byte[(leds * 3) + 2]; - _sequenceNumbers[channel] = 0; - yield return (channel, leds); - } + _dataBuffer[channel] = new byte[(leds * 3) + 2]; + _sequenceNumbers[channel] = 0; + yield return (channel, leds); } } + } - internal void ResetDevice() - { - lock (_httpClient) _httpClient.GetStringAsync(GetUrl("reset")).Wait(); - } + internal void ResetDevice() + { + lock (_httpClient) _httpClient.GetStringAsync(GetUrl("reset")).Wait(); + } - private void EnableUdp(int port) - { - _httpClient.PostAsync(GetUrl("enableUDP"), new StringContent(port.ToString(), Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Wait(); - _udpClient.Connect(_hostname, port); - } + private void EnableUdp(int port) + { + _httpClient.PostAsync(GetUrl("enableUDP"), new StringContent(port.ToString(), Encoding.UTF8, "application/json")).Result.Content.ReadAsStringAsync().Wait(); + _udpClient?.Connect(_hostname, port); + } - private byte GetSequenceNumber(int channel) - { - byte sequenceNumber = (byte)Math.Max(1, (_sequenceNumbers[channel] + 1) % byte.MaxValue); - _sequenceNumbers[channel] = sequenceNumber; - return sequenceNumber; - } + private byte GetSequenceNumber(int channel) + { + byte sequenceNumber = (byte)Math.Max(1, (_sequenceNumbers[channel] + 1) % byte.MaxValue); + _sequenceNumbers[channel] = sequenceNumber; + return sequenceNumber; + } - /// - public override void Dispose() + /// + public override void Dispose() + { + lock (_httpClient) { - lock (_httpClient) - { - base.Dispose(); + base.Dispose(); -#if NETSTANDARD - _udpClient?.Dispose(); -#endif - _udpClient = null; + _udpClient?.Dispose(); + _udpClient = null; - ResetDevice(); - _httpClient.Dispose(); - _httpClient = null; - } + ResetDevice(); + _httpClient.Dispose(); } + } - private string GetUrl(string path) => $"http://{_hostname}/{path}"; + private string GetUrl(string path) => $"http://{_hostname}/{path}"; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs index f573eab8..0f68f2be 100644 --- a/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs +++ b/RGB.NET.Devices.WS281X/NodeMCU/NodeMCUWS281XDeviceDefinition.cs @@ -6,78 +6,75 @@ using System.Collections.Generic; using RGB.NET.Core; -namespace RGB.NET.Devices.WS281X.NodeMCU +namespace RGB.NET.Devices.WS281X.NodeMCU; + +// ReSharper disable once InconsistentNaming +/// +/// +/// Represents a definition of an NodeMCU WS2812 devices. +/// +public class NodeMCUWS281XDeviceDefinition : IWS281XDeviceDefinition { - // ReSharper disable once InconsistentNaming - /// + #region Properties & Fields + /// - /// Represents a definition of an NodeMCU WS2812 devices. + /// Gets the hostname to connect to. /// - public class NodeMCUWS281XDeviceDefinition : IWS281XDeviceDefinition - { - #region Properties & Fields - - /// - /// Gets the hostname to connect to. - /// - public string Hostname { get; } + public string Hostname { get; } - /// - /// Gets or sets the port of the UDP connection. - /// - public int Port { get; set; } = 1872; + /// + /// Gets or sets the port of the UDP connection. + /// + public int Port { get; set; } = 1872; - /// - /// Gets or sets the update-mode of the device. - /// - public NodeMCUUpdateMode UpdateMode { get; set; } + /// + /// Gets or sets the update-mode of the device. + /// + public NodeMCUUpdateMode UpdateMode { get; set; } - /// - /// Gets or sets the name used by this device. - /// This allows to use {0} as a placeholder for a incrementing number if multiple devices are created. - /// - public string Name { get; set; } + /// + /// Gets or sets the name used by this device. + /// This allows to use {0} as a placeholder for a incrementing number if multiple devices are created. + /// + public string? Name { get; set; } - #endregion + #endregion - #region Constructors + #region Constructors - /// - /// Initializes a new instance of the class. - /// - /// The hostname to connect to. - /// The update mode of the device. - public NodeMCUWS281XDeviceDefinition(string hostname, NodeMCUUpdateMode updateMode = NodeMCUUpdateMode.Udp) - { - this.Hostname = hostname; - this.UpdateMode = updateMode; - } + /// + /// Initializes a new instance of the class. + /// + /// The hostname to connect to. + /// The update mode of the device. + public NodeMCUWS281XDeviceDefinition(string hostname, NodeMCUUpdateMode updateMode = NodeMCUUpdateMode.Udp) + { + this.Hostname = hostname; + this.UpdateMode = updateMode; + } - #endregion + #endregion - #region Methods + #region Methods - /// - public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) + /// + public IEnumerable CreateDevices(IDeviceUpdateTrigger updateTrigger) + { + NodeMCUWS2812USBUpdateQueue queue = UpdateMode switch { - NodeMCUWS2812USBUpdateQueue queue = UpdateMode switch - { - NodeMCUUpdateMode.Http => new NodeMCUWS2812USBUpdateQueue(updateTrigger, Hostname), - NodeMCUUpdateMode.Udp => new NodeMCUWS2812USBUpdateQueue(updateTrigger, Hostname, Port), - _ => throw new ArgumentOutOfRangeException() - }; + NodeMCUUpdateMode.Http => new NodeMCUWS2812USBUpdateQueue(updateTrigger, Hostname), + NodeMCUUpdateMode.Udp => new NodeMCUWS2812USBUpdateQueue(updateTrigger, Hostname, Port), + _ => throw new ArgumentOutOfRangeException() + }; - IEnumerable<(int channel, int ledCount)> channels = queue.GetChannels(); - int counter = 0; - foreach ((int channel, int ledCount) in channels) - { - string name = string.Format(Name ?? $"NodeMCU WS2812 WIFI ({Hostname}) [{{0}}]", ++counter); - NodeMCUWS2812USBDevice device = new NodeMCUWS2812USBDevice(new NodeMCUWS2812USBDeviceInfo(name), queue, channel); - device.Initialize(ledCount); - yield return device; - } + IEnumerable<(int channel, int ledCount)> channels = queue.GetChannels(); + int counter = 0; + foreach ((int channel, int ledCount) in channels) + { + string name = string.Format(Name ?? $"NodeMCU WS2812 WIFI ({Hostname}) [{{0}}]", ++counter); + yield return new NodeMCUWS2812USBDevice(new NodeMCUWS2812USBDeviceInfo(name), queue, channel, ledCount); } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/README.md b/RGB.NET.Devices.WS281X/README.md new file mode 100644 index 00000000..c18d3236 --- /dev/null +++ b/RGB.NET.Devices.WS281X/README.md @@ -0,0 +1,20 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for RGB.NET-Devices based on Aurdion or ESP8266. + +To create your own Aurdion/ESP8266 based controller check the Sketches at [https://github.com/DarthAffe/RGB.NET/tree/master/RGB.NET.Devices.WS281X/Sketches](https://github.com/DarthAffe/RGB.NET/tree/master/RGB.NET.Devices.WS281X/Sketches) + +> If you start a new project it's recommended to use the Raspberry Pi Pico due to it's better performance and lower cost. Check the `RGB.NET.Devices.PicoPi`-package. + +> This provider does not work with WLED. If you want to use that check the `RGB.NET.Devices.DMX`-package. + +## Usage +This provider does not load anything by default and requires additional configuration to work. + +```csharp +// Add as many Arduino or NodeMCU devices as you like +WS281XDeviceProvider.Instance.AddDeviceDefinition(new ArduinoWS281XDeviceDefinition("COM3")); + +surface.Load(WS281XDeviceProvider.Instance); +``` + +# Required SDK +This provider does not require an additional SDK. diff --git a/RGB.NET.Devices.WS281X/RGB.NET.Devices.WS281X.csproj b/RGB.NET.Devices.WS281X/RGB.NET.Devices.WS281X.csproj index c8a987d4..0e0e08f4 100644 --- a/RGB.NET.Devices.WS281X/RGB.NET.Devices.WS281X.csproj +++ b/RGB.NET.Devices.WS281X/RGB.NET.Devices.WS281X.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.WS281X WS281X-Device-Implementations of RGB.NET WS281X-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,41 +35,32 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + - - - + + - - + + \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/RGB.NET.Devices.WS281X.csproj.DotSettings b/RGB.NET.Devices.WS281X/RGB.NET.Devices.WS281X.csproj.DotSettings index acc5fca7..a54436d3 100644 --- a/RGB.NET.Devices.WS281X/RGB.NET.Devices.WS281X.csproj.DotSettings +++ b/RGB.NET.Devices.WS281X/RGB.NET.Devices.WS281X.csproj.DotSettings @@ -1,2 +1,3 @@  - True \ No newline at end of file + True + \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs index 3875cf4a..e2adc455 100644 --- a/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs +++ b/RGB.NET.Devices.WS281X/WS281XDeviceProvider.cs @@ -2,125 +2,80 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using RGB.NET.Core; -using RGB.NET.Devices.WS281X.NodeMCU; -namespace RGB.NET.Devices.WS281X +namespace RGB.NET.Devices.WS281X; + +/// +/// +/// Represents a device provider responsible for WS2812B- and WS2811-Led-devices. +/// +// ReSharper disable once InconsistentNaming +// ReSharper disable once UnusedType.Global +public class WS281XDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static WS281XDeviceProvider? _instance; /// - /// Represents a device provider responsible for WS2812B- and WS2811-Led-devices. + /// Gets the singleton instance. /// - // ReSharper disable once InconsistentNaming - public class WS281XDeviceProvider : IRGBDeviceProvider - { - #region Properties & Fields - - private static WS281XDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static WS281XDeviceProvider Instance => _instance ?? new WS281XDeviceProvider(); - - /// - public bool IsInitialized { get; private set; } - - /// - public IEnumerable Devices { get; private set; } - - /// - public bool HasExclusiveAccess => false; + public static WS281XDeviceProvider Instance => _instance ?? new WS281XDeviceProvider(); - /// - /// Gets a list of all defined device-definitions. - /// - // ReSharper disable once CollectionNeverUpdated.Global - // ReSharper disable once ReturnTypeCanBeEnumerable.Global - public List DeviceDefinitions { get; } = new List(); - - /// - /// The used to trigger the updates for corsair devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; } - - #endregion + /// + /// Gets a list of all defined device-definitions. + /// + // ReSharper disable once CollectionNeverUpdated.Global + // ReSharper disable once ReturnTypeCanBeEnumerable.Global + public List DeviceDefinitions { get; } = new(); - #region Constructors + #endregion - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public WS281XDeviceProvider() - { - if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WS281XDeviceProvider)}"); - _instance = this; + #region Constructors - UpdateTrigger = new DeviceUpdateTrigger(); - } + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public WS281XDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WS281XDeviceProvider)}"); + _instance = this; + } - #endregion + #endregion - #region Methods + #region Methods - /// - /// Adds the given to this device-provider. - /// - /// The to add. - // ReSharper disable once UnusedMember.Global - public void AddDeviceDefinition(IWS281XDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); + /// + /// Adds the specified to this device-provider. + /// + /// The to add. + // ReSharper disable once UnusedMember.Global + public void AddDeviceDefinition(IWS281XDeviceDefinition deviceDefinition) => DeviceDefinitions.Add(deviceDefinition); - /// - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.Unknown, bool exclusiveAccessIfPossible = false, bool throwExceptions = false) - { - IsInitialized = false; - - try - { - UpdateTrigger?.Stop(); - - List devices = new List(); - foreach (IWS281XDeviceDefinition deviceDefinition in DeviceDefinitions) - { - try - { - devices.AddRange(deviceDefinition.CreateDevices(UpdateTrigger)); - } - catch { if (throwExceptions) throw; } - } - UpdateTrigger?.Start(); - - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) - throw; - return false; - } - - return true; - } + /// + protected override void InitializeSDK() { } - /// - public void ResetDevices() + /// + protected override IEnumerable LoadDevices() + { + int i = 0; + foreach (IWS281XDeviceDefinition deviceDefinition in DeviceDefinitions) { - foreach (IRGBDevice device in Devices) - if (device is NodeMCUWS2812USBDevice nodemcuDevice) - nodemcuDevice.UpdateQueue.ResetDevice(); + IDeviceUpdateTrigger updateTrigger = GetUpdateTrigger(i++); + foreach (IRGBDevice device in deviceDefinition.CreateDevices(updateTrigger)) + yield return device; } + } - /// - public void Dispose() - { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */} - - DeviceDefinitions.Clear(); - } + /// + public override void Dispose() + { + base.Dispose(); - #endregion + DeviceDefinitions.Clear(); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.WS281X/WS281XDeviceProviderLoader.cs b/RGB.NET.Devices.WS281X/WS281XDeviceProviderLoader.cs deleted file mode 100644 index 10781a91..00000000 --- a/RGB.NET.Devices.WS281X/WS281XDeviceProviderLoader.cs +++ /dev/null @@ -1,27 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.WS281X -{ - /// - /// - /// Represents a device provider loaded used to dynamically load WS281X devices into an application. - /// - // ReSharper disable once UnusedMember.Global - // ReSharper disable once InconsistentNaming - public class WS281XDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => true; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => WS281XDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs b/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs index 86f79cf4..513fae59 100644 --- a/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs +++ b/RGB.NET.Devices.Wooting/Enum/WootingDeviceType.cs @@ -1,11 +1,24 @@ -namespace RGB.NET.Devices.Wooting.Enum +// ReSharper disable InconsistentNaming + +namespace RGB.NET.Devices.Wooting.Enum; + +/// +/// Represents the type of a wooting device +/// +public enum WootingDeviceType { - public enum WootingDeviceType - { - /// 10 Keyless Keyboard. E.g. Wooting One - KeyboardTKL = 1, + /// + /// 10 Keyless Keyboard. E.g. Wooting One + /// + KeyboardTKL = 1, - /// Full Size keyboard. E.g. Wooting Two - Keyboard = 2 - } -} + /// + /// Full Size keyboard. E.g. Wooting Two + /// + Keyboard = 2, + + /// + /// Full Size keyboard. E.g. Wooting Two + /// + KeyboardSixtyPercent = 3 +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs b/RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs deleted file mode 100644 index c25afa49..00000000 --- a/RGB.NET.Devices.Wooting/Enum/WootingDevicesIndexes.cs +++ /dev/null @@ -1,21 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -using System.ComponentModel; - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Wooting.Enum -{ - /// - /// Contains a list of available device-indexes. - /// - public enum WootingDevicesIndexes - { - [Description("Wooting One")] - WootingOne = 0, - - [Description("Wooting Two")] - WootingTwo = 1 - } -} diff --git a/RGB.NET.Devices.Wooting/Enum/WootingLayoutType.cs b/RGB.NET.Devices.Wooting/Enum/WootingLayoutType.cs new file mode 100644 index 00000000..e01a6d14 --- /dev/null +++ b/RGB.NET.Devices.Wooting/Enum/WootingLayoutType.cs @@ -0,0 +1,18 @@ +// ReSharper disable InconsistentNaming +// ReSharper disable UnusedMember.Global + +#pragma warning disable 1591 // Missing XML comment for publicly visible type or member + +namespace RGB.NET.Devices.Wooting.Enum; + +/// +/// Contains list of available physical layouts for Wooting keyboards. +/// +/// +/// Shop states ANSI (US) and ISO (UK/German/Nodics) - https://wooting.store/collections/wooting-keyboards/products/wooting-two +/// +public enum WootingLayoutType +{ + ANSI = 0, + ISO = 1 +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs b/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs deleted file mode 100644 index 640bfee4..00000000 --- a/RGB.NET.Devices.Wooting/Enum/WootingLogicalKeyboardLayout.cs +++ /dev/null @@ -1,21 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Wooting.Enum -{ - /// - /// Contains list of available logical layouts for cooler master keyboards. - /// - /// - /// Based on what is available in the shop: https://wooting.store/collections/wooting-keyboards/products/wooting-two - /// - public enum WootingLogicalKeyboardLayout - { - US = 0, - UK = 1, - DE = 2, - ND = 3 - }; -} diff --git a/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs b/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs deleted file mode 100644 index 07d830fc..00000000 --- a/RGB.NET.Devices.Wooting/Enum/WootingPhysicalKeyboardLayout.cs +++ /dev/null @@ -1,19 +0,0 @@ -// ReSharper disable InconsistentNaming -// ReSharper disable UnusedMember.Global - -#pragma warning disable 1591 // Missing XML comment for publicly visible type or member - -namespace RGB.NET.Devices.Wooting.Enum -{ - /// - /// Contains list of available physical layouts for Wooting keyboards. - /// - /// - /// Shop states ANSI (US) and ISO (UK/German/Nodics) - https://wooting.store/collections/wooting-keyboards/products/wooting-two - /// - public enum WootingPhysicalKeyboardLayout - { - US = 0, - UK = 1 - } -} diff --git a/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs index b7356eb5..89ab9b5e 100644 --- a/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Generic/IWootingRGBDevice.cs @@ -1,12 +1,9 @@ using RGB.NET.Core; -namespace RGB.NET.Devices.Wooting.Generic -{ - /// - /// Represents a Wooting RGB-device. - /// - internal interface IWootingRGBDevice : IRGBDevice - { - void Initialize(IDeviceUpdateTrigger updateTrigger); - } -} +namespace RGB.NET.Devices.Wooting.Generic; + +/// +/// Represents a Wooting RGB-device. +/// +public interface IWootingRGBDevice : IRGBDevice +{ } \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs index b766da8e..fc28728a 100644 --- a/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDevice.cs @@ -1,77 +1,27 @@ -using System.Linq; -using RGB.NET.Core; +using RGB.NET.Core; -namespace RGB.NET.Devices.Wooting.Generic +namespace RGB.NET.Devices.Wooting.Generic; + +/// +/// +/// +/// Represents a Wooting-device +/// +public abstract class WootingRGBDevice : AbstractRGBDevice, IWootingRGBDevice + where TDeviceInfo : WootingRGBDeviceInfo { - /// - /// + #region Constructors + /// - /// Represents a Wooting-device + /// Initializes a new instance of the class. /// - public abstract class WootingRGBDevice : AbstractRGBDevice, IWootingRGBDevice - where TDeviceInfo : WootingRGBDeviceInfo + /// The generic information provided by Wooting for the device. + /// The update queue used to update this device. + protected WootingRGBDevice(TDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) { - #region Properties & Fields - - /// - /// - /// Gets information about the . - /// - public override TDeviceInfo DeviceInfo { get; } - - /// - /// Gets or sets the update queue performing updates for this device. - /// - // ReSharper disable once MemberCanBePrivate.Global - protected UpdateQueue UpdateQueue { get; set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The generic information provided by Wooting for the device. - protected WootingRGBDevice(TDeviceInfo info) - { - this.DeviceInfo = info; - } - - #endregion - - #region Methods - - /// - /// Initializes the device. - /// - public void Initialize(IDeviceUpdateTrigger updateTrigger) - { - InitializeLayout(); - - if (Size == Size.Invalid) - { - Rectangle ledRectangle = new Rectangle(this.Select(x => x.LedRectangle)); - Size = ledRectangle.Size + new Size(ledRectangle.Location.X, ledRectangle.Location.Y); - } - - UpdateQueue = new WootingUpdateQueue(updateTrigger); - } - - /// - /// Initializes the and of the device. - /// - protected abstract void InitializeLayout(); - - /// - public override void Dispose() - { - try { UpdateQueue?.Dispose(); } - catch { /* at least we tried */ } - - base.Dispose(); - } - - #endregion + RequiresFlush = true; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs index bf91f8d6..ec4500da 100644 --- a/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Generic/WootingRGBDeviceInfo.cs @@ -1,62 +1,63 @@ -using System; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; -using RGB.NET.Devices.Wooting.Helper; +using RGB.NET.Devices.Wooting.Native; -namespace RGB.NET.Devices.Wooting.Generic -{ - /// - /// - /// Represents a generic information for a Wooting-. - /// - public class WootingRGBDeviceInfo : IRGBDeviceInfo - { - #region Properties & Fields +namespace RGB.NET.Devices.Wooting.Generic; - /// - public RGBDeviceType DeviceType { get; } +/// +/// +/// Represents a generic information for a Wooting-. +/// +public class WootingRGBDeviceInfo : IRGBDeviceInfo +{ + #region Properties & Fields - /// - public string DeviceName { get; } + /// + public RGBDeviceType DeviceType { get; } - /// - public string Manufacturer => "Wooting"; + /// + public string DeviceName { get; } - /// - public string Model { get; } + /// + public string Manufacturer => "Wooting"; - /// - public Uri Image { get; set; } + /// + public string Model { get; } - /// - public RGBDeviceLighting Lighting => RGBDeviceLighting.Key; + /// + public object? LayoutMetadata { get; set; } - /// - public bool SupportsSyncBack => false; + /// + /// Gets the of the . + /// + public WootingDeviceType WootingDeviceType { get; } - /// - /// Gets the of the . - /// - public WootingDevicesIndexes DeviceIndex { get; } + /// + /// Gets the of the . + /// + public WootingLayoutType WootingLayoutType { get; } - #endregion + public byte WootingDeviceIndex { get; } - #region Constructors + #endregion - /// - /// Internal constructor of managed . - /// - /// The type of the . - /// The of the . - internal WootingRGBDeviceInfo(RGBDeviceType deviceType, WootingDevicesIndexes deviceIndex) - { - this.DeviceType = deviceType; - this.DeviceIndex = deviceIndex; + #region Constructors - Model = deviceIndex.GetDescription(); - DeviceName = $"{Manufacturer} {Model}"; - } + /// + /// Internal constructor of managed . + /// + /// The type of the . + /// The of the . + internal WootingRGBDeviceInfo(RGBDeviceType deviceType, _WootingDeviceInfo deviceInfo, byte deviceIndex) + { + this.DeviceType = deviceType; + this.WootingDeviceType = deviceInfo.DeviceType; + this.WootingLayoutType = deviceInfo.LayoutType; + this.WootingDeviceIndex = deviceIndex; - #endregion + Model = deviceInfo.Model; + DeviceName = DeviceHelper.CreateDeviceName(Manufacturer, Model); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs b/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs index 8f896100..a9d6f547 100644 --- a/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs +++ b/RGB.NET.Devices.Wooting/Generic/WootingUpdateQueue.cs @@ -1,42 +1,51 @@ -using System.Collections.Generic; +using System; using RGB.NET.Core; using RGB.NET.Devices.Wooting.Native; -namespace RGB.NET.Devices.Wooting.Generic +namespace RGB.NET.Devices.Wooting.Generic; + +/// +/// +/// Represents the update-queue performing updates for cooler master devices. +/// +public class WootingUpdateQueue : UpdateQueue { - /// + #region Properties & Fields + private readonly byte _deviceid; + #endregion + + #region Constructors + /// - /// Represents the update-queue performing updates for cooler master devices. + /// Initializes a new instance of the class. /// - public class WootingUpdateQueue : UpdateQueue + /// The update trigger used by this queue. + public WootingUpdateQueue(IDeviceUpdateTrigger updateTrigger, byte deviceId) + : base(updateTrigger) { - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// The update trigger used by this queue. - public WootingUpdateQueue(IDeviceUpdateTrigger updateTrigger) - : base(updateTrigger) - { - } + this._deviceid = deviceId; + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void Update(Dictionary dataSet) + /// + protected override void Update(in ReadOnlySpan<(object key, Color color)> dataSet) + { + lock (_WootingSDK.SdkLock) { - foreach (KeyValuePair data in dataSet) + _WootingSDK.SelectDevice(_deviceid); + + foreach ((object key, Color color) in dataSet) { - (int row, int column) = ((int, int))data.Key; - _WootingSDK.ArraySetSingle((byte)row, (byte)column, data.Value.GetR(), data.Value.GetG(), data.Value.GetB()); + (int row, int column) = ((int, int))key; + _WootingSDK.ArraySetSingle((byte)row, (byte)column, color.GetR(), color.GetG(), color.GetB()); } _WootingSDK.ArrayUpdateKeyboard(); } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs b/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs index 7c2e8b3a..0ec89587 100644 --- a/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs +++ b/RGB.NET.Devices.Wooting/Helper/EnumExtension.cs @@ -1,41 +1,34 @@ using System; using System.ComponentModel; using System.Reflection; -using RGB.NET.Core; -namespace RGB.NET.Devices.Wooting.Helper +namespace RGB.NET.Devices.Wooting.Helper; + +/// +/// Offers some extensions and helper-methods for enum related things. +/// +internal static class EnumExtension { /// - /// Offers some extensions and helper-methods for enum related things. + /// Gets the value of the . + /// + /// The enum value to get the description from. + /// The value of the or the result of the source. + internal static string GetDescription(this System.Enum source) + => source.GetAttribute()?.Description ?? source.ToString(); + + /// + /// Gets the attribute of type T. /// - internal static class EnumExtension + /// The enum value to get the attribute from + /// The generic attribute type + /// The . + private static T? GetAttribute(this System.Enum source) + where T : Attribute { - /// - /// Gets the value of the . - /// - /// The enum value to get the description from. - /// The generic enum-type - /// The value of the or the result of the source. - internal static string GetDescription(this T source) - where T : struct - { - return source.GetAttribute()?.Description ?? source.ToString(); - } - - /// - /// Gets the attribute of type T. - /// - /// The enum value to get the attribute from - /// The generic attribute type - /// The generic enum-type - /// The . - private static T GetAttribute(this TEnum source) - where T : Attribute - where TEnum : struct - { - FieldInfo fi = source.GetType().GetField(source.ToString()); - T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); - return attributes.Length > 0 ? attributes[0] : null; - } + FieldInfo? fi = source.GetType().GetField(source.ToString()); + if (fi == null) return null; + T[] attributes = (T[])fi.GetCustomAttributes(typeof(T), false); + return attributes.Length > 0 ? attributes[0] : null; } -} +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs index dc9fa155..0b442375 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardLedMappings.cs @@ -1,477 +1,319 @@ // ReSharper disable InconsistentNaming -using System.Collections.Generic; using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; +using System.Collections.Generic; -namespace RGB.NET.Devices.Wooting.Keyboard -{ - /// - /// Contains all the hardware-id mappings for Wooting devices. - /// - internal static class WootingKeyboardLedMappings - { - #region Properties & Fields - - #region Wooting One - - private static readonly Dictionary WootingOne_US = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,2) }, - { LedId.Keyboard_F2, (0,3) }, - { LedId.Keyboard_F3, (0,4) }, - { LedId.Keyboard_F4, (0,5) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,10) }, - { LedId.Keyboard_F10, (0,11) }, - { LedId.Keyboard_F11, (0,12) }, - { LedId.Keyboard_F12, (0,13) }, - { LedId.Keyboard_PrintScreen, (0,14) }, - { LedId.Keyboard_PauseBreak, (0,15) }, - { LedId.Keyboard_Custom1, (0,16) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,13) }, - { LedId.Keyboard_Insert, (1,14) }, - { LedId.Keyboard_Home, (1,15) }, - { LedId.Keyboard_PageUp, (1,16) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,13) }, - { LedId.Keyboard_Delete, (2,14) }, - { LedId.Keyboard_End, (2,15) }, - { LedId.Keyboard_PageDown, (2,16) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_Enter, (3,13) }, - - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,13) }, - { LedId.Keyboard_ArrowUp, (4,15) }, - - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,13) }, - { LedId.Keyboard_ArrowLeft, (5,14) }, - { LedId.Keyboard_ArrowDown, (5,15) }, - { LedId.Keyboard_ArrowRight, (5,16) } - }; - - private static readonly Dictionary WootingOne_UK = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,2) }, - { LedId.Keyboard_F2, (0,3) }, - { LedId.Keyboard_F3, (0,4) }, - { LedId.Keyboard_F4, (0,5) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,10) }, - { LedId.Keyboard_F10, (0,11) }, - { LedId.Keyboard_F11, (0,12) }, - { LedId.Keyboard_F12, (0,13) }, - { LedId.Keyboard_PrintScreen, (0,14) }, - { LedId.Keyboard_PauseBreak, (0,15) }, - { LedId.Keyboard_Custom1, (0,16) }, - - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,13) }, - { LedId.Keyboard_Insert, (1,14) }, - { LedId.Keyboard_Home, (1,15) }, - { LedId.Keyboard_PageUp, (1,16) }, - - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,13) }, - { LedId.Keyboard_Delete, (2,14) }, - { LedId.Keyboard_End, (2,15) }, - { LedId.Keyboard_PageDown, (2,16) }, - - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_NonUsTilde, (3,11) }, - { LedId.Keyboard_Enter, (3,13) }, +namespace RGB.NET.Devices.Wooting.Keyboard; - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_NonUsBackslash, (4,1) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,13) }, - { LedId.Keyboard_ArrowUp, (4,15) }, +/// +/// Contains all the hardware-id mappings for Wooting devices. +/// +internal static class WootingKeyboardLedMappings +{ + #region Properties & Fields - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,13) }, - { LedId.Keyboard_ArrowLeft, (5,14) }, - { LedId.Keyboard_ArrowDown, (5,15) }, - { LedId.Keyboard_ArrowRight, (5,16) } - }; + private static readonly Dictionary TKL = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 2) }, + { LedId.Keyboard_F2, (0, 3) }, + { LedId.Keyboard_F3, (0, 4) }, + { LedId.Keyboard_F4, (0, 5) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 10) }, + { LedId.Keyboard_F10, (0, 11) }, + { LedId.Keyboard_F11, (0, 12) }, + { LedId.Keyboard_F12, (0, 13) }, + { LedId.Keyboard_PrintScreen, (0, 14) }, + { LedId.Keyboard_PauseBreak, (0, 15) }, + { LedId.Keyboard_Custom1, (0, 16) }, - #endregion + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 13) }, + { LedId.Keyboard_Insert, (1, 14) }, + { LedId.Keyboard_Home, (1, 15) }, + { LedId.Keyboard_PageUp, (1, 16) }, - #region Wooting Two + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Backslash, (2, 13) }, + { LedId.Keyboard_Delete, (2, 14) }, + { LedId.Keyboard_End, (2, 15) }, + { LedId.Keyboard_PageDown, (2, 16) }, - private static readonly Dictionary WootingTwo_US = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,2) }, - { LedId.Keyboard_F2, (0,3) }, - { LedId.Keyboard_F3, (0,4) }, - { LedId.Keyboard_F4, (0,5) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,10) }, - { LedId.Keyboard_F10, (0,11) }, - { LedId.Keyboard_F11, (0,12) }, - { LedId.Keyboard_F12, (0,13) }, - { LedId.Keyboard_PrintScreen, (0,14) }, - { LedId.Keyboard_PauseBreak, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_Custom1, (0,17) }, - { LedId.Keyboard_Custom2, (0,18) }, - { LedId.Keyboard_Custom3, (0,19) }, - { LedId.Keyboard_Custom4, (0,20) }, + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_NonUsTilde, (3, 12) }, + { LedId.Keyboard_Enter, (3, 13) }, - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,13) }, - { LedId.Keyboard_Insert, (1,14) }, - { LedId.Keyboard_Home, (1,15) }, - { LedId.Keyboard_PageUp, (1,16) }, - { LedId.Keyboard_NumLock, (1,17) }, - { LedId.Keyboard_NumSlash, (1,18) }, - { LedId.Keyboard_NumAsterisk, (1,19) }, - { LedId.Keyboard_NumMinus, (1,20) }, + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_NonUsBackslash, (4, 1) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 13) }, + { LedId.Keyboard_ArrowUp, (4, 15) }, - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,13) }, - { LedId.Keyboard_Delete, (2,14) }, - { LedId.Keyboard_End, (2,15) }, - { LedId.Keyboard_PageDown, (2,16) }, - { LedId.Keyboard_Num7, (2,17) }, - { LedId.Keyboard_Num8, (2,18) }, - { LedId.Keyboard_Num9, (2,19) }, - { LedId.Keyboard_NumPlus, (2,20) }, + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Function, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 13) }, + { LedId.Keyboard_ArrowLeft, (5, 14) }, + { LedId.Keyboard_ArrowDown, (5, 15) }, + { LedId.Keyboard_ArrowRight, (5, 16) } + }; - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_Enter, (3,13) }, - { LedId.Keyboard_Num4, (3,17) }, - { LedId.Keyboard_Num5, (3,18) }, - { LedId.Keyboard_Num6, (3,19) }, + private static readonly Dictionary Fullsize = new() + { + { LedId.Keyboard_Escape, (0, 0) }, + { LedId.Keyboard_F1, (0, 2) }, + { LedId.Keyboard_F2, (0, 3) }, + { LedId.Keyboard_F3, (0, 4) }, + { LedId.Keyboard_F4, (0, 5) }, + { LedId.Keyboard_F5, (0, 6) }, + { LedId.Keyboard_F6, (0, 7) }, + { LedId.Keyboard_F7, (0, 8) }, + { LedId.Keyboard_F8, (0, 9) }, + { LedId.Keyboard_F9, (0, 10) }, + { LedId.Keyboard_F10, (0, 11) }, + { LedId.Keyboard_F11, (0, 12) }, + { LedId.Keyboard_F12, (0, 13) }, + { LedId.Keyboard_PrintScreen, (0, 14) }, + { LedId.Keyboard_PauseBreak, (0, 15) }, + { LedId.Keyboard_ScrollLock, (0, 16) }, + { LedId.Keyboard_Custom1, (0, 17) }, + { LedId.Keyboard_Custom2, (0, 18) }, + { LedId.Keyboard_Custom3, (0, 19) }, + { LedId.Keyboard_Custom4, (0, 20) }, - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,13) }, - { LedId.Keyboard_ArrowUp, (4,15) }, - { LedId.Keyboard_Num1, (4,17) }, - { LedId.Keyboard_Num2, (4,18) }, - { LedId.Keyboard_Num3, (4,19) }, - { LedId.Keyboard_NumEnter, (4,20) }, + { LedId.Keyboard_GraveAccentAndTilde, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 13) }, + { LedId.Keyboard_Insert, (1, 14) }, + { LedId.Keyboard_Home, (1, 15) }, + { LedId.Keyboard_PageUp, (1, 16) }, + { LedId.Keyboard_NumLock, (1, 17) }, + { LedId.Keyboard_NumSlash, (1, 18) }, + { LedId.Keyboard_NumAsterisk, (1, 19) }, + { LedId.Keyboard_NumMinus, (1, 20) }, - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,13) }, - { LedId.Keyboard_ArrowLeft, (5,14) }, - { LedId.Keyboard_ArrowDown, (5,15) }, - { LedId.Keyboard_ArrowRight, (5,16) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,19) } - }; + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Backslash, (2, 13) }, + { LedId.Keyboard_Delete, (2, 14) }, + { LedId.Keyboard_End, (2, 15) }, + { LedId.Keyboard_PageDown, (2, 16) }, + { LedId.Keyboard_Num7, (2, 17) }, + { LedId.Keyboard_Num8, (2, 18) }, + { LedId.Keyboard_Num9, (2, 19) }, + { LedId.Keyboard_NumPlus, (2, 20) }, - private static readonly Dictionary WootingTwo_UK = new Dictionary - { - { LedId.Keyboard_Escape, (0,0) }, - { LedId.Keyboard_F1, (0,2) }, - { LedId.Keyboard_F2, (0,3) }, - { LedId.Keyboard_F3, (0,4) }, - { LedId.Keyboard_F4, (0,5) }, - { LedId.Keyboard_F5, (0,6) }, - { LedId.Keyboard_F6, (0,7) }, - { LedId.Keyboard_F7, (0,8) }, - { LedId.Keyboard_F8, (0,9) }, - { LedId.Keyboard_F9, (0,10) }, - { LedId.Keyboard_F10, (0,11) }, - { LedId.Keyboard_F11, (0,12) }, - { LedId.Keyboard_F12, (0,13) }, - { LedId.Keyboard_PrintScreen, (0,14) }, - { LedId.Keyboard_PauseBreak, (0,15) }, - { LedId.Keyboard_ScrollLock, (0,16) }, - { LedId.Keyboard_Custom1, (0,17) }, - { LedId.Keyboard_Custom2, (0,18) }, - { LedId.Keyboard_Custom3, (0,19) }, - { LedId.Keyboard_Custom4, (0,20) }, + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_NonUsTilde, (3, 12) }, + { LedId.Keyboard_Enter, (3, 13) }, + { LedId.Keyboard_Num4, (3, 17) }, + { LedId.Keyboard_Num5, (3, 18) }, + { LedId.Keyboard_Num6, (3, 19) }, - { LedId.Keyboard_GraveAccentAndTilde, (1,0) }, - { LedId.Keyboard_1, (1,1) }, - { LedId.Keyboard_2, (1,2) }, - { LedId.Keyboard_3, (1,3) }, - { LedId.Keyboard_4, (1,4) }, - { LedId.Keyboard_5, (1,5) }, - { LedId.Keyboard_6, (1,6) }, - { LedId.Keyboard_7, (1,7) }, - { LedId.Keyboard_8, (1,8) }, - { LedId.Keyboard_9, (1,9) }, - { LedId.Keyboard_0, (1,10) }, - { LedId.Keyboard_MinusAndUnderscore, (1,11) }, - { LedId.Keyboard_EqualsAndPlus, (1,12) }, - { LedId.Keyboard_Backspace, (1,13) }, - { LedId.Keyboard_Insert, (1,14) }, - { LedId.Keyboard_Home, (1,15) }, - { LedId.Keyboard_PageUp, (1,16) }, - { LedId.Keyboard_NumLock, (1,17) }, - { LedId.Keyboard_NumSlash, (1,18) }, - { LedId.Keyboard_NumAsterisk, (1,19) }, - { LedId.Keyboard_NumMinus, (1,20) }, + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_NonUsBackslash, (4, 1) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 13) }, + { LedId.Keyboard_ArrowUp, (4, 15) }, + { LedId.Keyboard_Num1, (4, 17) }, + { LedId.Keyboard_Num2, (4, 18) }, + { LedId.Keyboard_Num3, (4, 19) }, + { LedId.Keyboard_NumEnter, (4, 20) }, - { LedId.Keyboard_Tab, (2,0) }, - { LedId.Keyboard_Q, (2,1) }, - { LedId.Keyboard_W, (2,2) }, - { LedId.Keyboard_E, (2,3) }, - { LedId.Keyboard_R, (2,4) }, - { LedId.Keyboard_T, (2,5) }, - { LedId.Keyboard_Y, (2,6) }, - { LedId.Keyboard_U, (2,7) }, - { LedId.Keyboard_I, (2,8) }, - { LedId.Keyboard_O, (2,9) }, - { LedId.Keyboard_P, (2,10) }, - { LedId.Keyboard_BracketLeft, (2,11) }, - { LedId.Keyboard_BracketRight, (2,12) }, - { LedId.Keyboard_Backslash, (2,13) }, - { LedId.Keyboard_Delete, (2,14) }, - { LedId.Keyboard_End, (2,15) }, - { LedId.Keyboard_PageDown, (2,16) }, - { LedId.Keyboard_Num7, (2,17) }, - { LedId.Keyboard_Num8, (2,18) }, - { LedId.Keyboard_Num9, (2,19) }, - { LedId.Keyboard_NumPlus, (2,20) }, + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_RightGui, (5, 11) }, + { LedId.Keyboard_Function, (5, 12) }, + { LedId.Keyboard_RightCtrl, (5, 13) }, + { LedId.Keyboard_ArrowLeft, (5, 14) }, + { LedId.Keyboard_ArrowDown, (5, 15) }, + { LedId.Keyboard_ArrowRight, (5, 16) }, + { LedId.Keyboard_Num0, (5, 18) }, + { LedId.Keyboard_NumPeriodAndDelete, (5, 19) } + }; - { LedId.Keyboard_CapsLock, (3,0) }, - { LedId.Keyboard_A, (3,1) }, - { LedId.Keyboard_S, (3,2) }, - { LedId.Keyboard_D, (3,3) }, - { LedId.Keyboard_F, (3,4) }, - { LedId.Keyboard_G, (3,5) }, - { LedId.Keyboard_H, (3,6) }, - { LedId.Keyboard_J, (3,7) }, - { LedId.Keyboard_K, (3,8) }, - { LedId.Keyboard_L, (3,9) }, - { LedId.Keyboard_SemicolonAndColon, (3,10) }, - { LedId.Keyboard_ApostropheAndDoubleQuote, (3,11) }, - { LedId.Keyboard_NonUsTilde, (3,12) }, - { LedId.Keyboard_Enter, (3,13) }, - { LedId.Keyboard_Num4, (3,17) }, - { LedId.Keyboard_Num5, (3,18) }, - { LedId.Keyboard_Num6, (3,19) }, + private static readonly Dictionary SixtyPercent = new() + { + { LedId.Keyboard_Escape, (1, 0) }, + { LedId.Keyboard_1, (1, 1) }, + { LedId.Keyboard_2, (1, 2) }, + { LedId.Keyboard_3, (1, 3) }, + { LedId.Keyboard_4, (1, 4) }, + { LedId.Keyboard_5, (1, 5) }, + { LedId.Keyboard_6, (1, 6) }, + { LedId.Keyboard_7, (1, 7) }, + { LedId.Keyboard_8, (1, 8) }, + { LedId.Keyboard_9, (1, 9) }, + { LedId.Keyboard_0, (1, 10) }, + { LedId.Keyboard_MinusAndUnderscore, (1, 11) }, + { LedId.Keyboard_EqualsAndPlus, (1, 12) }, + { LedId.Keyboard_Backspace, (1, 13) }, - { LedId.Keyboard_LeftShift, (4,0) }, - { LedId.Keyboard_NonUsBackslash, (4,1) }, - { LedId.Keyboard_Z, (4,2) }, - { LedId.Keyboard_X, (4,3) }, - { LedId.Keyboard_C, (4,4) }, - { LedId.Keyboard_V, (4,5) }, - { LedId.Keyboard_B, (4,6) }, - { LedId.Keyboard_N, (4,7) }, - { LedId.Keyboard_M, (4,8) }, - { LedId.Keyboard_CommaAndLessThan, (4,9) }, - { LedId.Keyboard_PeriodAndBiggerThan, (4,10) }, - { LedId.Keyboard_SlashAndQuestionMark, (4,11) }, - { LedId.Keyboard_RightShift, (4,13) }, - { LedId.Keyboard_ArrowUp, (4,15) }, - { LedId.Keyboard_Num1, (4,17) }, - { LedId.Keyboard_Num2, (4,18) }, - { LedId.Keyboard_Num3, (4,19) }, - { LedId.Keyboard_NumEnter, (4,20) }, + { LedId.Keyboard_Tab, (2, 0) }, + { LedId.Keyboard_Q, (2, 1) }, + { LedId.Keyboard_W, (2, 2) }, + { LedId.Keyboard_E, (2, 3) }, + { LedId.Keyboard_R, (2, 4) }, + { LedId.Keyboard_T, (2, 5) }, + { LedId.Keyboard_Y, (2, 6) }, + { LedId.Keyboard_U, (2, 7) }, + { LedId.Keyboard_I, (2, 8) }, + { LedId.Keyboard_O, (2, 9) }, + { LedId.Keyboard_P, (2, 10) }, + { LedId.Keyboard_BracketLeft, (2, 11) }, + { LedId.Keyboard_BracketRight, (2, 12) }, + { LedId.Keyboard_Backslash, (2, 13) }, - { LedId.Keyboard_LeftCtrl, (5,0) }, - { LedId.Keyboard_LeftGui, (5,1) }, - { LedId.Keyboard_LeftAlt, (5,2) }, - { LedId.Keyboard_Space, (5,6) }, - { LedId.Keyboard_RightAlt, (5,10) }, - { LedId.Keyboard_RightGui, (5,11) }, - { LedId.Keyboard_Application, (5,12) }, - { LedId.Keyboard_RightCtrl, (5,13) }, - { LedId.Keyboard_ArrowLeft, (5,14) }, - { LedId.Keyboard_ArrowDown, (5,15) }, - { LedId.Keyboard_ArrowRight, (5,16) }, - { LedId.Keyboard_Num0, (5,18) }, - { LedId.Keyboard_NumPeriodAndDelete, (5,19) } - }; + { LedId.Keyboard_CapsLock, (3, 0) }, + { LedId.Keyboard_A, (3, 1) }, + { LedId.Keyboard_S, (3, 2) }, + { LedId.Keyboard_D, (3, 3) }, + { LedId.Keyboard_F, (3, 4) }, + { LedId.Keyboard_G, (3, 5) }, + { LedId.Keyboard_H, (3, 6) }, + { LedId.Keyboard_J, (3, 7) }, + { LedId.Keyboard_K, (3, 8) }, + { LedId.Keyboard_L, (3, 9) }, + { LedId.Keyboard_SemicolonAndColon, (3, 10) }, + { LedId.Keyboard_ApostropheAndDoubleQuote, (3, 11) }, + { LedId.Keyboard_NonUsTilde, (3, 12) }, + { LedId.Keyboard_Enter, (3, 13) }, - #endregion + { LedId.Keyboard_LeftShift, (4, 0) }, + { LedId.Keyboard_NonUsBackslash, (4, 1) }, + { LedId.Keyboard_Z, (4, 2) }, + { LedId.Keyboard_X, (4, 3) }, + { LedId.Keyboard_C, (4, 4) }, + { LedId.Keyboard_V, (4, 5) }, + { LedId.Keyboard_B, (4, 6) }, + { LedId.Keyboard_N, (4, 7) }, + { LedId.Keyboard_M, (4, 8) }, + { LedId.Keyboard_CommaAndLessThan, (4, 9) }, + { LedId.Keyboard_PeriodAndBiggerThan, (4, 10) }, + { LedId.Keyboard_SlashAndQuestionMark, (4, 11) }, + { LedId.Keyboard_RightShift, (4, 13) }, - /// - /// Contains all the hardware-id mappings for Wooting devices. - /// - public static readonly Dictionary>> Mapping = - new Dictionary>> - { - { WootingDevicesIndexes.WootingOne, new Dictionary> - { - { WootingPhysicalKeyboardLayout.US, WootingOne_US }, - { WootingPhysicalKeyboardLayout.UK, WootingOne_UK } - } - }, + { LedId.Keyboard_LeftCtrl, (5, 0) }, + { LedId.Keyboard_LeftGui, (5, 1) }, + { LedId.Keyboard_LeftAlt, (5, 2) }, + { LedId.Keyboard_Custom1, (5, 4) }, + { LedId.Keyboard_Custom2, (5, 5) }, + { LedId.Keyboard_Space, (5, 6) }, + { LedId.Keyboard_Custom3, (5, 7) }, + { LedId.Keyboard_Custom4, (5, 8) }, + { LedId.Keyboard_RightAlt, (5, 10) }, + { LedId.Keyboard_Application, (5, 11) }, + { LedId.Keyboard_RightCtrl, (5, 12) }, + { LedId.Keyboard_Function, (5, 13) } + }; - { WootingDevicesIndexes.WootingTwo, new Dictionary> - { - { WootingPhysicalKeyboardLayout.US, WootingTwo_US }, - { WootingPhysicalKeyboardLayout.UK, WootingTwo_UK } - } - } - }; + /// + /// Contains all the hardware-id mappings for Wooting devices. + /// + public static readonly Dictionary> Mapping = new() + { + [WootingDeviceType.Keyboard] = Fullsize, + [WootingDeviceType.KeyboardTKL] = TKL, + [WootingDeviceType.KeyboardSixtyPercent] = SixtyPercent + }; - #endregion - } -} + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs index 3ccc35ae..502927ad 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDevice.cs @@ -1,53 +1,61 @@ using System.Collections.Generic; -using System.Linq; using RGB.NET.Core; using RGB.NET.Devices.Wooting.Generic; +using RGB.NET.Devices.Wooting.Native; -namespace RGB.NET.Devices.Wooting.Keyboard +namespace RGB.NET.Devices.Wooting.Keyboard; + +/// +/// +/// Represents a Wooting keyboard. +/// +public class WootingKeyboardRGBDevice : WootingRGBDevice, IKeyboard { - /// + #region Properties & Fields + + IKeyboardDeviceInfo IKeyboard.DeviceInfo => DeviceInfo; + + #endregion + + #region Constructors + + /// /// - /// Represents a Wooting keyboard. + /// Initializes a new instance of the class. /// - public class WootingKeyboardRGBDevice : WootingRGBDevice, IKeyboard + /// The specific information provided by Wooting for the keyboard + /// The update trigger used to update this device. + internal WootingKeyboardRGBDevice(WootingKeyboardRGBDeviceInfo info, IUpdateQueue updateQueue) + : base(info, updateQueue) { - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// The specific information provided by Wooting for the keyboard - internal WootingKeyboardRGBDevice(WootingKeyboardRGBDeviceInfo info) - : base(info) - { } + InitializeLayout(); + } - #endregion + #endregion - #region Methods + #region Methods - /// - protected override void InitializeLayout() - { - - Dictionary mapping = WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout]; + private void InitializeLayout() + { + Dictionary mapping = WootingKeyboardLedMappings.Mapping[DeviceInfo.WootingDeviceType]; - foreach (KeyValuePair led in mapping) - { - InitializeLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19,19)); - } + foreach (KeyValuePair led in mapping) + AddLed(led.Key, new Point(led.Value.column * 19, led.Value.row * 19), new Size(19, 19)); + } - string model = DeviceInfo.Model.Replace(" ", string.Empty).ToUpper(); - ApplyLayoutFromFile(PathHelper.GetAbsolutePath(this, $@"Layouts\Wooting\Keyboards\{model}", $"{DeviceInfo.PhysicalLayout.ToString().ToUpper()}.xml"), - DeviceInfo.LogicalLayout.ToString()); - } + /// + protected override object GetLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.WootingDeviceType][ledId]; - /// - protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(ledsToUpdate.Where(x => x.Color.A > 0)); + /// + protected override void UpdateLeds(IEnumerable ledsToUpdate) => UpdateQueue.SetData(GetUpdateData(ledsToUpdate)); - /// - protected override object CreateLedCustomData(LedId ledId) => WootingKeyboardLedMappings.Mapping[DeviceInfo.DeviceIndex][DeviceInfo.PhysicalLayout][ledId]; + public override void Dispose() + { + _WootingSDK.SelectDevice(DeviceInfo.WootingDeviceIndex); + _WootingSDK.Reset(); - #endregion + base.Dispose(); } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs index b2bcc704..dfcc8eb5 100644 --- a/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Keyboard/WootingKeyboardRGBDeviceInfo.cs @@ -1,63 +1,39 @@ -using System.Globalization; -using RGB.NET.Core; +using RGB.NET.Core; using RGB.NET.Devices.Wooting.Enum; using RGB.NET.Devices.Wooting.Generic; +using RGB.NET.Devices.Wooting.Native; -namespace RGB.NET.Devices.Wooting.Keyboard -{ - /// - /// - /// Represents a generic information for a . - /// - public class WootingKeyboardRGBDeviceInfo : WootingRGBDeviceInfo - { - #region Properties & Fields - - /// - /// Gets the of the . - /// - public WootingPhysicalKeyboardLayout PhysicalLayout { get; } +namespace RGB.NET.Devices.Wooting.Keyboard; - /// - /// Gets the of the . - /// - public WootingLogicalKeyboardLayout LogicalLayout { get; private set; } - - #endregion +/// +/// Represents a generic information for a . +/// +public class WootingKeyboardRGBDeviceInfo : WootingRGBDeviceInfo, IKeyboardDeviceInfo +{ + #region Properties & Fields - #region Constructors + /// + public KeyboardLayoutType Layout { get; } - /// - /// - /// Internal constructor of managed . - /// - /// The index of the . - /// The of the . - /// The of the layout this keyboard is using - internal WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes deviceIndex, WootingPhysicalKeyboardLayout physicalKeyboardLayout, - CultureInfo culture) - : base(RGBDeviceType.Keyboard, deviceIndex) - { - this.PhysicalLayout = physicalKeyboardLayout; + #endregion - DetermineLogicalLayout(culture.KeyboardLayoutId); - } + #region Constructors - private void DetermineLogicalLayout(int keyboardLayoutId) + /// + /// + /// Internal constructor of managed . + /// + /// The native . + internal WootingKeyboardRGBDeviceInfo(_WootingDeviceInfo deviceInfo, byte deviceIndex) + : base(RGBDeviceType.Keyboard, deviceInfo, deviceIndex) + { + Layout = WootingLayoutType switch { - switch (keyboardLayoutId) - { - // TODO SpoinkyNL 15-12-2019: There doesn't seem to be an accurate way to determine this, perhaps it should be a configurable thing.. - // I'm using US International and it's reporting nl-NL's 1043. Also you can after all just swap your keycaps - default: - if (PhysicalLayout == WootingPhysicalKeyboardLayout.US) - LogicalLayout = WootingLogicalKeyboardLayout.US; - else - LogicalLayout = WootingLogicalKeyboardLayout.UK; - break; - } - } - - #endregion + WootingLayoutType.ANSI => KeyboardLayoutType.ANSI, + WootingLayoutType.ISO => KeyboardLayoutType.ISO, + _ => KeyboardLayoutType.Unknown + }; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs b/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs index d22a518b..a672f315 100644 --- a/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs +++ b/RGB.NET.Devices.Wooting/Native/_WootingDeviceInfo.cs @@ -1,21 +1,27 @@ -using System.Runtime.InteropServices; +#pragma warning disable IDE1006 // Naming Styles +// ReSharper disable InconsistentNaming + +using System.Runtime.InteropServices; using RGB.NET.Devices.Wooting.Enum; -namespace RGB.NET.Devices.Wooting.Native +namespace RGB.NET.Devices.Wooting.Native; + +[StructLayout(LayoutKind.Sequential)] +internal struct _WootingDeviceInfo { - [StructLayout(LayoutKind.Sequential)] - internal struct _WootingDeviceInfo - { - internal bool Connected { get; private set; } + internal bool Connected { get; private set; } + + internal string Model { get; private set; } + + internal byte MaxRows { get; private set; } - internal string Model { get; private set; } + internal byte MaxColumns { get; private set; } - internal byte MaxRows { get; private set; } + internal byte KeycodeLimit { get; private set; } - internal byte MaxColumns { get; private set; } + internal WootingDeviceType DeviceType { get; private set; } - internal byte KeycodeLimit { get; private set; } + internal bool V2Interface { get; set; } - internal WootingDeviceType DeviceType { get; private set; } - } -} + internal WootingLayoutType LayoutType { get; private set; } +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs index 1bb7dd94..07bc8ed7 100644 --- a/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs +++ b/RGB.NET.Devices.Wooting/Native/_WootingSDK.cs @@ -1,4 +1,4 @@ -// ReSharper disable UnusedMethodReturnValue.Global +// ReSharper disable UnusedMethodReturnValue.Global // ReSharper disable UnusedMember.Global using System; @@ -8,115 +8,116 @@ using System.Runtime.InteropServices; using RGB.NET.Core; -namespace RGB.NET.Devices.Wooting.Native -{ - // ReSharper disable once InconsistentNaming - internal static class _WootingSDK - { - #region Library management - - private static IntPtr _dllHandle = IntPtr.Zero; - - /// - /// Gets the loaded architecture (x64/x86). - /// - internal static string LoadedArchitecture { get; private set; } - - /// - /// Reloads the SDK. - /// - internal static void Reload() - { - UnloadWootingSDK(); - LoadWootingSDK(); - } - - private static void LoadWootingSDK() - { - if (_dllHandle != IntPtr.Zero) return; - - // HACK: Load library at runtime to support both, x86 and x64 with one managed dll - List possiblePathList = Environment.Is64BitProcess ? WootingDeviceProvider.PossibleX64NativePaths : WootingDeviceProvider.PossibleX86NativePaths; - string dllPath = possiblePathList.FirstOrDefault(File.Exists); - if (dllPath == null) throw new RGBDeviceException($"Can't find the Wooting-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); - - SetDllDirectory(Path.GetDirectoryName(Path.GetFullPath(dllPath))); - - _dllHandle = LoadLibrary(dllPath); - - _getDeviceInfoPointer = (GetDeviceInfoPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_device_info"), typeof(GetDeviceInfoPointer)); - _keyboardConnectedPointer = (KeyboardConnectedPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_kbd_connected"), typeof(KeyboardConnectedPointer)); - _resetPointer = (ResetPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_reset_rgb"), typeof(ResetPointer)); - _closePointer = (ClosePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_close"), typeof(ClosePointer)); - _arrayUpdateKeyboardPointer = (ArrayUpdateKeyboardPointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_array_update_keyboard"), typeof(ArrayUpdateKeyboardPointer)); - _arraySetSinglePointer = (ArraySetSinglePointer)Marshal.GetDelegateForFunctionPointer(GetProcAddress(_dllHandle, "wooting_rgb_array_set_single"), typeof(ArraySetSinglePointer)); - } - - internal static void UnloadWootingSDK() - { - if (_dllHandle == IntPtr.Zero) return; - - // ReSharper disable once EmptyEmbeddedStatement - DarthAffe 20.02.2016: We might need to reduce the internal reference counter more than once to set the library free - while (FreeLibrary(_dllHandle)) ; - _dllHandle = IntPtr.Zero; - } +namespace RGB.NET.Devices.Wooting.Native; - [DllImport("kernel32.dll")] - private static extern bool SetDllDirectory(string lpPathName); - - [DllImport("kernel32.dll")] - private static extern IntPtr LoadLibrary(string dllToLoad); +// ReSharper disable once InconsistentNaming +internal static class _WootingSDK +{ + #region Library management - [DllImport("kernel32.dll")] - private static extern bool FreeLibrary(IntPtr dllHandle); + private static IntPtr _handle = IntPtr.Zero; + internal static object SdkLock = new(); - [DllImport("kernel32.dll")] - private static extern IntPtr GetProcAddress(IntPtr dllHandle, string name); + /// + /// Reloads the SDK. + /// + internal static void Reload() + { + UnloadWootingSDK(); + LoadWootingSDK(); + } - #endregion + private static void LoadWootingSDK() + { + if (_handle != IntPtr.Zero) return; + + List possiblePathList = GetPossibleLibraryPaths().ToList(); + + string? dllPath = possiblePathList.FirstOrDefault(File.Exists); + if (dllPath == null) throw new RGBDeviceException($"Can't find the Wooting-SDK at one of the expected locations:\r\n '{string.Join("\r\n", possiblePathList.Select(Path.GetFullPath))}'"); + + if (!NativeLibrary.TryLoad(dllPath, out _handle)) +#if NET6_0 + throw new RGBDeviceException($"Wooting LoadLibrary failed with error code {Marshal.GetLastPInvokeError()}"); +#else + throw new RGBDeviceException($"Wooting LoadLibrary failed with error code {Marshal.GetLastWin32Error()}"); +#endif + + if (!NativeLibrary.TryGetExport(_handle, "wooting_rgb_device_info", out _getDeviceInfoPointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_rgb_device_info'"); + if (!NativeLibrary.TryGetExport(_handle, "wooting_rgb_kbd_connected", out _keyboardConnectedPointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_rgb_kbd_connected'"); + if (!NativeLibrary.TryGetExport(_handle, "wooting_rgb_reset_rgb", out _resetPointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_rgb_reset_rgb'"); + if (!NativeLibrary.TryGetExport(_handle, "wooting_rgb_close", out _closePointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_rgb_close'"); + if (!NativeLibrary.TryGetExport(_handle, "wooting_rgb_array_update_keyboard", out _arrayUpdateKeyboardPointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_rgb_array_update_keyboard'"); + if (!NativeLibrary.TryGetExport(_handle, "wooting_rgb_array_set_single", out _arraySetSinglePointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_rgb_array_set_single'"); + if (!NativeLibrary.TryGetExport(_handle, "wooting_usb_device_count", out _getDeviceCountPointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_usb_device_count'"); + if (!NativeLibrary.TryGetExport(_handle, "wooting_usb_select_device", out _selectDevicePointer)) throw new RGBDeviceException("Failed to load wooting function 'wooting_usb_select_device'"); + } - #region SDK-METHODS + private static IEnumerable GetPossibleLibraryPaths() + { + IEnumerable possibleLibraryPaths; - #region Pointers + if (OperatingSystem.IsWindows()) + possibleLibraryPaths = Environment.Is64BitProcess ? WootingDeviceProvider.PossibleX64NativePaths : WootingDeviceProvider.PossibleX86NativePaths; + else if (OperatingSystem.IsLinux()) + possibleLibraryPaths = Environment.Is64BitProcess ? WootingDeviceProvider.PossibleX64NativePathsLinux : WootingDeviceProvider.PossibleX86NativePathsLinux; + else + possibleLibraryPaths = Enumerable.Empty(); - private static GetDeviceInfoPointer _getDeviceInfoPointer; - private static KeyboardConnectedPointer _keyboardConnectedPointer; - private static ResetPointer _resetPointer; - private static ClosePointer _closePointer; - private static ArrayUpdateKeyboardPointer _arrayUpdateKeyboardPointer; - private static ArraySetSinglePointer _arraySetSinglePointer; + return possibleLibraryPaths.Select(Environment.ExpandEnvironmentVariables); + } - #endregion + internal static void UnloadWootingSDK() + { + if (_handle == IntPtr.Zero) return; - #region Delegates + Close(); - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate IntPtr GetDeviceInfoPointer(); + _getDeviceInfoPointer = IntPtr.Zero; + _keyboardConnectedPointer = IntPtr.Zero; + _resetPointer = IntPtr.Zero; + _closePointer = IntPtr.Zero; + _arrayUpdateKeyboardPointer = IntPtr.Zero; + _arraySetSinglePointer = IntPtr.Zero; + _getDeviceCountPointer = IntPtr.Zero; + _selectDevicePointer = IntPtr.Zero; - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool KeyboardConnectedPointer(); + NativeLibrary.Free(_handle); + _handle = IntPtr.Zero; + } - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool ResetPointer(); + #endregion - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool ClosePointer(); + #region SDK-METHODS - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool ArrayUpdateKeyboardPointer(); + #region Pointers - [UnmanagedFunctionPointer(CallingConvention.Cdecl)] - private delegate bool ArraySetSinglePointer(byte row, byte column, byte red, byte green, byte blue); + private static IntPtr _getDeviceInfoPointer; + private static IntPtr _keyboardConnectedPointer; + private static IntPtr _resetPointer; + private static IntPtr _closePointer; + private static IntPtr _arrayUpdateKeyboardPointer; + private static IntPtr _arraySetSinglePointer; + private static IntPtr _getDeviceCountPointer; + private static IntPtr _selectDevicePointer; - #endregion + #endregion - internal static IntPtr GetDeviceInfo() => _getDeviceInfoPointer(); - internal static bool KeyboardConnected() => _keyboardConnectedPointer(); - internal static bool Reset() => _resetPointer(); - internal static bool Close() => _closePointer(); - internal static bool ArrayUpdateKeyboard() => _arrayUpdateKeyboardPointer(); - internal static bool ArraySetSingle(byte row, byte column, byte red, byte green, byte blue) => _arraySetSinglePointer(row, column, red, green, blue); + internal static unsafe IntPtr GetDeviceInfo() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_getDeviceInfoPointer))(); + internal static unsafe bool KeyboardConnected() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_keyboardConnectedPointer))(); + internal static unsafe bool Reset() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_resetPointer))(); + internal static unsafe bool Close() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_closePointer))(); + internal static unsafe bool ArrayUpdateKeyboard() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_arrayUpdateKeyboardPointer))(); + internal static unsafe bool ArraySetSingle(byte row, byte column, byte red, byte green, byte blue) + => ((delegate* unmanaged[Cdecl])ThrowIfZero(_arraySetSinglePointer))(row, column, red, green, blue); + internal static unsafe byte GetDeviceCount() => ((delegate* unmanaged[Cdecl])ThrowIfZero(_getDeviceCountPointer))(); + internal static unsafe void SelectDevice(byte index) => ((delegate* unmanaged[Cdecl])ThrowIfZero(_selectDevicePointer))(index); - #endregion + private static IntPtr ThrowIfZero(IntPtr ptr) + { + if (ptr == IntPtr.Zero) throw new RGBDeviceException("The Wooting-SDK is not initialized."); + return ptr; } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/README.md b/RGB.NET.Devices.Wooting/README.md new file mode 100644 index 00000000..6348b982 --- /dev/null +++ b/RGB.NET.Devices.Wooting/README.md @@ -0,0 +1,24 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Device-Provider-Package for Wooting-Devices. + +## Usage +This provider follows the default pattern and does not require additional setup. + +```csharp +surface.Load(WootingDeviceProvider.Instance); +``` + +# Required SDK +This providers requires native SDK-dlls. +You can get them directly from Wooting at [https://github.com/WootingKb/wooting-rgb-sdk/releases](https://github.com/WootingKb/wooting-rgb-sdk/releases) + +Since the SDK-dlls are native it's important to use the correct architecture you're building your application for. (If in doubt you can always include both.) + +### x64 +`wooting-rgb-sdk.dll` from the x64-zip needs to be distributed as `\x64\wooting-rgb-sdk.dll` + +You can use other, custom paths by adding them to `WootingDeviceProvider.PossibleX64NativePaths`. + +### x86 +`wooting-rgb-sdk.dll` from the x86-zip needs to be distributed as `\x86\wooting-rgb-sdk.dll` + +You can use other, custom paths by adding them to `WootingDeviceProvider.PossibleX86NativePaths`. diff --git a/RGB.NET.Devices.Wooting/RGB.NET.Devices.Wooting.csproj b/RGB.NET.Devices.Wooting/RGB.NET.Devices.Wooting.csproj index 4efa9356..ac158f03 100644 --- a/RGB.NET.Devices.Wooting/RGB.NET.Devices.Wooting.csproj +++ b/RGB.NET.Devices.Wooting/RGB.NET.Devices.Wooting.csproj @@ -1,7 +1,8 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez @@ -14,11 +15,12 @@ RGB.NET.Devices.Wooting Wooting-Device-Implementations of RGB.NET Wooting-Device-Implementations of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,36 +35,29 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg + true $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + - - + + \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs index 9b834525..5ddf6cca 100644 --- a/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs +++ b/RGB.NET.Devices.Wooting/WootingDeviceProvider.cs @@ -1,158 +1,108 @@ using System; using System.Collections.Generic; -using System.Collections.ObjectModel; using System.Runtime.InteropServices; using RGB.NET.Core; -using RGB.NET.Devices.Wooting.Enum; using RGB.NET.Devices.Wooting.Generic; using RGB.NET.Devices.Wooting.Keyboard; using RGB.NET.Devices.Wooting.Native; -namespace RGB.NET.Devices.Wooting +namespace RGB.NET.Devices.Wooting; + +/// +/// +/// Represents a device provider responsible for Wooting devices. +/// +public class WootingDeviceProvider : AbstractRGBDeviceProvider { - /// + #region Properties & Fields + + private static WootingDeviceProvider? _instance; /// - /// Represents a device provider responsible for Wooting devices. + /// Gets the singleton instance. /// - public class WootingDeviceProvider : IRGBDeviceProvider - { - #region Properties & Fields - - private static WootingDeviceProvider _instance; - /// - /// Gets the singleton instance. - /// - public static WootingDeviceProvider Instance => _instance ?? new WootingDeviceProvider(); - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 applications. - /// The first match will be used. - /// - public static List PossibleX86NativePaths { get; } = new List { "x86/wooting-rgb-sdk.dll" }; - - /// - /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 applications. - /// The first match will be used. - /// - public static List PossibleX64NativePaths { get; } = new List { "x64/wooting-rgb-sdk64.dll" }; - - /// - /// - /// Indicates if the SDK is initialized and ready to use. - /// - public bool IsInitialized { get; private set; } - - /// - /// Gets the loaded architecture (x64/x86). - /// - public string LoadedArchitecture => _WootingSDK.LoadedArchitecture; - - /// - /// - /// Gets whether the application has exclusive access to the SDK or not. - /// - public bool HasExclusiveAccess => false; - - /// - public IEnumerable Devices { get; private set; } - - /// - /// The used to trigger the updates for cooler master devices. - /// - public DeviceUpdateTrigger UpdateTrigger { get; private set; } - - #endregion - - #region Constructors - - /// - /// Initializes a new instance of the class. - /// - /// Thrown if this constructor is called even if there is already an instance of this class. - public WootingDeviceProvider() - { - if (_instance != null) - throw new InvalidOperationException($"There can be only one instance of type {nameof(WootingDeviceProvider)}"); - _instance = this; + public static WootingDeviceProvider Instance => _instance ?? new WootingDeviceProvider(); - UpdateTrigger = new DeviceUpdateTrigger(); - } + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 windows applications. + /// The first match will be used. + /// + public static List PossibleX86NativePaths { get; } = new() { "x86/wooting-rgb-sdk.dll" }; - #endregion + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x86 linux applications. + /// The first match will be used. + /// + public static List PossibleX86NativePathsLinux { get; } = new() { "x86/wooting-rgb-sdk.so" }; - #region Methods + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 windows applications. + /// The first match will be used. + /// + public static List PossibleX64NativePaths { get; } = new() { "x64/wooting-rgb-sdk64.dll" }; - /// - /// Thrown if the SDK failed to initialize - public bool Initialize(RGBDeviceType loadFilter = RGBDeviceType.All, bool exclusiveAccessIfPossible = false, - bool throwExceptions = false) - { - IsInitialized = false; + /// + /// Gets a modifiable list of paths used to find the native SDK-dlls for x64 linux applications. + /// The first match will be used. + /// + public static List PossibleX64NativePathsLinux { get; } = new() { "x64/wooting-rgb-sdk64.so" }; - try - { - UpdateTrigger?.Stop(); + #endregion - _WootingSDK.Reload(); + #region Constructors - IList devices = new List(); - if (_WootingSDK.KeyboardConnected()) - { - _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo)); - IWootingRGBDevice device; - // TODO: Find an accurate way to determine physical and logical layouts - if (nativeDeviceInfo.Model == "Wooting two") - { - device = new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingTwo, - WootingPhysicalKeyboardLayout.US, - CultureHelper.GetCurrentCulture())); - } - else if (nativeDeviceInfo.Model == "Wooting one") - { - device = new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(WootingDevicesIndexes.WootingOne, - WootingPhysicalKeyboardLayout.US, - CultureHelper.GetCurrentCulture())); - } - else - { - throw new RGBDeviceException("No supported Wooting keyboard connected"); - } - - device.Initialize(UpdateTrigger); - devices.Add(device); - } + /// + /// Initializes a new instance of the class. + /// + /// Thrown if this constructor is called even if there is already an instance of this class. + public WootingDeviceProvider() + { + if (_instance != null) throw new InvalidOperationException($"There can be only one instance of type {nameof(WootingDeviceProvider)}"); + _instance = this; + } - UpdateTrigger?.Start(); + #endregion - Devices = new ReadOnlyCollection(devices); - IsInitialized = true; - } - catch - { - if (throwExceptions) throw; - return false; - } + #region Methods - return true; + /// + protected override void InitializeSDK() + { + lock (_WootingSDK.SdkLock) + { + _WootingSDK.Reload(); } + } - /// - public void ResetDevices() - { } - - /// - public void Dispose() + /// + protected override IEnumerable LoadDevices() + { + lock (_WootingSDK.SdkLock) { - try { UpdateTrigger?.Dispose(); } - catch { /* at least we tried */ } + if (_WootingSDK.KeyboardConnected()) + { + for (byte i = 0; i < _WootingSDK.GetDeviceCount(); i++) + { + WootingUpdateQueue updateQueue = new(GetUpdateTrigger(), i); + _WootingSDK.SelectDevice(i); + _WootingDeviceInfo nativeDeviceInfo = (_WootingDeviceInfo)Marshal.PtrToStructure(_WootingSDK.GetDeviceInfo(), typeof(_WootingDeviceInfo))!; - try { _WootingSDK.Close(); } - catch { /* Unlucky.. */ } + yield return new WootingKeyboardRGBDevice(new WootingKeyboardRGBDeviceInfo(nativeDeviceInfo, i), updateQueue); + } + } + } + } + /// + public override void Dispose() + { + base.Dispose(); + + lock (_WootingSDK.SdkLock) + { try { _WootingSDK.UnloadWootingSDK(); } catch { /* at least we tried */ } } - - #endregion } -} + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs b/RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs deleted file mode 100644 index 5daf314e..00000000 --- a/RGB.NET.Devices.Wooting/WootingDeviceProviderLoader.cs +++ /dev/null @@ -1,24 +0,0 @@ -using RGB.NET.Core; - -namespace RGB.NET.Devices.Wooting -{ - /// - /// Represents a device provider loaded used to dynamically load Wooting devices into an application. - /// - public class WootingDeviceProviderLoader : IRGBDeviceProviderLoader - { - #region Properties & Fields - - /// - public bool RequiresInitialization => false; - - #endregion - - #region Methods - - /// - public IRGBDeviceProvider GetDeviceProvider() => WootingDeviceProvider.Instance; - - #endregion - } -} diff --git a/RGB.NET.Groups/Extensions/LedGroupExtension.cs b/RGB.NET.Groups/Extensions/LedGroupExtension.cs deleted file mode 100644 index cd09393b..00000000 --- a/RGB.NET.Groups/Extensions/LedGroupExtension.cs +++ /dev/null @@ -1,58 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedMember.Global - -using RGB.NET.Core; - -namespace RGB.NET.Groups -{ - /// - /// Offers some extensions and helper-methods for related things. - /// - public static class LedGroupExtension - { - /// - /// Converts the given to a . - /// - /// The to convert. - /// The converted . - public static ListLedGroup ToListLedGroup(this ILedGroup ledGroup) - { - // ReSharper disable once InvertIf - if (!(ledGroup is ListLedGroup listLedGroup)) - { - bool wasAttached = ledGroup.Detach(); - listLedGroup = new ListLedGroup(wasAttached, ledGroup.GetLeds()) { Brush = ledGroup.Brush }; - } - return listLedGroup; - } - - /// - /// Returns a new which contains all from the given excluding the specified ones. - /// - /// The base . - /// The to exclude. - /// The new . - public static ListLedGroup Exclude(this ILedGroup ledGroup, params Led[] ledIds) - { - ListLedGroup listLedGroup = ledGroup.ToListLedGroup(); - foreach (Led led in ledIds) - listLedGroup.RemoveLed(led); - return listLedGroup; - } - - // ReSharper disable once UnusedMethodReturnValue.Global - /// - /// Attaches the given to the . - /// - /// The to attach. - /// true if the could be attached; otherwise, false. - public static bool Attach(this ILedGroup ledGroup) => RGBSurface.Instance.AttachLedGroup(ledGroup); - - /// - /// Detaches the given from the . - /// - /// The to attach. - /// true if the could be detached; otherwise, false. - public static bool Detach(this ILedGroup ledGroup) => RGBSurface.Instance.DetachLedGroup(ledGroup); - } -} diff --git a/RGB.NET.Groups/Groups/ListLedGroup.cs b/RGB.NET.Groups/Groups/ListLedGroup.cs deleted file mode 100644 index eb833d84..00000000 --- a/RGB.NET.Groups/Groups/ListLedGroup.cs +++ /dev/null @@ -1,157 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable UnusedMember.Global - -using System.Collections.Generic; -using RGB.NET.Core; - -namespace RGB.NET.Groups -{ - /// - /// - /// Represents a ledgroup containing arbitrary . - /// - public class ListLedGroup : AbstractLedGroup - { - #region Properties & Fields - - /// - /// Gets the list containing the of this . - /// - protected IList GroupLeds { get; } = new List(); - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// Specifies whether this should be automatically attached or not. - public ListLedGroup(bool autoAttach = true) - : base(autoAttach) - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The initial of this . - public ListLedGroup(params Led[] leds) - : this(true, leds) - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The initial of this . - public ListLedGroup(IEnumerable leds) - : this(true, leds) - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// Specifies whether this should be automatically attached or not. - /// The initial of this . - public ListLedGroup(bool autoAttach, IEnumerable leds) - : base(autoAttach) - { - AddLeds(leds); - } - - /// - /// - /// Initializes a new instance of the class. - /// - /// Specifies whether this should be automatically attached or not. - /// The initial of this . - public ListLedGroup(bool autoAttach, params Led[] leds) - : base(autoAttach) - { - AddLeds(leds); - } - - #endregion - - #region Methods - - /// - /// Adds the given LED(s) to this . - /// - /// The LED(s) to add. - public void AddLed(params Led[] leds) => AddLeds(leds); - - /// - /// Adds the given to this . - /// - /// The to add. - public void AddLeds(IEnumerable leds) - { - if (leds == null) return; - - lock (GroupLeds) - foreach (Led led in leds) - if ((led != null) && !ContainsLed(led)) - GroupLeds.Add(led); - } - - /// - /// Removes the given LED(s) from this . - /// - /// The LED(s) to remove. - public void RemoveLed(params Led[] leds) => RemoveLeds(leds); - - /// - /// Removes the given from this . - /// - /// The to remove. - public void RemoveLeds(IEnumerable leds) - { - if (leds == null) return; - - lock (GroupLeds) - foreach (Led led in leds) - if (led != null) - GroupLeds.Remove(led); - } - - /// - /// Checks if a given LED is contained by this ledgroup. - /// - /// The LED which should be checked. - /// true if the LED is contained by this ledgroup; otherwise, false. - public bool ContainsLed(Led led) - { - lock (GroupLeds) - return (led != null) && GroupLeds.Contains(led); - } - - /// - /// Merges the from the given ledgroup in this ledgroup. - /// - /// The ledgroup to merge. - public void MergeLeds(ILedGroup groupToMerge) - { - lock (GroupLeds) - foreach (Led led in groupToMerge.GetLeds()) - if (!GroupLeds.Contains(led)) - GroupLeds.Add(led); - } - - /// - /// - /// Gets a list containing the from this group. - /// - /// The list containing the . - public override IList GetLeds() - { - lock (GroupLeds) - return new List(GroupLeds); - } - - #endregion - } -} diff --git a/RGB.NET.Groups/Groups/RectangleLedGroup.cs b/RGB.NET.Groups/Groups/RectangleLedGroup.cs deleted file mode 100644 index 90bb88c5..00000000 --- a/RGB.NET.Groups/Groups/RectangleLedGroup.cs +++ /dev/null @@ -1,114 +0,0 @@ -// ReSharper disable MemberCanBePrivate.Global -// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global -// ReSharper disable UnusedMember.Global - -using System.Collections.Generic; -using System.Linq; -using RGB.NET.Core; - -namespace RGB.NET.Groups -{ - /// - /// - /// Represents a containing which physically lay inside a . - /// - public class RectangleLedGroup : AbstractLedGroup - { - #region Properties & Fields - - private IList _ledCache; - - private Rectangle _rectangle; - /// - /// Gets or sets the the should be taken from. - /// - public Rectangle Rectangle - { - get => _rectangle; - set - { - if (SetProperty(ref _rectangle, value)) - InvalidateCache(); - } - } - - private double _minOverlayPercentage; - /// - /// Gets or sets the minimal percentage overlay a must have with the to be taken into the . - /// - public double MinOverlayPercentage - { - get => _minOverlayPercentage; - set - { - if (SetProperty(ref _minOverlayPercentage, value)) - InvalidateCache(); - } - } - - #endregion - - #region Constructors - - /// - /// - /// Initializes a new instance of the class. - /// - /// They first to calculate the of this from. - /// They second to calculate the of this from. - /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) - /// (optional) Specifies whether this should be automatically attached or not. (default: true) - public RectangleLedGroup(Led fromLed, Led toLed, double minOverlayPercentage = 0.5, bool autoAttach = true) - : this(new Rectangle(fromLed.LedRectangle, toLed.LedRectangle), minOverlayPercentage, autoAttach) - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// They first point to calculate the of this from. - /// They second point to calculate the of this from. - /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) - /// (optional) Specifies whether this should be automatically attached or not. (default: true) - public RectangleLedGroup(Point fromPoint, Point toPoint, double minOverlayPercentage = 0.5, bool autoAttach = true) - : this(new Rectangle(fromPoint, toPoint), minOverlayPercentage, autoAttach) - { } - - /// - /// - /// Initializes a new instance of the class. - /// - /// The of this . - /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) - /// (optional) Specifies whether this should be automatically attached or not. (default: true) - public RectangleLedGroup(Rectangle rectangle, double minOverlayPercentage = 0.5, bool autoAttach = true) - : base(autoAttach) - { - this.Rectangle = rectangle; - this.MinOverlayPercentage = minOverlayPercentage; - } - - #endregion - - #region Methods - - /// - public override void OnAttach() => RGBSurface.Instance.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged; - - /// - public override void OnDetach() => RGBSurface.Instance.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged; - - private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) => InvalidateCache(); - - /// - /// - /// Gets a list containing all of this . - /// - /// The list containing all of this . - public override IList GetLeds() => _ledCache ??= RGBSurface.Instance.Leds.Where(led => led.AbsoluteLedRectangle.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList(); - - private void InvalidateCache() => _ledCache = null; - - #endregion - } -} diff --git a/RGB.NET.HID/HIDLoader.cs b/RGB.NET.HID/HIDLoader.cs new file mode 100644 index 00000000..b0ecfe7a --- /dev/null +++ b/RGB.NET.HID/HIDLoader.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using HidSharp; +using RGB.NET.Core; + +namespace RGB.NET.HID; + +/// +/// Represents the data used to define a HID-device. +/// +/// The type of the identifier leds are mapped to. +/// The type of the custom data added to the HID-device. +public record HIDDeviceDefinition(int ProductId, RGBDeviceType DeviceType, string Name, LedMapping LedMapping, TData CustomData) where TLed : notnull; + +/// +/// Represents a loaded for HID-devices based on the specified definitions. +/// +/// The type of the identifier leds are mapped to. +/// The type of the custom data added to the HID-device. +public class HIDLoader : IEnumerable> + where TLed : notnull +{ + #region Properties & Fields + + private readonly Dictionary> _deviceDefinitions = new(); + + /// + /// Gets the vendor id used for this loader. + /// + public int VendorId { get; } + + /// + /// Gets or sets the filter used to determine which devices should be loaded. + /// + public RGBDeviceType LoadFilter { get; set; } = RGBDeviceType.All; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The vendor id used for this loader. + public HIDLoader(int vendorId) + { + this.VendorId = vendorId; + } + + #endregion + + #region Methods + + /// + /// Adds a new to this loader. + /// + /// The product id of the HID-device. + /// The type of the device. + /// The name of the device. + /// The mapping of the leds of the device. + /// Some custom data to attach to the device. + public void Add(int productId, RGBDeviceType deviceType, string name, LedMapping ledMapping, TData customData) + => _deviceDefinitions.Add(productId, new HIDDeviceDefinition(productId, deviceType, name, ledMapping, customData)); + + /// + /// Gets a enumerable containing all devices from the definition-list that are connected and match the . + /// + /// The enumerable containing the connected devices. + public IEnumerable<(HIDDeviceDefinition definition, HidDevice device)> GetConnectedDevices() + { + IEnumerable devices = DeviceList.Local.GetHidDevices(VendorId); + foreach (HidDevice device in devices) + { + if (_deviceDefinitions.TryGetValue(device.ProductID, out HIDDeviceDefinition? definition)) + if (LoadFilter.HasFlag(definition.DeviceType)) + yield return (definition, device); + } + } + + /// + /// Gets a enumerable containing all the first device of each group of devices from the definition-list that are connected and match the . + /// The grouping is done by the specified function. + /// + /// The type of the key used to group the devices. + /// The function grouping the devices. + /// The enumerable containing the selected devices. + public IEnumerable<(HIDDeviceDefinition definition, HidDevice device)> GetConnectedDevices(Func, TKey> groupBy) + => GetConnectedDevices().GroupBy(x => groupBy(x.definition)) + .Select(group => group.First()); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + /// + public IEnumerator> GetEnumerator() => _deviceDefinitions.Values.GetEnumerator(); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.HID/README.md b/RGB.NET.HID/README.md new file mode 100644 index 00000000..b3a73548 --- /dev/null +++ b/RGB.NET.HID/README.md @@ -0,0 +1,3 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) HID-Package. + +Abstraction for device-providers that require HID-functionality. \ No newline at end of file diff --git a/RGB.NET.HID/RGB.NET.HID.csproj b/RGB.NET.HID/RGB.NET.HID.csproj new file mode 100644 index 00000000..54694389 --- /dev/null +++ b/RGB.NET.HID/RGB.NET.HID.csproj @@ -0,0 +1,66 @@ + + + net7.0;net6.0;net5.0 + latest + enable + + Darth Affe + Wyrez + en-US + en-US + RGB.NET.HID + RGB.NET.HID + RGB.NET.HID + RGB.NET.HID + RGB.NET.HID + HID-Module of RGB.NET + HID-Module of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md + https://github.com/DarthAffe/RGB.NET + LGPL-2.1-only + Github + https://github.com/DarthAffe/RGB.NET + True + + + + 0.0.1 + 0.0.1 + 0.0.1 + + ..\bin\ + true + True + True + portable + snupkg + + + + $(DefineConstants);TRACE;DEBUG + true + false + + + + true + $(NoWarn);CS1591;CS1572;CS1573 + $(DefineConstants);RELEASE + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/RGB.NET.Layout/DeviceLayout.cs b/RGB.NET.Layout/DeviceLayout.cs new file mode 100644 index 00000000..bdddb99b --- /dev/null +++ b/RGB.NET.Layout/DeviceLayout.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Xml; +using System.Xml.Serialization; +using RGB.NET.Core; + +namespace RGB.NET.Layout; + +/// +/// Represents the serializable layout of a . +/// +[Serializable] +[XmlRoot("Device")] +public class DeviceLayout : IDeviceLayout +{ + #region Properties & Fields + + /// + /// Gets or sets the name of the . + /// + [XmlElement("Name")] + public string? Name { get; set; } + + /// + /// Gets or sets the description of the . + /// + [XmlElement("Description")] + public string? Description { get; set; } + + /// + /// Gets or sets the author of the . + /// + [XmlElement("Author")] + public string? Author { get; set; } + + /// + /// Gets or sets the of the . + /// + [XmlElement("Type")] + public RGBDeviceType Type { get; set; } + + /// + /// Gets or sets the vendor of the . + /// + [XmlElement("Vendor")] + public string? Vendor { get; set; } + + /// + /// Gets or sets the model of the . + /// + [XmlElement("Model")] + public string? Model { get; set; } + + /// + /// Gets or sets the of the . + /// + [XmlElement("Shape")] + [DefaultValue(Shape.Rectangle)] + public Shape Shape { get; set; } = Shape.Rectangle; + + /// + /// Gets or sets the width of the . + /// + [XmlElement("Width")] + public float Width { get; set; } + + /// + /// Gets or sets the height of the . + /// + [XmlElement("Height")] + public float Height { get; set; } + + /// + /// Gets or sets the width of one 'unit' used for the calculation of led positions and sizes. + /// + [XmlElement("LedUnitWidth")] + [DefaultValue(19.0)] + public float LedUnitWidth { get; set; } = 19.0f; + + /// + /// Gets or sets the height of one 'unit' used for the calculation of led positions and sizes. + /// + [XmlElement("LedUnitHeight")] + [DefaultValue(19.0)] + public float LedUnitHeight { get; set; } = 19.0f; + + /// + /// Gets or sets the internal list of led layouts. + /// Normally you should use to access this data. + /// + [XmlArray("Leds")] + public List InternalLeds { get; set; } = new(); + + /// + /// Gets or sets a list of representing all the of the . + /// + [XmlIgnore] + public IEnumerable Leds => InternalLeds; + + /// + /// Gets or sets the internal custom data of this layout. + /// Normally you should use to access or set this data. + /// + [XmlElement("CustomData")] + public object? InternalCustomData { get; set; } + + /// + [XmlIgnore] + public object? CustomData { get; set; } + + #endregion + + #region Methods + + /// + /// Creates a new from the specified xml. + /// + /// The path to the xml file. + /// The type of the custom data. + /// The type of the custom data of the leds. + /// The deserialized . + public static DeviceLayout? Load(string path, Type? customDeviceDataType = null, Type? customLedDataType = null) + { + if (!File.Exists(path)) return null; + + try + { + XmlSerializer serializer = new(typeof(DeviceLayout)); + using StreamReader reader = new(path); + + DeviceLayout? layout = serializer.Deserialize(reader) as DeviceLayout; + if (layout != null) + layout.CustomData = layout.GetCustomData(layout.InternalCustomData, customDeviceDataType); + + if (layout?.InternalLeds != null) + { + LedLayout? lastLed = null; + foreach (LedLayout led in layout.InternalLeds) + { + led.CalculateValues(layout, lastLed); + lastLed = led; + + led.CustomData = layout.GetCustomData(led.InternalCustomData, customLedDataType); + } + } + + return layout; + } + catch + { + return null; + } + } + + /// + /// Gets the deserialized custom data. + /// + /// The internal custom data node. + /// The type of the custom data. + /// The deserialized custom data object. + protected virtual object? GetCustomData(object? customData, Type? type) + { + XmlNode? node = (customData as XmlNode) ?? (customData as IEnumerable)?.FirstOrDefault()?.ParentNode; //HACK DarthAffe 16.01.2021: This gives us the CustomData-Node + if ((node == null) || (type == null)) return null; + + using MemoryStream ms = new(); + using StreamWriter writer = new(ms); + + writer.Write(node.OuterXml); + writer.Flush(); + ms.Seek(0, SeekOrigin.Begin); + + return new XmlSerializer(type).Deserialize(ms); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Layout/IDeviceLayout.cs b/RGB.NET.Layout/IDeviceLayout.cs new file mode 100644 index 00000000..d55a7abf --- /dev/null +++ b/RGB.NET.Layout/IDeviceLayout.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using RGB.NET.Core; + +namespace RGB.NET.Layout; + +/// +/// Represents a generic layout of a device. +/// +public interface IDeviceLayout +{ + /// + /// Gets or sets the name of the . + /// + string? Name { get; } + + /// + /// Gets or sets the description of the . + /// + string? Description { get; } + + /// + /// Gets or sets the author of the . + /// + string? Author { get; } + + /// + /// Gets or sets the of the . + /// + RGBDeviceType Type { get; } + + /// + /// Gets or sets the vendor of the . + /// + string? Vendor { get; } + + /// + /// Gets or sets the model of the . + /// + string? Model { get; } + + /// + /// Gets or sets the of the . + /// + Shape Shape { get; } + + /// + /// Gets or sets the width of the . + /// + float Width { get; } + + /// + /// Gets or sets the height of the . + /// + float Height { get; } + + /// + /// Gets or sets a list of representing all the of the . + /// + IEnumerable Leds { get; } + + /// + /// Gets the the custom data associated with the device. + /// + object? CustomData { get; } +} \ No newline at end of file diff --git a/RGB.NET.Layout/ILedLayout.cs b/RGB.NET.Layout/ILedLayout.cs new file mode 100644 index 00000000..65c1ab79 --- /dev/null +++ b/RGB.NET.Layout/ILedLayout.cs @@ -0,0 +1,49 @@ +using RGB.NET.Core; + +namespace RGB.NET.Layout; + +/// +/// Represents a generic layour of a LED. +/// +public interface ILedLayout +{ + /// + /// Gets or sets the Id of the . + /// + string? Id { get; } + + /// + /// Gets or sets the of the . + /// + Shape Shape { get; } + + /// + /// Gets or sets the vecor-data representing a custom-shape of the . + /// + string? ShapeData { get; } + + /// + /// Gets the x-position of the . + /// + float X { get; } + + /// + /// Gets the y-position of the . + /// + float Y { get; } + + /// + /// Gets the width of the . + /// + float Width { get; } + + /// + /// Gets the height of the . + /// + float Height { get; } + + /// + /// Gets the the custom data associated with the LED. + /// + object? CustomData { get; } +} \ No newline at end of file diff --git a/RGB.NET.Layout/LayoutExtension.cs b/RGB.NET.Layout/LayoutExtension.cs new file mode 100644 index 00000000..a6666372 --- /dev/null +++ b/RGB.NET.Layout/LayoutExtension.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using RGB.NET.Core; + +namespace RGB.NET.Layout; + +/// +/// Offers some extensions and helper-methods for layout related things. +/// +public static class LayoutExtension +{ + /// + /// Applies the specified layout to the specified device. + /// + /// The layout to apply. + /// The device to apply the layout to. + /// Indicates if LEDs that are in the layout but not on the device should be created. + /// Indicates if LEDS that are on the device but not in the layout should be removed. + public static void ApplyTo(this IDeviceLayout layout, IRGBDevice device, bool createMissingLeds = false, bool removeExcessiveLeds = false) + { + device.Size = new Size(layout.Width, layout.Height); + device.DeviceInfo.LayoutMetadata = layout.CustomData; + + HashSet ledIds = new(); + foreach (ILedLayout layoutLed in layout.Leds) + { + if (Enum.TryParse(layoutLed.Id, true, out LedId ledId)) + { + ledIds.Add(ledId); + + Led? led = device[ledId]; + if ((led == null) && createMissingLeds) + led = device.AddLed(ledId, new Point(), new Size()); + + if (led != null) + { + led.Location = new Point(layoutLed.X, layoutLed.Y); + led.Size = new Size(layoutLed.Width, layoutLed.Height); + led.Shape = layoutLed.Shape; + led.ShapeData = layoutLed.ShapeData; + led.LayoutMetadata = layoutLed.CustomData; + } + } + } + + if (removeExcessiveLeds) + { + List ledsToRemove = device.Select(led => led.Id).Where(id => !ledIds.Contains(id)).ToList(); + foreach (LedId led in ledsToRemove) + device.RemoveLed(led); + } + } +} \ No newline at end of file diff --git a/RGB.NET.Layout/LedLayout.cs b/RGB.NET.Layout/LedLayout.cs new file mode 100644 index 00000000..57fdd361 --- /dev/null +++ b/RGB.NET.Layout/LedLayout.cs @@ -0,0 +1,207 @@ +using System; +using System.ComponentModel; +using System.Globalization; +using System.Xml.Serialization; +using RGB.NET.Core; + +namespace RGB.NET.Layout; + +/// +/// Represents the serializable layout of a . +/// +[Serializable] +[XmlType("Led")] +public class LedLayout : ILedLayout +{ + #region Properties & Fields + + /// + /// Gets or sets the Id of the . + /// + [XmlAttribute("Id")] + public string? Id { get; set; } + + /// + /// Gets or sets the descriptive of the . + /// This property is for XML-serialization only and should not be directly accessed. + /// + [XmlElement("Shape")] + [DefaultValue("Rectangle")] + public string DescriptiveShape { get; set; } = "Rectangle"; + + /// + /// Gets or sets the descriptive x-position of the . + /// This property is for XML-serialization only and should not be directly accessed. + /// + [XmlElement("X")] + [DefaultValue("+")] + public string DescriptiveX { get; set; } = "+"; + + /// + /// Gets or sets the descriptive y-position of the . + /// This property is for XML-serialization only and should not be directly accessed. + /// + [XmlElement("Y")] + [DefaultValue("=")] + public string DescriptiveY { get; set; } = "="; + + /// + /// Gets or sets the descriptive width of the . + /// This property is for XML-serialization only and should not be directly accessed. + /// + [XmlElement("Width")] + [DefaultValue("1.0")] + public string DescriptiveWidth { get; set; } = "1.0"; + + /// + /// Gets or sets the descriptive height of the . + /// This property is for XML-serialization only and should not be directly accessed. + /// + [XmlElement("Height")] + [DefaultValue("1.0")] + public string DescriptiveHeight { get; set; } = "1.0"; + + /// + /// Gets or sets the internal custom data of this layout. + /// Normally you should use to access or set this data. + /// + [XmlElement("CustomData")] + public object? InternalCustomData { get; set; } + + /// + [XmlIgnore] + public object? CustomData { get; set; } + + /// + /// Gets or sets the of the . + /// + [XmlIgnore] + public Shape Shape { get; set; } + + /// + /// Gets or sets the vecor-data representing a custom-shape of the . + /// + [XmlIgnore] + public string? ShapeData { get; set; } + + /// + /// Gets the x-position of the . + /// + [XmlIgnore] + public float X { get; private set; } + + /// + /// Gets the y-position of the . + /// + [XmlIgnore] + public float Y { get; private set; } + + /// + /// Gets the width of the . + /// + [XmlIgnore] + public float Width { get; private set; } + + /// + /// Gets the height of the . + /// + [XmlIgnore] + public float Height { get; private set; } + + #endregion + + #region Methods + + /// + /// Calculates the position- and size-data from the respective descriptive values. + /// + /// The this belongs to. + /// The previously calculated. + public virtual void CalculateValues(DeviceLayout device, LedLayout? lastLed) + { + if (!Enum.TryParse(DescriptiveShape, true, out Shape shape)) + { + shape = Shape.Custom; + ShapeData = DescriptiveShape; + } + Shape = shape; + + Width = GetSizeValue(DescriptiveWidth, device.LedUnitWidth); + Height = GetSizeValue(DescriptiveHeight, device.LedUnitHeight); + + X = GetLocationValue(DescriptiveX, lastLed?.X ?? 0, Width, lastLed?.Width ?? 0); + Y = GetLocationValue(DescriptiveY, lastLed?.Y ?? 0, Height, lastLed?.Height ?? 0); + } + + /// + /// Gets the calculated location-value from the internal representation. + /// + /// The value provided by the layout. + /// The location of the last calculated LED. + /// The size of the current LED. + /// The size of the last loaded LED. + /// The location-value of the LED. + protected virtual float GetLocationValue(string value, float lastValue, float currentSize, float lastSize) + { + try + { + if (string.IsNullOrWhiteSpace(value)) return 0; + + value = value.Replace(" ", string.Empty); + + if (string.Equals(value, "=", StringComparison.Ordinal)) + return lastValue; + + if (string.Equals(value, "+", StringComparison.Ordinal)) + return lastValue + lastSize; + + if (value.StartsWith("+", StringComparison.Ordinal)) + return lastValue + lastSize + float.Parse(value[1..], CultureInfo.InvariantCulture); + + if (string.Equals(value, "-", StringComparison.Ordinal)) + return lastValue - currentSize; + + if (value.StartsWith("-", StringComparison.Ordinal)) + return lastValue - currentSize - float.Parse(value[1..], CultureInfo.InvariantCulture); + + if (string.Equals(value, "~", StringComparison.Ordinal)) + return (lastValue + lastSize) - currentSize; + + if (value.StartsWith("~", StringComparison.Ordinal)) + return (lastValue + lastSize) - currentSize - float.Parse(value[1..], CultureInfo.InvariantCulture); + + return float.Parse(value, CultureInfo.InvariantCulture); + } + catch + { + return 0; + } + } + + /// + /// Gets the calculated size-value from the internal representation. + /// + /// The value provided by the layout. + /// The absolute size of one 'unit'. + /// The size-value of the LED. + protected virtual float GetSizeValue(string value, float unitSize) + { + try + { + if (string.IsNullOrWhiteSpace(value)) return 0; + + value = value.Replace(" ", string.Empty); + + if (value.EndsWith("mm", StringComparison.OrdinalIgnoreCase)) + return float.Parse(value[..^2], CultureInfo.InvariantCulture); + + return unitSize * float.Parse(value, CultureInfo.InvariantCulture); + } + catch + { + return 0; + } + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Layout/README.md b/RGB.NET.Layout/README.md new file mode 100644 index 00000000..91203578 --- /dev/null +++ b/RGB.NET.Layout/README.md @@ -0,0 +1,3 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Layout-Package. + +Required to use the RGB.NET-Layout-System. \ No newline at end of file diff --git a/RGB.NET.Layout/RGB.NET.Layout.csproj b/RGB.NET.Layout/RGB.NET.Layout.csproj new file mode 100644 index 00000000..f6330ede --- /dev/null +++ b/RGB.NET.Layout/RGB.NET.Layout.csproj @@ -0,0 +1,62 @@ + + + net7.0;net6.0;net5.0 + latest + enable + + Darth Affe + Wyrez + en-US + en-US + RGB.NET.Layout + RGB.NET.Layout + RGB.NET.Layout + RGB.NET.Layout + RGB.NET.Layout + Layout-Module of RGB.NET + Layout-Module of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md + https://github.com/DarthAffe/RGB.NET + LGPL-2.1-only + Github + https://github.com/DarthAffe/RGB.NET + True + + + + 0.0.1 + 0.0.1 + 0.0.1 + + ..\bin\ + true + True + True + portable + snupkg + + + + $(DefineConstants);TRACE;DEBUG + true + false + + + + true + $(NoWarn);CS1591;CS1572;CS1573 + $(DefineConstants);RELEASE + + + + + + + + + + + \ No newline at end of file diff --git a/RGB.NET.Presets/Decorators/FlashDecorator.cs b/RGB.NET.Presets/Decorators/FlashDecorator.cs new file mode 100644 index 00000000..64794b5c --- /dev/null +++ b/RGB.NET.Presets/Decorators/FlashDecorator.cs @@ -0,0 +1,176 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +// ReSharper disable UnusedMember.Global + +using System; +using RGB.NET.Core; + +namespace RGB.NET.Presets.Decorators; + +/// +/// +/// +/// Represents a decorator which allows to flash a brush by modifying his opacity. +/// +public class FlashDecorator : AbstractUpdateAwareDecorator, IBrushDecorator +{ + #region Properties & Fields + + /// + /// Gets or sets the attack-time (in seconds) of the decorator. (default: 0.2)
+ /// This is close to a synthesizer envelope. (See as reference) + ///
+ public float Attack { get; set; } = 0.2f; + + /// + /// Gets or sets the decay-time (in seconds) of the decorator. (default: 0)
+ /// This is close to a synthesizer envelope. (See as reference) + ///
+ public float Decay { get; set; } = 0; + + /// + /// Gets or sets the sustain-time (in seconds) of the decorator. (default: 0.3)
+ /// This is close to a synthesizer envelope. (See as reference)
+ /// Note that this value for naming reasons represents the time NOT the level. + ///
+ public float Sustain { get; set; } = 0.3f; + + /// + /// Gets or sets the release-time (in seconds) of the decorator. (default: 0.2)
+ /// This is close to a synthesizer envelope. (See as reference) + ///
+ public float Release { get; set; } = 0.2f; + + /// + /// Gets or sets the level to which the oppacity (percentage) should raise in the attack-cycle. (default: 1); + /// + public float AttackValue { get; set; } = 1; + + /// + /// Gets or sets the level at which the oppacity (percentage) should stay in the sustain-cycle. (default: 1); + /// + public float SustainValue { get; set; } = 1; + + /// + /// Gets or sets the level at which the oppacity (percentage) should stay in the pause-cycle. (default: 0); + /// + public float PauseValue { get; set; } = 0; + + /// + /// Gets or sets the interval (in seconds) in which the decorator should repeat (if repetition is enabled). (default: 1) + /// + public float Interval { get; set; } = 1; + + /// + /// Gets or sets the amount of repetitions the decorator should do until it's finished. Zero means infinite. (default: 0) + /// + public int Repetitions { get; set; } = 0; + + private ADSRPhase _currentPhase; + private float _currentPhaseValue; + private int _repetitionCount; + + private float _currentValue; + + #endregion + + #region Constructors + + /// + /// Creates a new from the specified xml. + /// + /// The surface this decorator belongs to. + /// A value indicating if the decorator should be updated if it is disabled. + public FlashDecorator(RGBSurface surface, bool updateIfDisabled = false) + : base(surface, updateIfDisabled) + { } + + #endregion + + #region Methods + + /// + public void ManipulateColor(in Rectangle rectangle, in RenderTarget renderTarget, ref Color color) => color = color.SetA(_currentValue); + + /// + protected override void Update(double deltaTime) + { + _currentPhaseValue -= (float)deltaTime; + + // Using ifs instead of a switch allows to skip phases with time 0. + // ReSharper disable InvertIf + + if (_currentPhase == ADSRPhase.Attack) + if (_currentPhaseValue > 0) + _currentValue = PauseValue + (MathF.Min(1, (Attack - _currentPhaseValue) / Attack) * (AttackValue - PauseValue)); + else + { + _currentPhaseValue = Decay; + _currentPhase = ADSRPhase.Decay; + } + + if (_currentPhase == ADSRPhase.Decay) + if (_currentPhaseValue > 0) + _currentValue = SustainValue + (MathF.Min(1, _currentPhaseValue / Decay) * (AttackValue - SustainValue)); + else + { + _currentPhaseValue = Sustain; + _currentPhase = ADSRPhase.Sustain; + } + + if (_currentPhase == ADSRPhase.Sustain) + if (_currentPhaseValue > 0) + _currentValue = SustainValue; + else + { + _currentPhaseValue = Release; + _currentPhase = ADSRPhase.Release; + } + + if (_currentPhase == ADSRPhase.Release) + if (_currentPhaseValue > 0) + _currentValue = PauseValue + (MathF.Min(1, _currentPhaseValue / Release) * (SustainValue - PauseValue)); + else + { + _currentPhaseValue = Interval; + _currentPhase = ADSRPhase.Pause; + } + + if (_currentPhase == ADSRPhase.Pause) + if (_currentPhaseValue > 0) + _currentValue = PauseValue; + else + { + if ((++_repetitionCount >= Repetitions) && (Repetitions > 0)) + Detach(); + _currentPhaseValue = Attack; + _currentPhase = ADSRPhase.Attack; + } + + // ReSharper restore InvertIf + } + + /// + /// + public override void OnAttached(IDecoratable decoratable) + { + base.OnAttached(decoratable); + + _currentPhase = ADSRPhase.Attack; + _currentPhaseValue = Attack; + _repetitionCount = 0; + _currentValue = 0; + } + + #endregion + + // ReSharper disable once InconsistentNaming + private enum ADSRPhase + { + Attack, + Decay, + Sustain, + Release, + Pause + } +} \ No newline at end of file diff --git a/RGB.NET.Presets/Decorators/IGradientDecorator.cs b/RGB.NET.Presets/Decorators/IGradientDecorator.cs new file mode 100644 index 00000000..9373e4ea --- /dev/null +++ b/RGB.NET.Presets/Decorators/IGradientDecorator.cs @@ -0,0 +1,10 @@ +using RGB.NET.Core; + +namespace RGB.NET.Presets.Decorators; + +/// +/// +/// Represents a basic decorator decorating a . +/// +public interface IGradientDecorator : IDecorator +{ } \ No newline at end of file diff --git a/RGB.NET.Presets/Decorators/MoveGradientDecorator.cs b/RGB.NET.Presets/Decorators/MoveGradientDecorator.cs new file mode 100644 index 00000000..9a915904 --- /dev/null +++ b/RGB.NET.Presets/Decorators/MoveGradientDecorator.cs @@ -0,0 +1,73 @@ +using RGB.NET.Core; +using RGB.NET.Presets.Textures.Gradients; + +namespace RGB.NET.Presets.Decorators; + +/// +/// +/// +/// Represents a decorator which allows to move an by modifying his offset. +/// +public class MoveGradientDecorator : AbstractUpdateAwareDecorator, IGradientDecorator +{ + #region Properties & Fields + // ReSharper disable AutoPropertyCanBeMadeGetOnly.Global + // ReSharper disable MemberCanBePrivate.Global + + /// + /// Gets or sets the direction the is moved. + /// True leads to an offset-increment (normaly moving to the right), false to an offset-decrement (normaly moving to the left). + /// + public bool Direction { get; set; } + + /// + /// Gets or sets the speed of the movement in units per second. + /// The meaning of units differs for the different , but 360 units will always be one complete cycle: + /// : 360 unit = 1 offset. + /// : 1 unit = 1 degree. + /// + public float Speed { get; set; } + + // ReSharper restore MemberCanBePrivate.Global + // ReSharper restore AutoPropertyCanBeMadeGetOnly.Global + #endregion + + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// The surface this decorator belongs to. + /// The speed of the movement in units per second. + /// The meaning of units differs for the different but 360 units will always be one complete cycle: + /// : 360 unit = 1 offset. + /// : 1 unit = 1 degree. + /// The direction the is moved. + /// True leads to an offset-increment (normaly moving to the right), false to an offset-decrement (normaly moving to the left). + public MoveGradientDecorator(RGBSurface surface, float speed = 180.0f, bool direction = true) + : base(surface) + { + this.Speed = speed; + this.Direction = direction; + } + + #endregion + + #region Methods + + /// + protected override void Update(double deltaTime) + { + float movement = Speed * (float)deltaTime; + + if (!Direction) + movement = -movement; + + foreach (IDecoratable decoratedObject in DecoratedObjects) + if (decoratedObject is IGradient gradient) + gradient.Move(movement); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Groups/RectangleLedGroup.cs b/RGB.NET.Presets/Groups/RectangleLedGroup.cs new file mode 100644 index 00000000..9547476f --- /dev/null +++ b/RGB.NET.Presets/Groups/RectangleLedGroup.cs @@ -0,0 +1,122 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +// ReSharper disable UnusedMember.Global + +using System.Collections.Generic; +using System.Linq; +using RGB.NET.Core; + +namespace RGB.NET.Presets.Groups; + +/// +/// +/// Represents a containing which physically lay inside a . +/// +public class RectangleLedGroup : AbstractLedGroup +{ + #region Properties & Fields + + private IList? _ledCache; + + private Rectangle _rectangle; + /// + /// Gets or sets the the should be taken from. + /// + public Rectangle Rectangle + { + get => _rectangle; + set + { + if (SetProperty(ref _rectangle, value)) + InvalidateCache(); + } + } + + private double _minOverlayPercentage; + /// + /// Gets or sets the minimal percentage overlay a must have with the to be taken into the . + /// + public double MinOverlayPercentage + { + get => _minOverlayPercentage; + set + { + if (SetProperty(ref _minOverlayPercentage, value)) + InvalidateCache(); + } + } + + #endregion + + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + /// Specifies the surface to attach this group to or null if the group should not be attached on creation. + /// They first to calculate the of this from. + /// They second to calculate the of this from. + /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) + public RectangleLedGroup(RGBSurface? surface, Led fromLed, Led toLed, double minOverlayPercentage = 0.5) + : this(surface, new Rectangle(fromLed.Boundary, toLed.Boundary), minOverlayPercentage) + { } + + /// + /// + /// Initializes a new instance of the class. + /// + /// Specifies the surface to attach this group to or null if the group should not be attached on creation. + /// They first point to calculate the of this from. + /// They second point to calculate the of this from. + /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) + public RectangleLedGroup(RGBSurface? surface, Point fromPoint, Point toPoint, double minOverlayPercentage = 0.5) + : this(surface, new Rectangle(fromPoint, toPoint), minOverlayPercentage) + { } + + /// + /// + /// Initializes a new instance of the class. + /// + /// Specifies the surface to attach this group to or null if the group should not be attached on creation. + /// The of this . + /// (optional) The minimal percentage overlay a must have with the to be taken into the . (default: 0.5) + public RectangleLedGroup(RGBSurface? surface, Rectangle rectangle, double minOverlayPercentage = 0.5) + : base(surface) + { + this.Rectangle = rectangle; + this.MinOverlayPercentage = minOverlayPercentage; + } + + #endregion + + #region Methods + + /// + public override void OnAttach() + { + base.OnAttach(); + Surface!.SurfaceLayoutChanged += RGBSurfaceOnSurfaceLayoutChanged; + } + + /// + public override void OnDetach() + { + Surface!.SurfaceLayoutChanged -= RGBSurfaceOnSurfaceLayoutChanged; + + base.OnDetach(); + } + + private void RGBSurfaceOnSurfaceLayoutChanged(SurfaceLayoutChangedEventArgs args) => InvalidateCache(); + + /// + /// + /// Gets a list containing all of this . + /// + /// The list containing all of this . + protected override IEnumerable GetLeds() => _ledCache ??= (Surface?.Leds.Where(led => led.AbsoluteBoundary.CalculateIntersectPercentage(Rectangle) >= MinOverlayPercentage).ToList() ?? new List()); + + private void InvalidateCache() => _ledCache = null; + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Helper/GradientHelper.cs b/RGB.NET.Presets/Helper/GradientHelper.cs new file mode 100644 index 00000000..2f6d68d9 --- /dev/null +++ b/RGB.NET.Presets/Helper/GradientHelper.cs @@ -0,0 +1,85 @@ +// ReSharper disable MemberCanBePrivate.Global + +using System; +using RGB.NET.Core; + +namespace RGB.NET.Presets.Helper; + +/// +/// Offers some extensions and helper-methods for gradient related things. +/// +public static class GradientHelper +{ + #region Methods + + // Based on https://web.archive.org/web/20170125201230/https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/ + /// + /// Calculates the offset of an specified on an gradient. + /// + /// The start of the gradient. + /// The end of the gradient. + /// The on the gradient to which the offset is calculated. + /// The offset of the on the gradient. + public static float CalculateLinearGradientOffset(in Point startPoint, in Point endPoint, in Point point) + { + Point intersectingPoint; + if (startPoint.Y.EqualsInTolerance(endPoint.Y)) // Horizontal case + intersectingPoint = new Point(point.X, startPoint.Y); + + else if (startPoint.X.EqualsInTolerance(endPoint.X)) // Vertical case + intersectingPoint = new Point(startPoint.X, point.Y); + + else // Diagonal case + { + float slope = (endPoint.Y - startPoint.Y) / (endPoint.X - startPoint.X); + float orthogonalSlope = -1 / slope; + + float startYIntercept = startPoint.Y - (slope * startPoint.X); + float pointYIntercept = point.Y - (orthogonalSlope * point.X); + + float intersectingPointX = (pointYIntercept - startYIntercept) / (slope - orthogonalSlope); + float intersectingPointY = (slope * intersectingPointX) + startYIntercept; + intersectingPoint = new Point(intersectingPointX, intersectingPointY); + } + + // Calculate distances relative to the vector start + float intersectDistance = CalculateDistance(intersectingPoint, startPoint, endPoint); + float gradientLength = CalculateDistance(endPoint, startPoint, endPoint); + + return intersectDistance / gradientLength; + } + + // Based on https://web.archive.org/web/20170125201230/https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/ + /// + /// Returns the signed magnitude of a on a vector. + /// + /// The on the vector of which the magnitude should be calculated. + /// The origin of the vector. + /// The direction of the vector. + /// The signed magnitude of a on a vector. + public static float CalculateDistance(in Point point, in Point origin, in Point direction) + { + float distance = CalculateDistance(point, origin); + + return (((point.Y < origin.Y) && (direction.Y > origin.Y)) + || ((point.Y > origin.Y) && (direction.Y < origin.Y)) + || ((point.Y.EqualsInTolerance(origin.Y)) && (point.X < origin.X) && (direction.X > origin.X)) + || ((point.Y.EqualsInTolerance(origin.Y)) && (point.X > origin.X) && (direction.X < origin.X))) + ? -distance : distance; + } + + /// + /// Calculated the distance between two . + /// + /// The first . + /// The second . + /// The distance between the two . + public static float CalculateDistance(in Point point1, in Point point2) + { + float x = point1.X - point2.X; + float y = point1.Y - point2.Y; + return MathF.Sqrt((y * y) + (x * x)); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/README.md b/RGB.NET.Presets/README.md new file mode 100644 index 00000000..62228d56 --- /dev/null +++ b/RGB.NET.Presets/README.md @@ -0,0 +1,3 @@ +[RGB.NET](https://github.com/DarthAffe/RGB.NET) Presets-Package. + +Contains a mix of Groups, Textures, Decorators and more. \ No newline at end of file diff --git a/RGB.NET.Brushes/RGB.NET.Brushes.csproj b/RGB.NET.Presets/RGB.NET.Presets.csproj similarity index 51% rename from RGB.NET.Brushes/RGB.NET.Brushes.csproj rename to RGB.NET.Presets/RGB.NET.Presets.csproj index d016193d..fc2d052c 100644 --- a/RGB.NET.Brushes/RGB.NET.Brushes.csproj +++ b/RGB.NET.Presets/RGB.NET.Presets.csproj @@ -1,24 +1,26 @@  - netstandard2.0;net45 - win7-x86;win7-x64 + net7.0;net6.0;net5.0 + latest + enable Darth Affe Wyrez en-US en-US - RGB.NET.Brushes - RGB.NET.Brushes - RGB.NET.Brushes - RGB.NET.Brushes - RGB.NET.Brushes - Brushes-Presets of RGB.NET - Brushes-Presets of RGB.NET, a C# (.NET) library for accessing various RGB-peripherals - Copyright © Darth Affe 2020 - Copyright © Darth Affe 2020 - http://lib.arge.be/icon.png + RGB.NET.Presets + RGB.NET.Presets + RGB.NET.Presets + RGB.NET.Presets + RGB.NET.Presets + Presets-Presets of RGB.NET + Presets for RGB.NET, a C# (.NET) library for accessing various RGB-peripherals + Copyright © Darth Affe 2023 + Copyright © Darth Affe 2023 + icon.png + README.md https://github.com/DarthAffe/RGB.NET - https://raw.githubusercontent.com/DarthAffe/RGB.NET/master/LICENSE + LGPL-2.1-only Github https://github.com/DarthAffe/RGB.NET True @@ -33,36 +35,29 @@ true True True - latest - - - - NETCORE;NETSTANDARD;NETSTANDARD2_0 - - - - NET45;NETFULL + portable + snupkg + true $(DefineConstants);TRACE;DEBUG true - full false - pdbonly true $(NoWarn);CS1591;CS1572;CS1573 $(DefineConstants);RELEASE - + + - - + + \ No newline at end of file diff --git a/RGB.NET.Presets/RGB.NET.Presets.csproj.DotSettings b/RGB.NET.Presets/RGB.NET.Presets.csproj.DotSettings new file mode 100644 index 00000000..9b6455cd --- /dev/null +++ b/RGB.NET.Presets/RGB.NET.Presets.csproj.DotSettings @@ -0,0 +1,6 @@ + + False + False + True + True + \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/AbstractGradientTexture.cs b/RGB.NET.Presets/Textures/AbstractGradientTexture.cs new file mode 100644 index 00000000..3f2f73c2 --- /dev/null +++ b/RGB.NET.Presets/Textures/AbstractGradientTexture.cs @@ -0,0 +1,56 @@ +using RGB.NET.Core; +using RGB.NET.Presets.Textures.Gradients; + +namespace RGB.NET.Presets.Textures; + +/// +/// +/// +/// Represents a abstract texture containing a color-gradient. +/// +public abstract class AbstractGradientTexture : AbstractBindable, ITexture +{ + #region Properties & Fields + + /// + /// Gets the gradient used to generate this texture. + /// + public IGradient Gradient { get; } + + /// + public Size Size { get; } + + /// + public Color this[in Point point] => GetColor(point); + + /// + public Color this[in Rectangle rectangle] => GetColor(rectangle.Center); + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The size of the texture. + /// The gradient used to generate this texture. + protected AbstractGradientTexture(Size size, IGradient gradient) + { + this.Size = size; + this.Gradient = gradient; + } + + #endregion + + #region Methods + + /// + /// Gets the color at the specified location of the texture. + /// + /// The location to get the color from. + /// The color at the specified location. + protected abstract Color GetColor(in Point point); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/BytePixelTexture.cs b/RGB.NET.Presets/Textures/BytePixelTexture.cs new file mode 100644 index 00000000..eb6cd1c4 --- /dev/null +++ b/RGB.NET.Presets/Textures/BytePixelTexture.cs @@ -0,0 +1,73 @@ +using System; +using RGB.NET.Core; +using RGB.NET.Presets.Textures.Sampler; + +namespace RGB.NET.Presets.Textures; + +/// +/// +/// Represents a texture of byte-data pixels. +/// +public sealed class BytePixelTexture : PixelTexture +{ + #region Properties & Fields + + private readonly byte[] _data; + /// + protected override ReadOnlySpan Data => _data; + + /// + /// Gets the color format the data is in. + /// + public ColorFormat ColorFormat { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// A is used. + /// + /// The width of the texture. + /// The height of the texture. + /// The pixel-data of the texture. + /// The color format the data is in. (default: RGB) + public BytePixelTexture(int with, int height, byte[] data, ColorFormat colorFormat = ColorFormat.RGB) + : this(with, height, data, new AverageByteSampler(), colorFormat) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The width of the texture. + /// The height of the texture. + /// The pixel-data of the texture. + /// The sampler used to get the color of a region. + /// The color format the data is in. (default: RGB) + public BytePixelTexture(int with, int height, byte[] data, ISampler sampler, ColorFormat colorFormat = ColorFormat.RGB) + : base(with, height, 3, sampler) + { + this._data = data; + this.ColorFormat = colorFormat; + + if (Data.Length != ((with * height) * 3)) throw new ArgumentException($"Data-Length {Data.Length} differs from the specified size {with}x{height} * 3 bytes ({with * height * 3})."); + } + + #endregion + + #region Methods + + /// + protected override Color GetColor(in ReadOnlySpan pixel) + { + return ColorFormat switch + { + ColorFormat.RGB => new Color(pixel[0], pixel[1], pixel[2]), + ColorFormat.BGR => new Color(pixel[2], pixel[1], pixel[0]), + _ => throw new ArgumentOutOfRangeException() + }; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/ConicalGradientTexture.cs b/RGB.NET.Presets/Textures/ConicalGradientTexture.cs new file mode 100644 index 00000000..c60d9e4e --- /dev/null +++ b/RGB.NET.Presets/Textures/ConicalGradientTexture.cs @@ -0,0 +1,101 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable MemberCanBeProtected.Global +// ReSharper disable ReturnTypeCanBeEnumerable.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +// ReSharper disable UnusedMember.Global + +using System; +using RGB.NET.Core; +using RGB.NET.Presets.Textures.Gradients; + +namespace RGB.NET.Presets.Textures; + +/// +/// +/// Represents a texture drawing a conical gradient. +/// +public sealed class ConicalGradientTexture : AbstractGradientTexture +{ + #region Constants + + private const float PI2 = MathF.PI * 2.0f; + + #endregion + + #region Properties & Fields + + private float _origin = MathF.Atan2(-1, 0); + /// + /// Gets or sets the origin (radian-angle) this is drawn to. (default: -π/2) + /// + public float Origin + { + get => _origin; + set => SetProperty(ref _origin, value); + } + + private Point _center = new(0.5f, 0.5f); + /// + /// Gets or sets the center (as percentage in the range [0..1]) of the drawn by this . (default: 0.5, 0.5) + /// + public Point Center + { + get => _center; + set => SetProperty(ref _center, value); + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The size of the texture. + /// The drawn by this . + public ConicalGradientTexture(Size size, IGradient gradient) + : base(size, gradient) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The size of the texture. + /// The drawn by this . + /// The center (as percentage in the range [0..1]). + public ConicalGradientTexture(Size size, IGradient gradient, Point center) + : base(size, gradient) + { + this.Center = center; + } + + /// + /// Initializes a new instance of the class. + /// + /// The size of the texture. + /// The drawn by this . + /// The center (as percentage in the range [0..1]). + /// The origin (radian-angle) the gradient is drawn to. + public ConicalGradientTexture(Size size, IGradient gradient, Point center, float origin) + : base(size, gradient) + { + this.Center = center; + this.Origin = origin; + } + + #endregion + + #region Methods + + /// + protected override Color GetColor(in Point point) + { + float angle = MathF.Atan2(point.Y - Center.Y, point.X - Center.X) - Origin; + if (angle < 0) angle += PI2; + float offset = angle / PI2; + + return Gradient.GetColor(offset); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/Enums/ColorFormat.cs b/RGB.NET.Presets/Textures/Enums/ColorFormat.cs new file mode 100644 index 00000000..fe816604 --- /dev/null +++ b/RGB.NET.Presets/Textures/Enums/ColorFormat.cs @@ -0,0 +1,12 @@ +#pragma warning disable 1591 + +namespace RGB.NET.Presets.Textures; + +/// +/// Contains a list of possible color formats. +/// +public enum ColorFormat +{ + RGB, + BGR +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/FloatPixelTexture.cs b/RGB.NET.Presets/Textures/FloatPixelTexture.cs new file mode 100644 index 00000000..55d15fc3 --- /dev/null +++ b/RGB.NET.Presets/Textures/FloatPixelTexture.cs @@ -0,0 +1,73 @@ +using System; +using RGB.NET.Core; +using RGB.NET.Presets.Textures.Sampler; + +namespace RGB.NET.Presets.Textures; + +/// +/// +/// Represents a texture of float-data pixels. +/// +public sealed class FloatPixelTexture : PixelTexture +{ + #region Properties & Fields + + private readonly float[] _data; + /// + protected override ReadOnlySpan Data => _data; + + /// + /// Gets the color format the data is in. + /// + public ColorFormat ColorFormat { get; } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// A is used. + /// + /// The width of the texture. + /// The height of the texture. + /// The pixel-data of the texture. + /// The color format the data is in. (default: RGB) + public FloatPixelTexture(int with, int height, float[] data, ColorFormat colorFormat = ColorFormat.RGB) + : this(with, height, data, new AverageFloatSampler(), colorFormat) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The width of the texture. + /// The height of the texture. + /// The pixel-data of the texture. + /// The sampler used to get the color of a region. + /// The color format the data is in. (default: RGB) + public FloatPixelTexture(int with, int height, float[] data, ISampler sampler, ColorFormat colorFormat = ColorFormat.RGB) + : base(with, height, 3, sampler) + { + this._data = data; + this.ColorFormat = colorFormat; + + if (Data.Length != ((with * height) * 3)) throw new ArgumentException($"Data-Length {Data.Length} differs from the specified size {with}x{height} * 3 bytes ({with * height * 3})."); + } + + #endregion + + #region Methods + + /// + protected override Color GetColor(in ReadOnlySpan pixel) + { + return ColorFormat switch + { + ColorFormat.RGB => new Color(pixel[0], pixel[1], pixel[2]), + ColorFormat.BGR => new Color(pixel[2], pixel[1], pixel[0]), + _ => throw new ArgumentOutOfRangeException() + }; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/Gradients/AbstractGradient.cs b/RGB.NET.Presets/Textures/Gradients/AbstractGradient.cs new file mode 100644 index 00000000..50c51429 --- /dev/null +++ b/RGB.NET.Presets/Textures/Gradients/AbstractGradient.cs @@ -0,0 +1,150 @@ +// ReSharper disable MemberCanBeProtected.Global +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global + +using System; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Linq; +using RGB.NET.Core; +using RGB.NET.Presets.Decorators; + +namespace RGB.NET.Presets.Textures.Gradients; + +/// +/// +/// +/// Represents a basic gradient. +/// +public abstract class AbstractGradient : AbstractDecoratable, IGradient +{ + #region Properties & Fields + + /// + /// Gets a list of the stops used by this . + /// + public ObservableCollection GradientStops { get; } = new(); + + private bool _wrapGradient; + /// + /// Gets or sets if the Gradient wraps around if there isn't a second stop to take. + /// Example: There is a stop at offset 0.0, 0.5 and 0.75. + /// Without wrapping offset 1.0 will be calculated the same as 0.75; with wrapping it would be the same as 0.0. + /// + public bool WrapGradient + { + get => _wrapGradient; + set => SetProperty(ref _wrapGradient, value); + } + + #endregion + + #region Events + + /// + public event EventHandler? GradientChanged; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + protected AbstractGradient() + { + GradientStops.CollectionChanged += GradientCollectionChanged; + PropertyChanged += (_, _) => OnGradientChanged(); + } + + /// + /// Initializes a new instance of the class. + /// + /// The stops with which the gradient should be initialized. + protected AbstractGradient(params GradientStop[] gradientStops) + { + GradientStops.CollectionChanged += GradientCollectionChanged; + PropertyChanged += (_, _) => OnGradientChanged(); + + foreach (GradientStop gradientStop in gradientStops) + GradientStops.Add(gradientStop); + } + + /// + /// Initializes a new instance of the class. + /// + /// Specifies whether the gradient should wrapp or not (see for an example of what this means). + /// The stops with which the gradient should be initialized. + protected AbstractGradient(bool wrapGradient, params GradientStop[] gradientStops) + { + this.WrapGradient = wrapGradient; + + GradientStops.CollectionChanged += GradientCollectionChanged; + PropertyChanged += (_, _) => OnGradientChanged(); + + foreach (GradientStop gradientStop in gradientStops) + GradientStops.Add(gradientStop); + } + + #endregion + + #region Methods + + /// + /// Clips the offset and ensures, that it is inside the bounds of the stop list. + /// + /// The offset to clip. + /// The clipped offset. + protected float ClipOffset(float offset) + { + float max = GradientStops.Max(stop => stop.Offset); + if (offset > max) + return max; + + float min = GradientStops.Min(stop => stop.Offset); + return offset < min ? min : offset; + } + + /// + public abstract Color GetColor(float offset); + + /// + public virtual void Move(float offset) + { + offset /= 360.0f; + + foreach (GradientStop gradientStop in GradientStops) + gradientStop.Offset += offset; + + while (GradientStops.All(stop => stop.Offset > 1)) + foreach (GradientStop gradientStop in GradientStops) + gradientStop.Offset -= 1; + + while (GradientStops.All(stop => stop.Offset < 0)) + foreach (GradientStop gradientStop in GradientStops) + gradientStop.Offset += 1; + } + + /// + /// Should be called to indicate that the gradient was changed. + /// + protected void OnGradientChanged() => GradientChanged?.Invoke(this, EventArgs.Empty); + + private void GradientCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) + { + if (e.OldItems != null) + foreach (GradientStop gradientStop in e.OldItems) + gradientStop.PropertyChanged -= GradientStopChanged; + + if (e.NewItems != null) + foreach (GradientStop gradientStop in e.NewItems) + gradientStop.PropertyChanged += GradientStopChanged; + + OnGradientChanged(); + } + + private void GradientStopChanged(object? sender, PropertyChangedEventArgs propertyChangedEventArgs) => OnGradientChanged(); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/Gradients/GradientStop.cs b/RGB.NET.Presets/Textures/Gradients/GradientStop.cs new file mode 100644 index 00000000..d7aa5361 --- /dev/null +++ b/RGB.NET.Presets/Textures/Gradients/GradientStop.cs @@ -0,0 +1,51 @@ +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +// ReSharper disable MemberCanBePrivate.Global + +using RGB.NET.Core; + +namespace RGB.NET.Presets.Textures.Gradients; + +/// +/// Represents a stop on a gradient. +/// +public class GradientStop : AbstractBindable +{ + #region Properties & Fields + + private float _offset; + /// + /// Gets or sets the percentage offset to place this . This should be inside the range of [0..1] but it's not necessary. + /// + public float Offset + { + get => _offset; + set => SetProperty(ref _offset, value); + } + + private Color _color; + /// + /// Gets or sets the of this . + /// + public Color Color + { + get => _color; + set => SetProperty(ref _color, value); + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The percentage offset to place this . + /// The of the . + public GradientStop(float offset, Color color) + { + this.Offset = offset; + this.Color = color; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/Gradients/IGradient.cs b/RGB.NET.Presets/Textures/Gradients/IGradient.cs new file mode 100644 index 00000000..ba761a76 --- /dev/null +++ b/RGB.NET.Presets/Textures/Gradients/IGradient.cs @@ -0,0 +1,31 @@ +// ReSharper disable EventNeverSubscribedTo.Global + +using System; +using RGB.NET.Core; +using RGB.NET.Presets.Decorators; + +namespace RGB.NET.Presets.Textures.Gradients; + +/// +/// Represents a basic gradient. +/// +public interface IGradient : IDecoratable +{ + /// + /// Occurs if the is changed. + /// + event EventHandler GradientChanged; + + /// + /// Gets the of the on the specified offset. + /// + /// The percentage offset to take the from. + /// The at the specific offset. + Color GetColor(float offset); + + /// + /// Moves the by the provided offset. + /// + /// The offset the should be moved. + void Move(float offset); +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/Gradients/LinearGradient.cs b/RGB.NET.Presets/Textures/Gradients/LinearGradient.cs new file mode 100644 index 00000000..29a732a6 --- /dev/null +++ b/RGB.NET.Presets/Textures/Gradients/LinearGradient.cs @@ -0,0 +1,151 @@ +// ReSharper disable UnusedMember.Global + +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using RGB.NET.Core; + +namespace RGB.NET.Presets.Textures.Gradients; + +/// +/// +/// Represents a linear interpolated gradient with n stops. +/// +public class LinearGradient : AbstractGradient +{ + #region Properties & Fields + + private bool _isOrderedGradientListDirty = true; + private LinkedList _orderedGradientStops = new(); + + #endregion + + #region Constructors + + /// + /// + /// Initializes a new instance of the class. + /// + public LinearGradient() + { + Initialize(); + } + + /// + /// + /// Initializes a new instance of the class. + /// + /// The stops with which the gradient should be initialized. + public LinearGradient(params GradientStop[] gradientStops) + : base(gradientStops) + { + Initialize(); + } + + /// + /// + /// Initializes a new instance of the class. + /// + /// Specifies whether the gradient should wrapp or not (see for an example of what this means). + /// The stops with which the gradient should be initialized. + public LinearGradient(bool wrapGradient, params GradientStop[] gradientStops) + : base(wrapGradient, gradientStops) + { + Initialize(); + } + + #endregion + + #region Methods + + private void Initialize() + { + void OnGradientStopOnPropertyChanged(object? sender, PropertyChangedEventArgs args) => _isOrderedGradientListDirty = true; + + foreach (GradientStop gradientStop in GradientStops) + gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged; + + GradientStops.CollectionChanged += (_, args) => + { + if (args.OldItems != null) + foreach (GradientStop gradientStop in args.OldItems) + gradientStop.PropertyChanged -= OnGradientStopOnPropertyChanged; + + if (args.NewItems != null) + foreach (GradientStop gradientStop in args.NewItems) + gradientStop.PropertyChanged += OnGradientStopOnPropertyChanged; + }; + } + + /// + /// + /// Gets the linear interpolated at the specified offset. + /// + /// The percentage offset to take the color from. + /// The at the specific offset. + public override Color GetColor(float offset) + { + if (GradientStops.Count == 0) return Color.Transparent; + if (GradientStops.Count == 1) return GradientStops[0].Color; + + if (_isOrderedGradientListDirty) + _orderedGradientStops = new LinkedList(GradientStops.OrderBy(x => x.Offset)); + + (GradientStop gsBefore, GradientStop gsAfter) = GetEnclosingGradientStops(offset, _orderedGradientStops, WrapGradient); + + float blendFactor = 0; + if (!gsBefore.Offset.Equals(gsAfter.Offset)) + blendFactor = ((offset - gsBefore.Offset) / (gsAfter.Offset - gsBefore.Offset)); + + float colA = ((gsAfter.Color.A - gsBefore.Color.A) * blendFactor) + gsBefore.Color.A; + float colR = ((gsAfter.Color.R - gsBefore.Color.R) * blendFactor) + gsBefore.Color.R; + float colG = ((gsAfter.Color.G - gsBefore.Color.G) * blendFactor) + gsBefore.Color.G; + float colB = ((gsAfter.Color.B - gsBefore.Color.B) * blendFactor) + gsBefore.Color.B; + + return new Color(colA, colR, colG, colB); + } + + /// + /// Get the two s encapsulating the specified offset. + /// + /// The reference offset. + /// The ordered list of to choose from. + /// Bool indicating if the gradient should be wrapped or not. + /// The two s encapsulating the specified offset. + protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(float offset, LinkedList orderedStops, bool wrap) + { + LinkedList gradientStops = new(orderedStops); + + if (wrap) + { + GradientStop? gsBefore, gsAfter; + + do + { + gsBefore = gradientStops.LastOrDefault(n => n.Offset <= offset); + if (gsBefore == null) + { + GradientStop lastStop = gradientStops.Last!.Value; + gradientStops.AddFirst(new GradientStop(lastStop.Offset - 1, lastStop.Color)); + gradientStops.RemoveLast(); + } + + gsAfter = gradientStops.FirstOrDefault(n => n.Offset >= offset); + if (gsAfter == null) + { + GradientStop firstStop = gradientStops.First!.Value; + gradientStops.AddLast(new GradientStop(firstStop.Offset + 1, firstStop.Color)); + gradientStops.RemoveFirst(); + } + + } while ((gsBefore == null) || (gsAfter == null)); + + return (gsBefore, gsAfter); + } + + offset = ClipOffset(offset); + return (gradientStops.Last(n => n.Offset <= offset), gradientStops.First(n => n.Offset >= offset)); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/Gradients/RainbowGradient.cs b/RGB.NET.Presets/Textures/Gradients/RainbowGradient.cs new file mode 100644 index 00000000..46c1e5b1 --- /dev/null +++ b/RGB.NET.Presets/Textures/Gradients/RainbowGradient.cs @@ -0,0 +1,108 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global + +using System; +using RGB.NET.Core; +using RGB.NET.Presets.Decorators; + +namespace RGB.NET.Presets.Textures.Gradients; + +/// +/// +/// +/// Represents a rainbow gradient which circles through all colors of the HUE-color-space.
+/// See as reference. +///
+public class RainbowGradient : AbstractDecoratable, IGradient +{ + #region Properties & Fields + + private float _startHue; + /// + /// Gets or sets the hue (in degrees) to start from. + /// + public float StartHue + { + get => _startHue; + set => SetProperty(ref _startHue, value); + } + + private float _endHue; + /// + /// Gets or sets the hue (in degrees) to end the with. + /// + public float EndHue + { + get => _endHue; + set => SetProperty(ref _endHue, value); + } + + #endregion + + #region Events + + /// + public event EventHandler? GradientChanged; + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The hue (in degrees) to start from (default: 0) + /// The hue (in degrees) to end with (default: 360) + public RainbowGradient(float startHue = 0, float endHue = 360) + { + this.StartHue = startHue; + this.EndHue = endHue; + + PropertyChanged += (_, _) => OnGradientChanged(); + } + + #endregion + + #region Methods + + /// + /// + /// Gets the color on the rainbow at the specified offset. + /// + /// The percentage offset to take the color from. + /// The color at the specific offset. + public Color GetColor(float offset) + { + float range = EndHue - StartHue; + float hue = StartHue + (range * offset); + return HSVColor.Create(hue, 1, 1); + } + + /// + public void Move(float offset) + { + // RainbowGradient is calculated inverse + offset *= -1; + + StartHue += offset; + EndHue += offset; + + while ((StartHue > 360) && (EndHue > 360)) + { + StartHue -= 360; + EndHue -= 360; + } + while ((StartHue < -360) && (EndHue < -360)) + { + StartHue += 360; + EndHue += 360; + } + } + + /// + /// Should be called to indicate that the gradient was changed. + /// + protected void OnGradientChanged() => GradientChanged?.Invoke(this, EventArgs.Empty); + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/LinearGradientTexture.cs b/RGB.NET.Presets/Textures/LinearGradientTexture.cs new file mode 100644 index 00000000..c5bc2f75 --- /dev/null +++ b/RGB.NET.Presets/Textures/LinearGradientTexture.cs @@ -0,0 +1,81 @@ +// ReSharper disable CollectionNeverUpdated.Global +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable MemberCanBeProtected.Global +// ReSharper disable ReturnTypeCanBeEnumerable.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +// ReSharper disable UnusedMember.Global + +using RGB.NET.Core; +using RGB.NET.Presets.Helper; +using RGB.NET.Presets.Textures.Gradients; + +namespace RGB.NET.Presets.Textures; + +/// +/// +/// Represents a texture drawing a linear gradient. +/// +public sealed class LinearGradientTexture : AbstractGradientTexture +{ + #region Properties & Fields + + private Point _startPoint = new(0, 0.5f); + /// + /// Gets or sets the start (as percentage in the range [0..1]) of the drawn by this . (default: 0.0, 0.5) + /// + public Point StartPoint + { + get => _startPoint; + set => SetProperty(ref _startPoint, value); + } + + private Point _endPoint = new(1, 0.5f); + /// + /// Gets or sets the end (as percentage in the range [0..1]) of the drawn by this . (default: 1.0, 0.5) + /// + public Point EndPoint + { + get => _endPoint; + set => SetProperty(ref _endPoint, value); + } + + #endregion + + #region Constructor + + /// + /// Initializes a new instance of the class. + /// + /// The size of the texture. + /// The drawn by this . + public LinearGradientTexture(Size size, IGradient gradient) + : base(size, gradient) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The size of the texture. + /// The drawn by this . + /// The start (as percentage in the range [0..1]). + /// The end (as percentage in the range [0..1]). + public LinearGradientTexture(Size size, IGradient gradient, Point startPoint, Point endPoint) + : base(size, gradient) + { + this.StartPoint = startPoint; + this.EndPoint = endPoint; + } + + #endregion + + #region Methods + + /// + protected override Color GetColor(in Point point) + { + float offset = GradientHelper.CalculateLinearGradientOffset(StartPoint, EndPoint, point); + return Gradient.GetColor(offset); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/RadialGradientTexture.cs b/RGB.NET.Presets/Textures/RadialGradientTexture.cs new file mode 100644 index 00000000..3f96dedd --- /dev/null +++ b/RGB.NET.Presets/Textures/RadialGradientTexture.cs @@ -0,0 +1,80 @@ +// ReSharper disable MemberCanBePrivate.Global +// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global +// ReSharper disable UnusedMember.Global + +using RGB.NET.Core; +using RGB.NET.Presets.Helper; +using RGB.NET.Presets.Textures.Gradients; + +namespace RGB.NET.Presets.Textures; + +/// +/// +/// Represents a texture drawing a radial gradient around a center point. +/// +public sealed class RadialGradientTexture : AbstractGradientTexture +{ + #region Properties & Fields + + private float _referenceDistance = GradientHelper.CalculateDistance(new Point(0.5f, 0.5f), new Point(0, 0)); + + private Point _center = new(0.5f, 0.5f); + /// + /// Gets or sets the center (as percentage in the range [0..1]) around which the should be drawn. (default: 0.5, 0.5) + /// + public Point Center + { + get => _center; + set + { + if (SetProperty(ref _center, value)) + CalculateReferenceDistance(); + } + } + + #endregion + + #region Constructors + + /// + /// Initializes a new instance of the class. + /// + /// The size of the texture. + /// The gradient drawn by the brush. + public RadialGradientTexture(Size size, IGradient gradient) + : base(size, gradient) + { } + + /// + /// Initializes a new instance of the class. + /// + /// The size of the texture. + /// The gradient drawn by the brush. + /// The center point (as percentage in the range [0..1]). + public RadialGradientTexture(Size size, IGradient gradient, Point center) + : base(size, gradient) + { + this.Center = center; + } + + #endregion + + #region Methods + + private void CalculateReferenceDistance() + { + float referenceX = Center.X < 0.5f ? 1 : 0; + float referenceY = Center.Y < 0.5f ? 1 : 0; + _referenceDistance = GradientHelper.CalculateDistance(new Point(referenceX, referenceY), Center); + } + + /// + protected override Color GetColor(in Point point) + { + float distance = GradientHelper.CalculateDistance(point, Center); + float offset = distance / _referenceDistance; + return Gradient.GetColor(offset); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/Sampler/AverageByteSampler.cs b/RGB.NET.Presets/Textures/Sampler/AverageByteSampler.cs new file mode 100644 index 00000000..8d5b8b6d --- /dev/null +++ b/RGB.NET.Presets/Textures/Sampler/AverageByteSampler.cs @@ -0,0 +1,124 @@ +using System; +using System.Numerics; +using System.Runtime.InteropServices; +using RGB.NET.Core; + +namespace RGB.NET.Presets.Textures.Sampler; + +/// +/// Represents a sampled that averages multiple byte-data entries. +/// +public class AverageByteSampler : ISampler +{ + #region Constants + + private static readonly int INT_VECTOR_LENGTH = Vector.Count; + + #endregion + + #region Methods + + /// + public unsafe void Sample(in SamplerInfo info, in Span pixelData) + { + int count = info.Width * info.Height; + if (count == 0) return; + + ReadOnlySpan data = info.Data; + + int dataLength = pixelData.Length; + Span sums = stackalloc uint[dataLength]; + + if (Vector.IsHardwareAccelerated && (data.Length >= Vector.Count) && (dataLength <= Vector.Count)) + { + int elementsPerVector = Vector.Count / dataLength; + int valuesPerVector = elementsPerVector * dataLength; + + int chunks = data.Length / valuesPerVector; + int missingElements = data.Length - (chunks * valuesPerVector); + + Vector sum1 = Vector.Zero; + Vector sum2 = Vector.Zero; + Vector sum3 = Vector.Zero; + Vector sum4 = Vector.Zero; + + fixed (byte* colorPtr = &MemoryMarshal.GetReference(data)) + { + byte* current = colorPtr; + for (int i = 0; i < chunks; i++) + { + Vector bytes = *(Vector*)current; + Vector.Widen(bytes, out Vector short1, out Vector short2); + Vector.Widen(short1, out Vector int1, out Vector int2); + Vector.Widen(short2, out Vector int3, out Vector int4); + + sum1 = Vector.Add(sum1, int1); + sum2 = Vector.Add(sum2, int2); + sum3 = Vector.Add(sum3, int3); + sum4 = Vector.Add(sum4, int4); + + current += valuesPerVector; + } + } + + int value = 0; + int sumIndex = 0; + for (int j = 0; (j < INT_VECTOR_LENGTH) && (value < valuesPerVector); j++) + { + sums[sumIndex] += sum1[j]; + ++sumIndex; + ++value; + + if (sumIndex >= dataLength) + sumIndex = 0; + } + + for (int j = 0; (j < INT_VECTOR_LENGTH) && (value < valuesPerVector); j++) + { + sums[sumIndex] += sum2[j]; + ++sumIndex; + ++value; + + if (sumIndex >= dataLength) + sumIndex = 0; + } + + for (int j = 0; (j < INT_VECTOR_LENGTH) && (value < valuesPerVector); j++) + { + sums[sumIndex] += sum3[j]; + ++sumIndex; + ++value; + + if (sumIndex >= dataLength) + sumIndex = 0; + } + + for (int j = 0; (j < INT_VECTOR_LENGTH) && (value < valuesPerVector); j++) + { + sums[sumIndex] += sum4[j]; + ++sumIndex; + ++value; + + if (sumIndex >= dataLength) + sumIndex = 0; + } + + int offset = chunks * valuesPerVector; + for (int i = 0; i < missingElements; i += dataLength) + for (int j = 0; j < sums.Length; j++) + sums[j] += data[offset + i + j]; + } + else + { + for (int i = 0; i < data.Length; i += dataLength) + for (int j = 0; j < sums.Length; j++) + sums[j] += data[i + j]; + } + + float divisor = count * byte.MaxValue; + for (int i = 0; i < pixelData.Length; i++) + pixelData[i] = (sums[i] / divisor).GetByteValueFromPercentage(); + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.Presets/Textures/Sampler/AverageFloatSampler.cs b/RGB.NET.Presets/Textures/Sampler/AverageFloatSampler.cs new file mode 100644 index 00000000..50e95638 --- /dev/null +++ b/RGB.NET.Presets/Textures/Sampler/AverageFloatSampler.cs @@ -0,0 +1,67 @@ +using System; +using System.Numerics; +using System.Runtime.InteropServices; +using RGB.NET.Core; + +namespace RGB.NET.Presets.Textures.Sampler; + +/// +/// Represents a sampled that averages multiple float-data entries. +/// +public class AverageFloatSampler : ISampler +{ + #region Methods + + /// + public unsafe void Sample(in SamplerInfo info, in Span pixelData) + { + int count = info.Width * info.Height; + if (count == 0) return; + + ReadOnlySpan data = info.Data; + + int dataLength = pixelData.Length; + Span sums = stackalloc float[dataLength]; + + if (Vector.IsHardwareAccelerated && (data.Length >= Vector.Count) && (dataLength <= Vector.Count)) + { + int elementsPerVector = Vector.Count / dataLength; + int valuesPerVector = elementsPerVector * dataLength; + + int chunks = data.Length / valuesPerVector; + int missingElements = data.Length - (chunks * valuesPerVector); + + Vector sum = Vector.Zero; + + fixed (float* colorPtr = &MemoryMarshal.GetReference(data)) + { + float* current = colorPtr; + for (int i = 0; i < chunks; i++) + { + sum = Vector.Add(sum, *(Vector*)current); + current += valuesPerVector; + } + } + + for (int i = 0; i < valuesPerVector; i += dataLength) + for (int j = 0; j < sums.Length; j++) + sums[j] += sum[i + j]; + + int offset = chunks * valuesPerVector; + for (int i = 0; i < missingElements; i += dataLength) + for (int j = 0; j < sums.Length; j++) + sums[j] += data[offset + i + j]; + } + else + { + for (int i = 0; i < data.Length; i += dataLength) + for (int j = 0; j < sums.Length; j++) + sums[j] += data[i + j]; + } + + for (int i = 0; i < pixelData.Length; i++) + pixelData[i] = sums[i] / count; + } + + #endregion +} \ No newline at end of file diff --git a/RGB.NET.sln b/RGB.NET.sln index 2d2701ee..afbcb679 100644 --- a/RGB.NET.sln +++ b/RGB.NET.sln @@ -1,16 +1,12 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29424.173 +# Visual Studio Version 17 +VisualStudioVersion = 17.1.32407.343 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Devices", "Devices", "{D13032C6-432E-4F43-8A32-071133C22B16}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Presets", "Presets", "{EBC33090-8494-4DF4-B4B6-64D0E531E93F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Core", "RGB.NET.Core\RGB.NET.Core.csproj", "{F3ED5768-7251-4347-8D8F-2866313DA658}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Asus_Legacy", "RGB.NET.Devices.Asus_Legacy\RGB.NET.Devices.Asus_Legacy.csproj", "{105FD573-D165-49D1-B8EC-937570616F29}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.CoolerMaster", "RGB.NET.Devices.CoolerMaster\RGB.NET.Devices.CoolerMaster.csproj", "{E8F927F5-E7CF-464A-B9AE-824C2B29A7D1}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Corsair", "RGB.NET.Devices.Corsair\RGB.NET.Devices.Corsair.csproj", "{BDE3DAD5-75C9-4C50-848D-1E766E916006}" @@ -27,15 +23,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Novation", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Razer", "RGB.NET.Devices.Razer\RGB.NET.Devices.Razer.csproj", "{2E162CB7-2C6C-4069-8356-06162F7BE0AA}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Roccat", "RGB.NET.Devices.Roccat\RGB.NET.Devices.Roccat.csproj", "{9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.SoIP", "RGB.NET.Devices.SoIP\RGB.NET.Devices.SoIP.csproj", "{14FF7ECF-2E58-4B11-97A2-C5801E1BC696}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Brushes", "RGB.NET.Brushes\RGB.NET.Brushes.csproj", "{B159FB51-5939-490E-A1BA-FB55D4D7ADDF}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Decorators", "RGB.NET.Decorators\RGB.NET.Decorators.csproj", "{8725C448-818C-41F7-B23F-F97E062BF233}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Groups", "RGB.NET.Groups\RGB.NET.Groups.csproj", "{6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Presets", "RGB.NET.Presets\RGB.NET.Presets.csproj", "{B159FB51-5939-490E-A1BA-FB55D4D7ADDF}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.WS281X", "RGB.NET.Devices.WS281X\RGB.NET.Devices.WS281X.csproj", "{0AD382DA-E999-4F74-9658-8D402EE9BF3F}" EndProject @@ -49,6 +37,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Asus", "RGB EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.Wooting", "RGB.NET.Devices.Wooting\RGB.NET.Devices.Wooting.csproj", "{DD46DB2D-85BE-4962-86AE-E38C9053A548}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Layout", "RGB.NET.Layout\RGB.NET.Layout.csproj", "{8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.HID", "RGB.NET.HID\RGB.NET.HID.csproj", "{4F4B7329-4858-4314-BA32-9DF3B1B33482}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.PicoPi", "RGB.NET.Devices.PicoPi\RGB.NET.Devices.PicoPi.csproj", "{7FC5C7A8-7B27-46E7-A8E8-DB80568F49C5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Presets.Tests", "Tests\RGB.NET.Presets.Tests\RGB.NET.Presets.Tests.csproj", "{EDBA49D6-AE96-4E96-9E6A-30154D93BD5F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RGB.NET.Devices.OpenRGB", "RGB.NET.Devices.OpenRGB\RGB.NET.Devices.OpenRGB.csproj", "{F29A96E5-CDD0-469F-A871-A35A7519BC49}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -59,10 +57,6 @@ Global {F3ED5768-7251-4347-8D8F-2866313DA658}.Debug|Any CPU.Build.0 = Debug|Any CPU {F3ED5768-7251-4347-8D8F-2866313DA658}.Release|Any CPU.ActiveCfg = Release|Any CPU {F3ED5768-7251-4347-8D8F-2866313DA658}.Release|Any CPU.Build.0 = Release|Any CPU - {105FD573-D165-49D1-B8EC-937570616F29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {105FD573-D165-49D1-B8EC-937570616F29}.Debug|Any CPU.Build.0 = Debug|Any CPU - {105FD573-D165-49D1-B8EC-937570616F29}.Release|Any CPU.ActiveCfg = Release|Any CPU - {105FD573-D165-49D1-B8EC-937570616F29}.Release|Any CPU.Build.0 = Release|Any CPU {E8F927F5-E7CF-464A-B9AE-824C2B29A7D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E8F927F5-E7CF-464A-B9AE-824C2B29A7D1}.Debug|Any CPU.Build.0 = Debug|Any CPU {E8F927F5-E7CF-464A-B9AE-824C2B29A7D1}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -95,26 +89,10 @@ Global {2E162CB7-2C6C-4069-8356-06162F7BE0AA}.Debug|Any CPU.Build.0 = Debug|Any CPU {2E162CB7-2C6C-4069-8356-06162F7BE0AA}.Release|Any CPU.ActiveCfg = Release|Any CPU {2E162CB7-2C6C-4069-8356-06162F7BE0AA}.Release|Any CPU.Build.0 = Release|Any CPU - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E}.Release|Any CPU.Build.0 = Release|Any CPU - {14FF7ECF-2E58-4B11-97A2-C5801E1BC696}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {14FF7ECF-2E58-4B11-97A2-C5801E1BC696}.Debug|Any CPU.Build.0 = Debug|Any CPU - {14FF7ECF-2E58-4B11-97A2-C5801E1BC696}.Release|Any CPU.ActiveCfg = Release|Any CPU - {14FF7ECF-2E58-4B11-97A2-C5801E1BC696}.Release|Any CPU.Build.0 = Release|Any CPU {B159FB51-5939-490E-A1BA-FB55D4D7ADDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B159FB51-5939-490E-A1BA-FB55D4D7ADDF}.Debug|Any CPU.Build.0 = Debug|Any CPU {B159FB51-5939-490E-A1BA-FB55D4D7ADDF}.Release|Any CPU.ActiveCfg = Release|Any CPU {B159FB51-5939-490E-A1BA-FB55D4D7ADDF}.Release|Any CPU.Build.0 = Release|Any CPU - {8725C448-818C-41F7-B23F-F97E062BF233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8725C448-818C-41F7-B23F-F97E062BF233}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8725C448-818C-41F7-B23F-F97E062BF233}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8725C448-818C-41F7-B23F-F97E062BF233}.Release|Any CPU.Build.0 = Release|Any CPU - {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40}.Release|Any CPU.Build.0 = Release|Any CPU {0AD382DA-E999-4F74-9658-8D402EE9BF3F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0AD382DA-E999-4F74-9658-8D402EE9BF3F}.Debug|Any CPU.Build.0 = Debug|Any CPU {0AD382DA-E999-4F74-9658-8D402EE9BF3F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -135,12 +113,31 @@ Global {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Debug|Any CPU.Build.0 = Debug|Any CPU {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Release|Any CPU.ActiveCfg = Release|Any CPU {DD46DB2D-85BE-4962-86AE-E38C9053A548}.Release|Any CPU.Build.0 = Release|Any CPU + {8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8AAB3736-B443-402C-B8AC-63D1A6DAFCCB}.Release|Any CPU.Build.0 = Release|Any CPU + {4F4B7329-4858-4314-BA32-9DF3B1B33482}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4F4B7329-4858-4314-BA32-9DF3B1B33482}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4F4B7329-4858-4314-BA32-9DF3B1B33482}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4F4B7329-4858-4314-BA32-9DF3B1B33482}.Release|Any CPU.Build.0 = Release|Any CPU + {7FC5C7A8-7B27-46E7-A8E8-DB80568F49C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7FC5C7A8-7B27-46E7-A8E8-DB80568F49C5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7FC5C7A8-7B27-46E7-A8E8-DB80568F49C5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7FC5C7A8-7B27-46E7-A8E8-DB80568F49C5}.Release|Any CPU.Build.0 = Release|Any CPU + {EDBA49D6-AE96-4E96-9E6A-30154D93BD5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EDBA49D6-AE96-4E96-9E6A-30154D93BD5F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EDBA49D6-AE96-4E96-9E6A-30154D93BD5F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EDBA49D6-AE96-4E96-9E6A-30154D93BD5F}.Release|Any CPU.Build.0 = Release|Any CPU + {F29A96E5-CDD0-469F-A871-A35A7519BC49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F29A96E5-CDD0-469F-A871-A35A7519BC49}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F29A96E5-CDD0-469F-A871-A35A7519BC49}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F29A96E5-CDD0-469F-A871-A35A7519BC49}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {105FD573-D165-49D1-B8EC-937570616F29} = {D13032C6-432E-4F43-8A32-071133C22B16} {E8F927F5-E7CF-464A-B9AE-824C2B29A7D1} = {D13032C6-432E-4F43-8A32-071133C22B16} {BDE3DAD5-75C9-4C50-848D-1E766E916006} = {D13032C6-432E-4F43-8A32-071133C22B16} {8496134D-16F5-43E6-B847-604964B240AD} = {D13032C6-432E-4F43-8A32-071133C22B16} @@ -149,16 +146,14 @@ Global {00BA7E8E-822A-42DA-9EB4-DDBBC7CB0E46} = {D13032C6-432E-4F43-8A32-071133C22B16} {19F701FD-5577-4873-9BE6-6775676FA185} = {D13032C6-432E-4F43-8A32-071133C22B16} {2E162CB7-2C6C-4069-8356-06162F7BE0AA} = {D13032C6-432E-4F43-8A32-071133C22B16} - {9DF256B9-1AB7-4D5B-B2E5-94AF6691DC9E} = {D13032C6-432E-4F43-8A32-071133C22B16} - {14FF7ECF-2E58-4B11-97A2-C5801E1BC696} = {D13032C6-432E-4F43-8A32-071133C22B16} - {B159FB51-5939-490E-A1BA-FB55D4D7ADDF} = {EBC33090-8494-4DF4-B4B6-64D0E531E93F} - {8725C448-818C-41F7-B23F-F97E062BF233} = {EBC33090-8494-4DF4-B4B6-64D0E531E93F} - {6FEBDC9E-909D-4EE2-B003-EDFBEF5FFF40} = {EBC33090-8494-4DF4-B4B6-64D0E531E93F} {0AD382DA-E999-4F74-9658-8D402EE9BF3F} = {D13032C6-432E-4F43-8A32-071133C22B16} {FFDE4387-60F2-47B6-9704-3A57D02B8C64} = {D13032C6-432E-4F43-8A32-071133C22B16} {A3FD5AD7-040A-47CA-A278-53493A25FF8A} = {92D7C263-D4C9-4D26-93E2-93C1F9C2CD16} {E0732B34-3F96-4DD9-AFD5-0E34B833AD6D} = {D13032C6-432E-4F43-8A32-071133C22B16} {DD46DB2D-85BE-4962-86AE-E38C9053A548} = {D13032C6-432E-4F43-8A32-071133C22B16} + {7FC5C7A8-7B27-46E7-A8E8-DB80568F49C5} = {D13032C6-432E-4F43-8A32-071133C22B16} + {EDBA49D6-AE96-4E96-9E6A-30154D93BD5F} = {92D7C263-D4C9-4D26-93E2-93C1F9C2CD16} + {F29A96E5-CDD0-469F-A871-A35A7519BC49} = {D13032C6-432E-4F43-8A32-071133C22B16} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {7F222AD4-1F9E-4AAB-9D69-D62372D4C1BA} diff --git a/RGB.NET.sln.DotSettings b/RGB.NET.sln.DotSettings index 563aafdc..f0e61dd4 100644 --- a/RGB.NET.sln.DotSettings +++ b/RGB.NET.sln.DotSettings @@ -258,20 +258,28 @@ False False False + 131DMX AFBG + API ARGB + BGR BWZ + CID CM CMSDK + CUE CUESDK DB DG DMX + DRAM EK FM GEZ + GSDK HID HS + HSV IBAN ID IO @@ -280,7 +288,9 @@ PDF PLZ RGB + ROG SAP + SDK SQL UI USB diff --git a/Resources/icon.png b/Resources/icon.png new file mode 100644 index 00000000..484098a0 Binary files /dev/null and b/Resources/icon.png differ diff --git a/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs index 20b17a1b..0f781556 100644 --- a/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs +++ b/Tests/RGB.NET.Core.Tests/Color/ColorTest.cs @@ -1,395 +1,406 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace RGB.NET.Core.Tests.Color +namespace RGB.NET.Core.Tests.Color; + +[TestClass] +public class ColorTest { - [TestClass] - public class ColorTest + #region Basics + + [TestMethod] + public void VerifyTransparent() + { + Core.Color transparent = Core.Color.Transparent; + + Assert.AreEqual(0, transparent.GetA(), "A is not 0"); + Assert.AreEqual(0, transparent.GetR(), "R is not 0"); + Assert.AreEqual(0, transparent.GetG(), "G is not 0"); + Assert.AreEqual(0, transparent.GetB(), "B is not 0"); + } + + [TestMethod] + public void ToStringTest() + { + Core.Color color = new(255, 120, 13, 1); + + Assert.AreEqual("[A: 255, R: 120, G: 13, B: 1]", color.ToString()); + } + + #region HashCode + + [TestMethod] + public void GetHashCodeTestEqual() + { + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 32, 255); + + Assert.AreEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + [TestMethod] + public void GetHashCodeTestNotEqualA() + { + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(99, 68, 32, 255); + + Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + [TestMethod] + public void GetHashCodeTestNotEqualR() + { + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 69, 32, 255); + + Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + [TestMethod] + public void GetHashCodeTestNotEqualG() + { + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 200, 255); + + Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + [TestMethod] + public void GetHashCodeTestNotEqualB() + { + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 32, 0); + + Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + #endregion + + #region Equality + + [TestMethod] + public void EqualityTestEqual() + { + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 32, 255); + + Assert.IsTrue(color1.Equals(color2), $"Equals returns false on equal colors {color1} and {color2}"); + Assert.IsTrue(color1 == color2, $"Equal-operator returns false on equal colors {color1} and {color2}"); + Assert.IsFalse(color1 != color2, $"Not-Equal-operator returns true on equal colors {color1} and {color2}"); + } + + [TestMethod] + public void EqualityTestNotEqualA() + { + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(99, 68, 32, 255); + + Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); + Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); + Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); + } + + [TestMethod] + public void EqualityTestNotEqualR() + { + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 69, 32, 255); + + Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); + Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); + Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); + } + + [TestMethod] + public void EqualityTestNotEqualG() { - #region Basics - - [TestMethod] - public void VerifyTransparent() - { - Core.Color transparent = Core.Color.Transparent; - - Assert.AreEqual(0, transparent.GetA(), "A is not 0"); - Assert.AreEqual(0, transparent.GetR(), "R is not 0"); - Assert.AreEqual(0, transparent.GetG(), "G is not 0"); - Assert.AreEqual(0, transparent.GetB(), "B is not 0"); - } - - [TestMethod] - public void ToStringTest() - { - Core.Color color = new Core.Color(255, 120, 13, 1); - - Assert.AreEqual("[A: 255, R: 120, G: 13, B: 1]", color.ToString()); - } - - #region HashCode - - [TestMethod] - public void GetHashCodeTestEqual() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 32, 255); - - Assert.AreEqual(color1.GetHashCode(), color2.GetHashCode()); - } - - [TestMethod] - public void GetHashCodeTestNotEqualA() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(99, 68, 32, 255); - - Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); - } - - [TestMethod] - public void GetHashCodeTestNotEqualR() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 69, 32, 255); - - Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); - } - - [TestMethod] - public void GetHashCodeTestNotEqualG() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 200, 255); - - Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); - } - - [TestMethod] - public void GetHashCodeTestNotEqualB() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 32, 0); - - Assert.AreNotEqual(color1.GetHashCode(), color2.GetHashCode()); - } - - #endregion - - #region Equality - - [TestMethod] - public void EqualityTestEqual() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 32, 255); - - Assert.IsTrue(color1.Equals(color2), $"Equals returns false on equal colors {color1} and {color2}"); - Assert.IsTrue(color1 == color2, $"Equal-operator returns false on equal colors {color1} and {color2}"); - Assert.IsFalse(color1 != color2, $"Not-Equal-operator returns true on equal colors {color1} and {color2}"); - } - - [TestMethod] - public void EqualityTestNotEqualA() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(99, 68, 32, 255); - - Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); - Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); - Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); - } - - [TestMethod] - public void EqualityTestNotEqualR() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 69, 32, 255); - - Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); - Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); - Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); - } - - [TestMethod] - public void EqualityTestNotEqualG() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 200, 255); - - Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); - Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); - Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); - } - - [TestMethod] - public void EqualityTestNotEqualB() - { - Core.Color color1 = new Core.Color(100, 68, 32, 255); - Core.Color color2 = new Core.Color(100, 68, 32, 0); - - Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); - Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); - Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); - } - - #endregion - - #endregion - - #region Constructors - - [TestMethod] - public void RGBByteConstructorTest() - { - Core.Color color = new Core.Color((byte)10, (byte)120, (byte)255); - - Assert.AreEqual(255, color.GetA(), "A is not 255"); - Assert.AreEqual(10, color.GetR(), "R is not 10"); - Assert.AreEqual(120, color.GetG(), "G is not 120"); - Assert.AreEqual(255, color.GetB(), "B is not 255"); - } - - [TestMethod] - public void ARGBByteConstructorTest() - { - Core.Color color = new Core.Color((byte)200, (byte)10, (byte)120, (byte)255); - - Assert.AreEqual(200, color.GetA(), "A is not 200"); - Assert.AreEqual(10, color.GetR(), "R is not 10"); - Assert.AreEqual(120, color.GetG(), "G is not 120"); - Assert.AreEqual(255, color.GetB(), "B is not 255"); - } - - [TestMethod] - public void RGBIntConstructorTest() - { - Core.Color color = new Core.Color(10, 120, 255); - - Assert.AreEqual(255, color.GetA(), "A is not 255"); - Assert.AreEqual(10, color.GetR(), "R is not 10"); - Assert.AreEqual(120, color.GetG(), "G is not 120"); - Assert.AreEqual(255, color.GetB(), "B is not 255"); - } - - [TestMethod] - public void ARGBIntConstructorTest() - { - Core.Color color = new Core.Color(200, 10, 120, 255); - - Assert.AreEqual(200, color.GetA(), "A is not 200"); - Assert.AreEqual(10, color.GetR(), "R is not 10"); - Assert.AreEqual(120, color.GetG(), "G is not 120"); - Assert.AreEqual(255, color.GetB(), "B is not 255"); - } - - [TestMethod] - public void RGBIntConstructorClampTest() - { - Core.Color color1 = new Core.Color(256, 256, 256); - - Assert.AreEqual(255, color1.GetA(), "A is not 255"); - Assert.AreEqual(255, color1.GetR(), "R is not 255"); - Assert.AreEqual(255, color1.GetG(), "G is not 255"); - Assert.AreEqual(255, color1.GetB(), "B is not 255"); - - Core.Color color2 = new Core.Color(-1, -1, -1); - - Assert.AreEqual(255, color2.GetA(), "A is not 255"); - Assert.AreEqual(0, color2.GetR(), "R is not 0"); - Assert.AreEqual(0, color2.GetG(), "G is not 0"); - Assert.AreEqual(0, color2.GetB(), "B is not 0"); - } - - [TestMethod] - public void ARGBIntConstructorClampTest() - { - Core.Color color = new Core.Color(256, 256, 256, 256); - - Assert.AreEqual(255, color.GetA(), "A is not 255"); - Assert.AreEqual(255, color.GetR(), "R is not 255"); - Assert.AreEqual(255, color.GetG(), "G is not 255"); - Assert.AreEqual(255, color.GetB(), "B is not 255"); - - Core.Color color2 = new Core.Color(-1, -1, -1, -1); - - Assert.AreEqual(0, color2.GetA(), "A is not 0"); - Assert.AreEqual(0, color2.GetR(), "R is not 0"); - Assert.AreEqual(0, color2.GetG(), "G is not 0"); - Assert.AreEqual(0, color2.GetB(), "B is not 0"); - } - - [TestMethod] - public void RGBPercentConstructorTest() - { - Core.Color color = new Core.Color(0.25341, 0.55367, 1); - - Assert.AreEqual(1, color.A, DoubleExtensions.TOLERANCE, "A is not 1"); - Assert.AreEqual(0.25341, color.R, DoubleExtensions.TOLERANCE, "R is not 0.25341"); - Assert.AreEqual(0.55367, color.G, DoubleExtensions.TOLERANCE, "G is not 0.55367"); - Assert.AreEqual(1, color.B, DoubleExtensions.TOLERANCE, "B is not 1"); - } - - [TestMethod] - public void ARGBPercentConstructorTest() - { - Core.Color color = new Core.Color(0.3315, 0.25341, 0.55367, 1); - - Assert.AreEqual(0.3315, color.A, DoubleExtensions.TOLERANCE, "A is not 0.3315"); - Assert.AreEqual(0.25341, color.R, DoubleExtensions.TOLERANCE, "R is not 0.25341"); - Assert.AreEqual(0.55367, color.G, DoubleExtensions.TOLERANCE, "G is not 0.55367"); - Assert.AreEqual(1, color.B, DoubleExtensions.TOLERANCE, "B is not 1"); - } - - [TestMethod] - public void RGBPercentConstructorClampTest() - { - Core.Color color1 = new Core.Color(1.1, 1.1, 1.1); - - Assert.AreEqual(1, color1.A, "A is not 1"); - Assert.AreEqual(1, color1.R, "R is not 1"); - Assert.AreEqual(1, color1.G, "G is not 1"); - Assert.AreEqual(1, color1.B, "B is not 1"); - - Core.Color color2 = new Core.Color(-1.0, -1.0, -1.0); - - Assert.AreEqual(1, color2.A, "A is not 1"); - Assert.AreEqual(0, color2.R, "R is not 0"); - Assert.AreEqual(0, color2.G, "G is not 0"); - Assert.AreEqual(0, color2.B, "B is not 0"); - } - - [TestMethod] - public void ARGBPercentConstructorClampTest() - { - Core.Color color1 = new Core.Color(1.1, 1.1, 1.1, 1.1); - - Assert.AreEqual(1, color1.A, "A is not 1"); - Assert.AreEqual(1, color1.R, "R is not 1"); - Assert.AreEqual(1, color1.G, "G is not 1"); - Assert.AreEqual(1, color1.B, "B is not 1"); - - Core.Color color2 = new Core.Color(-1.0, -1.0, -1.0, -1.0); - - Assert.AreEqual(0, color2.A, "A is not 0"); - Assert.AreEqual(0, color2.R, "R is not 0"); - Assert.AreEqual(0, color2.G, "G is not 0"); - Assert.AreEqual(0, color2.B, "B is not 0"); - } - - [TestMethod] - public void CloneConstructorTest() - { - Core.Color referennceColor = new Core.Color(200, 10, 120, 255); - Core.Color color = new Core.Color(referennceColor); - - Assert.AreEqual(200, color.GetA(), "A is not 200"); - Assert.AreEqual(10, color.GetR(), "R is not 10"); - Assert.AreEqual(120, color.GetG(), "G is not 120"); - Assert.AreEqual(255, color.GetB(), "B is not 255"); - } - - #endregion - - #region Conversion - - [TestMethod] - public void ColorFromComponentsTest() - { - Core.Color color = (255, 120, 13, 1); - - Assert.AreEqual(255, color.GetA(), $"A doesn't equal the used component. ({color.GetA()} != 255)"); - Assert.AreEqual(120, color.GetR(), $"R doesn't equal the used component. ({color.GetR()} != 120)"); - Assert.AreEqual(13, color.GetG(), $"G doesn't equal the used component. ({color.GetG()} != 13)"); - Assert.AreEqual(1, color.GetB(), $"B doesn't equal the used component. ({color.GetB()} != 1)"); - } - - [TestMethod] - public void DesconstructTest() - { - (byte a, byte r, byte g, byte b) = new Core.Color(255, 120, 13, 1).GetRGBBytes(); - - Assert.AreEqual(255, a, $"A doesn't equal the color. ({a} != 255)"); - Assert.AreEqual(120, r, $"R doesn't equal the color. ({r} != 120)"); - Assert.AreEqual(13, g, $"G doesn't equal the color. ({g} != 13)"); - Assert.AreEqual(1, b, $"B doesn't equal the color. ({b} != 1)"); - } - - [TestMethod] - public void AToPercentTest() - { - Core.Color color1 = new Core.Color(0, 0, 0, 0); - Assert.AreEqual(0, color1.A); - - Core.Color color2 = new Core.Color(255, 0, 0, 0); - Assert.AreEqual(1, color2.A); - - Core.Color color3 = new Core.Color(128, 0, 0, 0); - Assert.AreEqual(128 / 255.0, color3.A); - - Core.Color color4 = new Core.Color(30, 0, 0, 0); - Assert.AreEqual(30 / 255.0, color4.A); - - Core.Color color5 = new Core.Color(201, 0, 0, 0); - Assert.AreEqual(201 / 255.0, color5.A); - } - - [TestMethod] - public void RToPercentTest() - { - Core.Color color1 = new Core.Color(0, 0, 0, 0); - Assert.AreEqual(0, color1.R); - - Core.Color color2 = new Core.Color(0, 255, 0, 0); - Assert.AreEqual(1, color2.R); - - Core.Color color3 = new Core.Color(0, 128, 0, 0); - Assert.AreEqual(128 / 255.0, color3.R); + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 200, 255); - Core.Color color4 = new Core.Color(0, 30, 0, 0); - Assert.AreEqual(30 / 255.0, color4.R); - - Core.Color color5 = new Core.Color(0, 201, 0, 0); - Assert.AreEqual(201 / 255.0, color5.R); - } - - [TestMethod] - public void GToPercentTest() - { - Core.Color color1 = new Core.Color(0, 0, 0, 0); - Assert.AreEqual(0, color1.G); + Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); + Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); + Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); + } - Core.Color color2 = new Core.Color(0, 0, 255, 0); - Assert.AreEqual(1, color2.G); + [TestMethod] + public void EqualityTestNotEqualB() + { + Core.Color color1 = new(100, 68, 32, 255); + Core.Color color2 = new(100, 68, 32, 0); - Core.Color color3 = new Core.Color(0, 0, 128, 0); - Assert.AreEqual(128 / 255.0, color3.G); - - Core.Color color4 = new Core.Color(0, 0, 30, 0); - Assert.AreEqual(30 / 255.0, color4.G); + Assert.IsFalse(color1.Equals(color2), $"Equals returns true on not equal colors {color1} and {color2}"); + Assert.IsFalse(color1 == color2, $"Equal-operator returns true on not equal colors {color1} and {color2}"); + Assert.IsTrue(color1 != color2, $"Not-Equal-operator returns false on not equal colors {color1} and {color2}"); + } - Core.Color color5 = new Core.Color(0, 0, 201, 0); - Assert.AreEqual(201 / 255.0, color5.G); - } - - [TestMethod] - public void BToPercentTest() - { - Core.Color color1 = new Core.Color(0, 0, 0, 0); - Assert.AreEqual(0, color1.B); + #endregion - Core.Color color2 = new Core.Color(0, 0, 0, 255); - Assert.AreEqual(1, color2.B); + #endregion - Core.Color color3 = new Core.Color(0, 0, 0, 128); - Assert.AreEqual(128 / 255.0, color3.B); + #region Constructors - Core.Color color4 = new Core.Color(0, 0, 0, 30); - Assert.AreEqual(30 / 255.0, color4.B); + [TestMethod] + public void RGBByteConstructorTest() + { + Core.Color color = new((byte)10, (byte)120, (byte)255); - Core.Color color5 = new Core.Color(0, 0, 0, 201); - Assert.AreEqual(201 / 255.0, color5.B); - } + Assert.AreEqual(255, color.GetA(), "A is not 255"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); + } + + [TestMethod] + public void ARGBByteConstructorTest() + { + Core.Color color = new((byte)200, (byte)10, (byte)120, (byte)255); - #endregion + Assert.AreEqual(200, color.GetA(), "A is not 200"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); } -} + + [TestMethod] + public void RGBIntConstructorTest() + { + Core.Color color = new(10, 120, 255); + + Assert.AreEqual(255, color.GetA(), "A is not 255"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); + } + + [TestMethod] + public void ARGBIntConstructorTest() + { + Core.Color color = new(200, 10, 120, 255); + + Assert.AreEqual(200, color.GetA(), "A is not 200"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); + } + + [TestMethod] + public void RGBIntConstructorClampTest() + { + Core.Color color1 = new(256, 256, 256); + + Assert.AreEqual(255, color1.GetA(), "A is not 255"); + Assert.AreEqual(255, color1.GetR(), "R is not 255"); + Assert.AreEqual(255, color1.GetG(), "G is not 255"); + Assert.AreEqual(255, color1.GetB(), "B is not 255"); + + Core.Color color2 = new(-1, -1, -1); + + Assert.AreEqual(255, color2.GetA(), "A is not 255"); + Assert.AreEqual(0, color2.GetR(), "R is not 0"); + Assert.AreEqual(0, color2.GetG(), "G is not 0"); + Assert.AreEqual(0, color2.GetB(), "B is not 0"); + } + + [TestMethod] + public void ARGBIntConstructorClampTest() + { + Core.Color color = new(256, 256, 256, 256); + + Assert.AreEqual(255, color.GetA(), "A is not 255"); + Assert.AreEqual(255, color.GetR(), "R is not 255"); + Assert.AreEqual(255, color.GetG(), "G is not 255"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); + + Core.Color color2 = new(-1, -1, -1, -1); + + Assert.AreEqual(0, color2.GetA(), "A is not 0"); + Assert.AreEqual(0, color2.GetR(), "R is not 0"); + Assert.AreEqual(0, color2.GetG(), "G is not 0"); + Assert.AreEqual(0, color2.GetB(), "B is not 0"); + } + + [TestMethod] + public void RGBPercentConstructorTest() + { + Core.Color color = new(0.25341f, 0.55367f, 1); + + Assert.AreEqual(1, color.A, FloatExtensions.TOLERANCE, "A is not 1"); + Assert.AreEqual(0.25341, color.R, FloatExtensions.TOLERANCE, "R is not 0.25341"); + Assert.AreEqual(0.55367, color.G, FloatExtensions.TOLERANCE, "G is not 0.55367"); + Assert.AreEqual(1, color.B, FloatExtensions.TOLERANCE, "B is not 1"); + } + + [TestMethod] + public void ARGBPercentConstructorTest() + { + Core.Color color = new(0.3315f, 0.25341f, 0.55367f, 1); + + Assert.AreEqual(0.3315f, color.A, FloatExtensions.TOLERANCE, "A is not 0.3315"); + Assert.AreEqual(0.25341f, color.R, FloatExtensions.TOLERANCE, "R is not 0.25341"); + Assert.AreEqual(0.55367f, color.G, FloatExtensions.TOLERANCE, "G is not 0.55367"); + Assert.AreEqual(1, color.B, FloatExtensions.TOLERANCE, "B is not 1"); + } + + [TestMethod] + public void RGBPercentConstructorClampTest() + { + Core.Color color1 = new(1.1f, 1.1f, 1.1f); + + Assert.AreEqual(1, color1.A, "A is not 1"); + Assert.AreEqual(1, color1.R, "R is not 1"); + Assert.AreEqual(1, color1.G, "G is not 1"); + Assert.AreEqual(1, color1.B, "B is not 1"); + + Core.Color color2 = new(-1.0f, -1.0f, -1.0f); + + Assert.AreEqual(1, color2.A, "A is not 1"); + Assert.AreEqual(0, color2.R, "R is not 0"); + Assert.AreEqual(0, color2.G, "G is not 0"); + Assert.AreEqual(0, color2.B, "B is not 0"); + } + + [TestMethod] + public void ARGBPercentConstructorClampTest() + { + Core.Color color1 = new(1.1f, 1.1f, 1.1f, 1.1f); + + Assert.AreEqual(1, color1.A, "A is not 1"); + Assert.AreEqual(1, color1.R, "R is not 1"); + Assert.AreEqual(1, color1.G, "G is not 1"); + Assert.AreEqual(1, color1.B, "B is not 1"); + + Core.Color color2 = new(-1.0f, -1.0f, -1.0f, -1.0f); + + Assert.AreEqual(0, color2.A, "A is not 0"); + Assert.AreEqual(0, color2.R, "R is not 0"); + Assert.AreEqual(0, color2.G, "G is not 0"); + Assert.AreEqual(0, color2.B, "B is not 0"); + } + + [TestMethod] + public void CloneConstructorTest() + { + Core.Color referennceColor = new(200, 10, 120, 255); + Core.Color color = new(referennceColor); + + Assert.AreEqual(200, color.GetA(), "A is not 200"); + Assert.AreEqual(10, color.GetR(), "R is not 10"); + Assert.AreEqual(120, color.GetG(), "G is not 120"); + Assert.AreEqual(255, color.GetB(), "B is not 255"); + } + + #endregion + + #region Conversion + + [TestMethod] + public void ColorFromComponentsTest() + { + Core.Color color = (255, 120, 13, 1); + + Assert.AreEqual(255, color.GetA(), $"A doesn't equal the used component. ({color.GetA()} != 255)"); + Assert.AreEqual(120, color.GetR(), $"R doesn't equal the used component. ({color.GetR()} != 120)"); + Assert.AreEqual(13, color.GetG(), $"G doesn't equal the used component. ({color.GetG()} != 13)"); + Assert.AreEqual(1, color.GetB(), $"B doesn't equal the used component. ({color.GetB()} != 1)"); + } + + [TestMethod] + public void DesconstructTest() + { + (byte a, byte r, byte g, byte b) = new Core.Color(255, 120, 13, 1).GetRGBBytes(); + + Assert.AreEqual(255, a, $"A doesn't equal the color. ({a} != 255)"); + Assert.AreEqual(120, r, $"R doesn't equal the color. ({r} != 120)"); + Assert.AreEqual(13, g, $"G doesn't equal the color. ({g} != 13)"); + Assert.AreEqual(1, b, $"B doesn't equal the color. ({b} != 1)"); + } + + [TestMethod] + public void AToPercentTest() + { + Core.Color color1 = new(0, 0, 0, 0); + Assert.AreEqual(0, color1.A); + + Core.Color color2 = new(255, 0, 0, 0); + Assert.AreEqual(1, color2.A); + + Core.Color color3 = new(128, 0, 0, 0); + Assert.AreEqual(128 / 256.0f, color3.A); + + Core.Color color4 = new(30, 0, 0, 0); + Assert.AreEqual(30 / 256.0f, color4.A); + + Core.Color color5 = new(201, 0, 0, 0); + Assert.AreEqual(201 / 256.0f, color5.A); + + Core.Color color6 = new(255, 0, 0, 0); + Assert.AreEqual(1f, color6.A); + } + + [TestMethod] + public void RToPercentTest() + { + Core.Color color1 = new(0, 0, 0, 0); + Assert.AreEqual(0, color1.R); + + Core.Color color2 = new(0, 255, 0, 0); + Assert.AreEqual(1, color2.R); + + Core.Color color3 = new(0, 128, 0, 0); + Assert.AreEqual(128 / 256.0f, color3.R); + + Core.Color color4 = new(0, 30, 0, 0); + Assert.AreEqual(30 / 256.0f, color4.R); + + Core.Color color5 = new(0, 201, 0, 0); + Assert.AreEqual(201 / 256.0f, color5.R); + + Core.Color color6 = new(0, 255, 0, 0); + Assert.AreEqual(1f, color6.R); + } + + [TestMethod] + public void GToPercentTest() + { + Core.Color color1 = new(0, 0, 0, 0); + Assert.AreEqual(0, color1.G); + + Core.Color color2 = new(0, 0, 255, 0); + Assert.AreEqual(1, color2.G); + + Core.Color color3 = new(0, 0, 128, 0); + Assert.AreEqual(128 / 256.0f, color3.G); + + Core.Color color4 = new(0, 0, 30, 0); + Assert.AreEqual(30 / 256.0f, color4.G); + + Core.Color color5 = new(0, 0, 201, 0); + Assert.AreEqual(201 / 256.0f, color5.G); + + Core.Color color6 = new(0, 0, 255, 0); + Assert.AreEqual(1f, color6.G); + } + + [TestMethod] + public void BToPercentTest() + { + Core.Color color1 = new(0, 0, 0, 0); + Assert.AreEqual(0, color1.B); + + Core.Color color2 = new(0, 0, 0, 255); + Assert.AreEqual(1, color2.B); + + Core.Color color3 = new(0, 0, 0, 128); + Assert.AreEqual(128 / 256.0f, color3.B); + + Core.Color color4 = new(0, 0, 0, 30); + Assert.AreEqual(30 / 256.0f, color4.B); + + Core.Color color5 = new(0, 0, 0, 201); + Assert.AreEqual(201 / 256.0f, color5.B); + + Core.Color color6 = new(0, 0, 0, 255); + Assert.AreEqual(1f, color6.B); + } + + #endregion +} \ No newline at end of file diff --git a/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs index 823a2031..ab0697fa 100644 --- a/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs +++ b/Tests/RGB.NET.Core.Tests/Color/HSVColorTest.cs @@ -1,284 +1,283 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace RGB.NET.Core.Tests.Color +namespace RGB.NET.Core.Tests.Color; + +[TestClass] +public class HSVColorTest { - [TestClass] - public class HSVColorTest - { - #region Manipulation + #region Manipulation - #region Add + #region Add - [TestMethod] - public void AddHueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.AddHSV(hue: 30); + [TestMethod] + public void AddHueTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.AddHSV(hue: 30); - Assert.AreEqual(HSVColor.Create(210, 0.5, 0.5), result); - } - - [TestMethod] - public void AddHueWrapTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.AddHSV(hue: 220); - - Assert.AreEqual(HSVColor.Create(40, 0.5, 0.5), result); - } - - [TestMethod] - public void AddSaturationTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.AddHSV(saturation: 0.3); - - Assert.AreEqual(HSVColor.Create(180, 0.8, 0.5), result); - } - - [TestMethod] - public void AddSaturationClampTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.AddHSV(saturation: 0.8); - - Assert.AreEqual(HSVColor.Create(180, 1.0, 0.5), result); - } - - [TestMethod] - public void AddValueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.AddHSV(value: 0.3); - - Assert.AreEqual(HSVColor.Create(180, 0.5, 0.8), result); - } - - [TestMethod] - public void AddValueClampTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.AddHSV(value: 0.8); - - Assert.AreEqual(HSVColor.Create(180, 0.5, 1.0), result); - } - - #endregion - - #region Subtract - - [TestMethod] - public void SubtractHueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractHSV(hue: 30); - - Assert.AreEqual(HSVColor.Create(150, 0.5, 0.5), result); - } - - [TestMethod] - public void SubtractHueWrapTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractHSV(hue: 220); - - Assert.AreEqual(HSVColor.Create(320, 0.5, 0.5), result); - } - - [TestMethod] - public void SubtractSaturationTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractHSV(saturation: 0.3); - - Assert.AreEqual(HSVColor.Create(180, 0.2, 0.5), result); - } - - [TestMethod] - public void SubtractSaturationClampTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractHSV(saturation: 0.8); - - Assert.AreEqual(HSVColor.Create(180, 0, 0.5), result); - } - - [TestMethod] - public void SubtractValueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractHSV(value: 0.3); - - Assert.AreEqual(HSVColor.Create(180, 0.5, 0.2), result); - } - - [TestMethod] - public void SubtractValueClampTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SubtractHSV(value: .8); - - Assert.AreEqual(HSVColor.Create(180, 0.5, 0), result); - } - - #endregion + Assert.AreEqual(HSVColor.Create(210, 0.5f, 0.5f), result); + } + + [TestMethod] + public void AddHueWrapTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.AddHSV(hue: 220); + + Assert.AreEqual(HSVColor.Create(40, 0.5f, 0.5f), result); + } + + [TestMethod] + public void AddSaturationTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.AddHSV(saturation: 0.3f); + + Assert.AreEqual(HSVColor.Create(180, 0.8f, 0.5f), result); + } + + [TestMethod] + public void AddSaturationClampTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.AddHSV(saturation: 0.8f); + + Assert.AreEqual(HSVColor.Create(180, 1.0f, 0.5f), result); + } + + [TestMethod] + public void AddValueTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.AddHSV(value: 0.3f); + + Assert.AreEqual(HSVColor.Create(180, 0.5f, 0.8f), result); + } + + [TestMethod] + public void AddValueClampTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.AddHSV(value: 0.8f); + + Assert.AreEqual(HSVColor.Create(180, 0.5f, 1.0f), result); + } + + #endregion + + #region Subtract - #region Multiply - - [TestMethod] - public void MultiplyHueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.MultiplyHSV(hue: 1.5); - - Assert.AreEqual(HSVColor.Create(270, 0.5, 0.5), result); - } - - [TestMethod] - public void MultiplyHueWrapTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.MultiplyHSV(hue: 3); - - Assert.AreEqual(HSVColor.Create(180, 0.5, 0.5), result); - } - - [TestMethod] - public void MultiplySaturationTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.2, 0.2); - Core.Color result = baseColor.MultiplyHSV(saturation: 3); - - Assert.AreEqual(HSVColor.Create(180, 0.6, 0.2), result); - } - - [TestMethod] - public void MultiplySaturationClampTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.MultiplyHSV(saturation: 3); - - Assert.AreEqual(HSVColor.Create(180, 1.0, 0.5), result); - } - - [TestMethod] - public void MultiplyValueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.2, 0.2); - Core.Color result = baseColor.MultiplyHSV(value: 3); - - Assert.AreEqual(HSVColor.Create(180, 0.2, 0.6), result); - } - - [TestMethod] - public void MultiplyValueClampTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.MultiplyHSV(value: 3); - - Assert.AreEqual(HSVColor.Create(180, 0.5, 1.0), result); - } - - #endregion - - #region Divide - - [TestMethod] - public void DivideHueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.DivideHSV(hue: 30); - - Assert.AreEqual(HSVColor.Create(6, 0.5, 0.5), result); - } - - [TestMethod] - public void DivideSaturationTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.6, 0.6); - Core.Color result = baseColor.DivideHSV(saturation: 2); + [TestMethod] + public void SubtractHueTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractHSV(hue: 30); - Assert.AreEqual(HSVColor.Create(180, 0.3, 0.6), result); - } - - [TestMethod] - public void DivideValueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.6, 0.6); - Core.Color result = baseColor.DivideHSV(value: 2); + Assert.AreEqual(HSVColor.Create(150, 0.5f, 0.5f), result); + } - Assert.AreEqual(HSVColor.Create(180, 0.6, 0.3), result); - } + [TestMethod] + public void SubtractHueWrapTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractHSV(hue: 220); - #endregion + Assert.AreEqual(HSVColor.Create(320, 0.5f, 0.5f), result); + } - #region Set + [TestMethod] + public void SubtractSaturationTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractHSV(saturation: 0.3f); + + Assert.AreEqual(HSVColor.Create(180, 0.2f, 0.5f), result); + } + + [TestMethod] + public void SubtractSaturationClampTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractHSV(saturation: 0.8f); + + Assert.AreEqual(HSVColor.Create(180, 0, 0.5f), result); + } + + [TestMethod] + public void SubtractValueTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractHSV(value: 0.3f); - [TestMethod] - public void SetHueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SetHSV(hue: 30); + Assert.AreEqual(HSVColor.Create(180, 0.5f, 0.2f), result); + } - Assert.AreEqual(HSVColor.Create(30, 0.5, 0.5), result); - } + [TestMethod] + public void SubtractValueClampTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractHSV(value: 0.8f); - [TestMethod] - public void SetHueWrapTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SetHSV(hue: 440); - - Assert.AreEqual(HSVColor.Create(80, 0.5, 0.5), result); - } - - [TestMethod] - public void SetHueWrapNegativeTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SetHSV(hue: -30); + Assert.AreEqual(HSVColor.Create(180, 0.5f, 0), result); + } - Assert.AreEqual(HSVColor.Create(330, 0.5, 0.5), result); - } - - [TestMethod] - public void SetSaturationTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SetHSV(saturation: 0.3); + #endregion - Assert.AreEqual(HSVColor.Create(180, 0.3, 0.5), result); - } + #region Multiply - [TestMethod] - public void SetSaturationClampTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SetHSV(saturation: 2); + [TestMethod] + public void MultiplyHueTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.MultiplyHSV(hue: 1.5f); - Assert.AreEqual(HSVColor.Create(180, 1.0, 0.5), result); - } + Assert.AreEqual(HSVColor.Create(270, 0.5f, 0.5f), result); + } - [TestMethod] - public void SetValueTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SetHSV(value: 0.3); + [TestMethod] + public void MultiplyHueWrapTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.MultiplyHSV(hue: 3); - Assert.AreEqual(HSVColor.Create(180, 0.5, 0.3), result); - } + Assert.AreEqual(HSVColor.Create(180, 0.5f, 0.5f), result); + } - [TestMethod] - public void SetValueClampTest() - { - Core.Color baseColor = HSVColor.Create(180, 0.5, 0.5); - Core.Color result = baseColor.SetHSV(value: 2); + [TestMethod] + public void MultiplySaturationTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.2f, 0.2f); + Core.Color result = baseColor.MultiplyHSV(saturation: 3); - Assert.AreEqual(HSVColor.Create(180, 0.5, 1.0), result); - } + Assert.AreEqual(HSVColor.Create(180,0.6f, 0.2f), result); + } - #endregion + [TestMethod] + public void MultiplySaturationClampTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.MultiplyHSV(saturation: 3); - #endregion + Assert.AreEqual(HSVColor.Create(180, 1.0f, 0.5f), result); } -} + + [TestMethod] + public void MultiplyValueTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.2f, 0.2f); + Core.Color result = baseColor.MultiplyHSV(value: 3); + + Assert.AreEqual(HSVColor.Create(180, 0.2f,0.6f), result); + } + + [TestMethod] + public void MultiplyValueClampTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.MultiplyHSV(value: 3); + + Assert.AreEqual(HSVColor.Create(180, 0.5f, 1.0f), result); + } + + #endregion + + #region Divide + + [TestMethod] + public void DivideHueTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.DivideHSV(hue: 30); + + Assert.AreEqual(HSVColor.Create(6, 0.5f, 0.5f), result); + } + + [TestMethod] + public void DivideSaturationTest() + { + Core.Color baseColor = HSVColor.Create(180,0.6f,0.6f); + Core.Color result = baseColor.DivideHSV(saturation: 2); + + Assert.AreEqual(HSVColor.Create(180, 0.3f,0.6f), result); + } + + [TestMethod] + public void DivideValueTest() + { + Core.Color baseColor = HSVColor.Create(180,0.6f,0.6f); + Core.Color result = baseColor.DivideHSV(value: 2); + + Assert.AreEqual(HSVColor.Create(180,0.6f, 0.3f), result); + } + + #endregion + + #region Set + + [TestMethod] + public void SetHueTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SetHSV(hue: 30); + + Assert.AreEqual(HSVColor.Create(30, 0.5f, 0.5f), result); + } + + [TestMethod] + public void SetHueWrapTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SetHSV(hue: 440); + + Assert.AreEqual(HSVColor.Create(80, 0.5f, 0.5f), result); + } + + [TestMethod] + public void SetHueWrapNegativeTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SetHSV(hue: -30); + + Assert.AreEqual(HSVColor.Create(330, 0.5f, 0.5f), result); + } + + [TestMethod] + public void SetSaturationTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SetHSV(saturation: 0.3f); + + Assert.AreEqual(HSVColor.Create(180, 0.3f, 0.5f), result); + } + + [TestMethod] + public void SetSaturationClampTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SetHSV(saturation: 2); + + Assert.AreEqual(HSVColor.Create(180, 1.0f, 0.5f), result); + } + + [TestMethod] + public void SetValueTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SetHSV(value: 0.3f); + + Assert.AreEqual(HSVColor.Create(180, 0.5f, 0.3f), result); + } + + [TestMethod] + public void SetValueClampTest() + { + Core.Color baseColor = HSVColor.Create(180, 0.5f, 0.5f); + Core.Color result = baseColor.SetHSV(value: 2); + + Assert.AreEqual(HSVColor.Create(180, 0.5f, 1.0f), result); + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs index 26244448..1a57a474 100644 --- a/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs +++ b/Tests/RGB.NET.Core.Tests/Color/RGBColorTest.cs @@ -1,432 +1,431 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace RGB.NET.Core.Tests.Color +namespace RGB.NET.Core.Tests.Color; + +[TestClass] +public class RGBColorTest { - [TestClass] - public class RGBColorTest + #region Manipulation + + #region Blend + + [TestMethod] + public void BlendOpaqueTest() + { + Core.Color baseColor = new(255, 0, 0); + Core.Color blendColor = new(0, 255, 0); + + Assert.AreEqual(blendColor, baseColor.Blend(blendColor)); + } + + [TestMethod] + public void BlendTransparentTest() + { + Core.Color baseColor = new(255, 0, 0); + Core.Color blendColor = new(0, 0, 255, 0); + + Assert.AreEqual(baseColor, baseColor.Blend(blendColor)); + } + + [TestMethod] + public void BlendUpTest() + { + Core.Color baseColor = new(0.0f, 0.0f, 0.0f); + Core.Color blendColor = new(0.5f, 1.0f, 1.0f, 1.0f); + + Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f), baseColor.Blend(blendColor)); + } + + [TestMethod] + public void BlendDownTest() + { + Core.Color baseColor = new(1.0f, 1.0f, 1.0f); + Core.Color blendColor = new(0.5f, 0.0f, 0.0f, 0.0f); + + Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f), baseColor.Blend(blendColor)); + } + + #endregion + + #region Add + + [TestMethod] + public void AddRGBTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.AddRGB(11, 12, 13); + + Assert.AreEqual(new Core.Color(128, 139, 140, 141), result); + } + + [TestMethod] + public void AddRGBPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.AddRGB(0.2f, 0.3f, 0.4f); + + Assert.AreEqual(new Core.Color(0.5f, 0.7f, 0.8f, 0.9f), result); + } + + [TestMethod] + public void AddATest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.AddA(10); + + Assert.AreEqual(new Core.Color(138, 128, 128, 128), result); + } + + [TestMethod] + public void AddAPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.AddA(0.1f); + + Assert.AreEqual(new Core.Color(0.6f, 0.5f, 0.5f, 0.5f), result); + } + + [TestMethod] + public void AddRTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.AddRGB(r: 10); + + Assert.AreEqual(new Core.Color(128, 138, 128, 128), result); + } + + [TestMethod] + public void AddRPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.AddRGB(r: 0.1f); + + Assert.AreEqual(new Core.Color(0.5f, 0.6f, 0.5f, 0.5f), result); + } + + [TestMethod] + public void AddGTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.AddRGB(g: 10); + + Assert.AreEqual(new Core.Color(128, 128, 138, 128), result); + } + + [TestMethod] + public void AddGPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.AddRGB(g: 0.1f); + + Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.6f, 0.5f), result); + } + + [TestMethod] + public void AddBTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.AddRGB(b: 10); + + Assert.AreEqual(new Core.Color(128, 128, 128, 138), result); + } + + [TestMethod] + public void AddBPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.AddRGB(b: 0.1f); + + Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f, 0.6f), result); + } + + #endregion + + #region Substract + + [TestMethod] + public void SubtractRGBTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SubtractRGB(11, 12, 13); + + Assert.AreEqual(new Core.Color(128, 117, 116, 115), result); + } + + [TestMethod] + public void SubtractRGBPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractRGB(0.2f, 0.3f, 0.4f); + + Assert.AreEqual(new Core.Color(0.5f, 0.3f, 0.2f, 0.1f), result); + } + + [TestMethod] + public void SubtractATest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SubtractA(10); + + Assert.AreEqual(new Core.Color(118, 128, 128, 128), result); + } + + [TestMethod] + public void SubtractAPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractA(0.1f); + + Assert.AreEqual(new Core.Color(0.4f, 0.5f, 0.5f, 0.5f), result); + } + + [TestMethod] + public void SubtractRTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SubtractRGB(r: 10); + + Assert.AreEqual(new Core.Color(128, 118, 128, 128), result); + } + + [TestMethod] + public void SubtractRPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractRGB(r: 0.1f); + + Assert.AreEqual(new Core.Color(0.5f, 0.4f, 0.5f, 0.5f), result); + } + + [TestMethod] + public void SubtractGTest() { - #region Manipulation - - #region Blend + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SubtractRGB(g: 10); - [TestMethod] - public void BlendOpaqueTest() - { - Core.Color baseColor = new Core.Color(255, 0, 0); - Core.Color blendColor = new Core.Color(0, 255, 0); - - Assert.AreEqual(blendColor, baseColor.Blend(blendColor)); - } - - [TestMethod] - public void BlendTransparentTest() - { - Core.Color baseColor = new Core.Color(255, 0, 0); - Core.Color blendColor = new Core.Color(0, 0, 255, 0); - - Assert.AreEqual(baseColor, baseColor.Blend(blendColor)); - } - - [TestMethod] - public void BlendUpTest() - { - Core.Color baseColor = new Core.Color(0.0, 0.0, 0.0); - Core.Color blendColor = new Core.Color(0.5, 1.0, 1.0, 1.0); - - Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5), baseColor.Blend(blendColor)); - } - - [TestMethod] - public void BlendDownTest() - { - Core.Color baseColor = new Core.Color(1.0, 1.0, 1.0); - Core.Color blendColor = new Core.Color(0.5, 0.0, 0.0, 0.0); - - Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5), baseColor.Blend(blendColor)); - } + Assert.AreEqual(new Core.Color(128, 128, 118, 128), result); + } + + [TestMethod] + public void SubtractGPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractRGB(g: 0.1f); + + Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.4f, 0.5f), result); + } + + [TestMethod] + public void SubtractBTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SubtractRGB(b: 10); + + Assert.AreEqual(new Core.Color(128, 128, 128, 118), result); + } + + [TestMethod] + public void SubtractBPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SubtractRGB(b: 0.1f); + + Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f, 0.4f), result); + } + + #endregion + + #region Multiply + + [TestMethod] + public void MultiplyRGBPercentTest() + { + Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f); + Core.Color result = baseColor.MultiplyRGB(3, 4, 5); + + Assert.AreEqual(new Core.Color(0.2f, 0.6f, 0.8f, 1.0f), result); + } + + [TestMethod] + public void MultiplyAPercentTest() + { + Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f); + Core.Color result = baseColor.MultiplyA(3); + + Assert.AreEqual(new Core.Color(0.6f, 0.2f, 0.2f, 0.2f), result); + } + + [TestMethod] + public void MultiplyRPercentTest() + { + Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f); + Core.Color result = baseColor.MultiplyRGB(r: 3); + + Assert.AreEqual(new Core.Color(0.2f, 0.6f, 0.2f, 0.2f), result); + } + + [TestMethod] + public void MultiplyGPercentTest() + { + Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f); + Core.Color result = baseColor.MultiplyRGB(g: 3); + + Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.6f, 0.2f), result); + } + + [TestMethod] + public void MultiplyBPercentTest() + { + Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.2f); + Core.Color result = baseColor.MultiplyRGB(b: 3); - #endregion - - #region Add + Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.6f), result); + } - [TestMethod] - public void AddRGBTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.AddRGB(11, 12, 13); - - Assert.AreEqual(new Core.Color(128, 139, 140, 141), result); - } - - [TestMethod] - public void AddRGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddRGB(0.2, 0.3, 0.4); - - Assert.AreEqual(new Core.Color(0.5, 0.7, 0.8, 0.9), result); - } - - [TestMethod] - public void AddATest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.AddA(10); - - Assert.AreEqual(new Core.Color(138, 128, 128, 128), result); - } - - [TestMethod] - public void AddAPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddA(0.1); - - Assert.AreEqual(new Core.Color(0.6, 0.5, 0.5, 0.5), result); - } - - [TestMethod] - public void AddRTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.AddRGB(r: 10); - - Assert.AreEqual(new Core.Color(128, 138, 128, 128), result); - } - - [TestMethod] - public void AddRPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddRGB(r: 0.1); - - Assert.AreEqual(new Core.Color(0.5, 0.6, 0.5, 0.5), result); - } - - [TestMethod] - public void AddGTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.AddRGB(g: 10); - - Assert.AreEqual(new Core.Color(128, 128, 138, 128), result); - } - - [TestMethod] - public void AddGPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddRGB(g: 0.1); - - Assert.AreEqual(new Core.Color(0.5, 0.5, 0.6, 0.5), result); - } - - [TestMethod] - public void AddBTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.AddRGB(b: 10); - - Assert.AreEqual(new Core.Color(128, 128, 128, 138), result); - } - - [TestMethod] - public void AddBPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.AddRGB(b: 0.1); - - Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.6), result); - } - - #endregion - - #region Substract - - [TestMethod] - public void SubtractRGBTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SubtractRGB(11, 12, 13); - - Assert.AreEqual(new Core.Color(128, 117, 116, 115), result); - } - - [TestMethod] - public void SubtractRGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractRGB(0.2, 0.3, 0.4); - - Assert.AreEqual(new Core.Color(0.5, 0.3, 0.2, 0.1), result); - } - - [TestMethod] - public void SubtractATest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SubtractA(10); - - Assert.AreEqual(new Core.Color(118, 128, 128, 128), result); - } - - [TestMethod] - public void SubtractAPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractA(0.1); - - Assert.AreEqual(new Core.Color(0.4, 0.5, 0.5, 0.5), result); - } - - [TestMethod] - public void SubtractRTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SubtractRGB(r: 10); - - Assert.AreEqual(new Core.Color(128, 118, 128, 128), result); - } - - [TestMethod] - public void SubtractRPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractRGB(r: 0.1); - - Assert.AreEqual(new Core.Color(0.5, 0.4, 0.5, 0.5), result); - } - - [TestMethod] - public void SubtractGTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SubtractRGB(g: 10); - - Assert.AreEqual(new Core.Color(128, 128, 118, 128), result); - } - - [TestMethod] - public void SubtractGPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractRGB(g: 0.1); - - Assert.AreEqual(new Core.Color(0.5, 0.5, 0.4, 0.5), result); - } - - [TestMethod] - public void SubtractBTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SubtractRGB(b: 10); - - Assert.AreEqual(new Core.Color(128, 128, 128, 118), result); - } - - [TestMethod] - public void SubtractBPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SubtractRGB(b: 0.1); - - Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.4), result); - } - - #endregion + #endregion - #region Multiply - - [TestMethod] - public void MultiplyRGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyRGB(3, 4, 5); - - Assert.AreEqual(new Core.Color(0.2, 0.6, 0.8, 1.0), result); - } - - [TestMethod] - public void MultiplyAPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyA(3); - - Assert.AreEqual(new Core.Color(0.6, 0.2, 0.2, 0.2), result); - } - - [TestMethod] - public void MultiplyRPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyRGB(r: 3); - - Assert.AreEqual(new Core.Color(0.2, 0.6, 0.2, 0.2), result); - } - - [TestMethod] - public void MultiplyGPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyRGB(g: 3); - - Assert.AreEqual(new Core.Color(0.2, 0.2, 0.6, 0.2), result); - } - - [TestMethod] - public void MultiplyBPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.2); - Core.Color result = baseColor.MultiplyRGB(b: 3); - - Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.6), result); - } - - #endregion - - #region Divide - - [TestMethod] - public void DivideRGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.6, 0.8, 1.0); - Core.Color result = baseColor.DivideRGB(3, 4, 5); - - Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); - } - - [TestMethod] - public void DivideAPercentTest() - { - Core.Color baseColor = new Core.Color(0.6, 0.2, 0.2, 0.2); - Core.Color result = baseColor.DivideA(3); - - Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); - } - - [TestMethod] - public void DivideRPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.6, 0.2, 0.2); - Core.Color result = baseColor.DivideRGB(r: 3); - - Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); - } - - [TestMethod] - public void DivideGPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.6, 0.2); - Core.Color result = baseColor.DivideRGB(g: 3); - - Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); - } - - [TestMethod] - public void DivideBPercentTest() - { - Core.Color baseColor = new Core.Color(0.2, 0.2, 0.2, 0.6); - Core.Color result = baseColor.DivideRGB(b: 3); - - Assert.AreEqual(new Core.Color(0.2, 0.2, 0.2, 0.2), result); - } - - #endregion + #region Divide - #region Set - - [TestMethod] - public void SetRGBTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetRGB(11, 12, 13); - - Assert.AreEqual(new Core.Color(128, 11, 12, 13), result); - } - - [TestMethod] - public void SetRGBPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetRGB(0.2, 0.3, 0.4); - - Assert.AreEqual(new Core.Color(0.5, 0.2, 0.3, 0.4), result); - } - - [TestMethod] - public void SetATest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetA(10); - - Assert.AreEqual(new Core.Color(10, 128, 128, 128), result); - } - - [TestMethod] - public void SetAPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetA(0.1); + [TestMethod] + public void DivideRGBPercentTest() + { + Core.Color baseColor = new(0.2f, 0.6f, 0.8f, 1.0f); + Core.Color result = baseColor.DivideRGB(3, 4, 5); - Assert.AreEqual(new Core.Color(0.1, 0.5, 0.5, 0.5), result); - } - - [TestMethod] - public void SetRTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetRGB(r: 10); + Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result); + } - Assert.AreEqual(new Core.Color(128, 10, 128, 128), result); - } + [TestMethod] + public void DivideAPercentTest() + { + Core.Color baseColor = new(0.6f, 0.2f, 0.2f, 0.2f); + Core.Color result = baseColor.DivideA(3); - [TestMethod] - public void SetRPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetRGB(r: 0.1); - - Assert.AreEqual(new Core.Color(0.5, 0.1, 0.5, 0.5), result); - } - - [TestMethod] - public void SetGTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetRGB(g: 10); - - Assert.AreEqual(new Core.Color(128, 128, 10, 128), result); - } - - [TestMethod] - public void SetGPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetRGB(g: 0.1); + Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result); + } - Assert.AreEqual(new Core.Color(0.5, 0.5, 0.1, 0.5), result); - } - - [TestMethod] - public void SetBTest() - { - Core.Color baseColor = new Core.Color(128, 128, 128, 128); - Core.Color result = baseColor.SetRGB(b: 10); + [TestMethod] + public void DivideRPercentTest() + { + Core.Color baseColor = new(0.2f, 0.6f, 0.2f, 0.2f); + Core.Color result = baseColor.DivideRGB(r: 3); - Assert.AreEqual(new Core.Color(128, 128, 128, 10), result); - } + Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result); + } - [TestMethod] - public void SetBPercentTest() - { - Core.Color baseColor = new Core.Color(0.5, 0.5, 0.5, 0.5); - Core.Color result = baseColor.SetRGB(b: 0.1); + [TestMethod] + public void DivideGPercentTest() + { + Core.Color baseColor = new(0.2f, 0.2f, 0.6f, 0.2f); + Core.Color result = baseColor.DivideRGB(g: 3); - Assert.AreEqual(new Core.Color(0.5, 0.5, 0.5, 0.1), result); - } + Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result); + } - #endregion + [TestMethod] + public void DivideBPercentTest() + { + Core.Color baseColor = new(0.2f, 0.2f, 0.2f, 0.6f); + Core.Color result = baseColor.DivideRGB(b: 3); - #endregion + Assert.AreEqual(new Core.Color(0.2f, 0.2f, 0.2f, 0.2f), result); } -} + + #endregion + + #region Set + + [TestMethod] + public void SetRGBTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SetRGB(11, 12, 13); + + Assert.AreEqual(new Core.Color(128, 11, 12, 13), result); + } + + [TestMethod] + public void SetRGBPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SetRGB(0.2f, 0.3f, 0.4f); + + Assert.AreEqual(new Core.Color(0.5f, 0.2f, 0.3f, 0.4f), result); + } + + [TestMethod] + public void SetATest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SetA(10); + + Assert.AreEqual(new Core.Color(10, 128, 128, 128), result); + } + + [TestMethod] + public void SetAPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SetA(0.1f); + + Assert.AreEqual(new Core.Color(0.1f, 0.5f, 0.5f, 0.5f), result); + } + + [TestMethod] + public void SetRTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SetRGB(r: 10); + + Assert.AreEqual(new Core.Color(128, 10, 128, 128), result); + } + + [TestMethod] + public void SetRPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SetRGB(r: 0.1f); + + Assert.AreEqual(new Core.Color(0.5f, 0.1f, 0.5f, 0.5f), result); + } + + [TestMethod] + public void SetGTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SetRGB(g: 10); + + Assert.AreEqual(new Core.Color(128, 128, 10, 128), result); + } + + [TestMethod] + public void SetGPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SetRGB(g: 0.1f); + + Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.1f, 0.5f), result); + } + + [TestMethod] + public void SetBTest() + { + Core.Color baseColor = new(128, 128, 128, 128); + Core.Color result = baseColor.SetRGB(b: 10); + + Assert.AreEqual(new Core.Color(128, 128, 128, 10), result); + } + + [TestMethod] + public void SetBPercentTest() + { + Core.Color baseColor = new(0.5f, 0.5f, 0.5f, 0.5f); + Core.Color result = baseColor.SetRGB(b: 0.1f); + + Assert.AreEqual(new Core.Color(0.5f, 0.5f, 0.5f, 0.1f), result); + } + + #endregion + + #endregion +} \ No newline at end of file diff --git a/Tests/RGB.NET.Core.Tests/RGB.NET.Core.Tests.csproj b/Tests/RGB.NET.Core.Tests/RGB.NET.Core.Tests.csproj index 1a1ca5b7..0279d53f 100644 --- a/Tests/RGB.NET.Core.Tests/RGB.NET.Core.Tests.csproj +++ b/Tests/RGB.NET.Core.Tests/RGB.NET.Core.Tests.csproj @@ -1,15 +1,15 @@ - netcoreapp2.2 + net7.0 false - - - + + + diff --git a/Tests/RGB.NET.Core.Tests/Sampler/AverageColorSamplerTest.cs b/Tests/RGB.NET.Core.Tests/Sampler/AverageColorSamplerTest.cs new file mode 100644 index 00000000..99398ec7 --- /dev/null +++ b/Tests/RGB.NET.Core.Tests/Sampler/AverageColorSamplerTest.cs @@ -0,0 +1,85 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace RGB.NET.Core.Tests.Sampler; + +[TestClass] +public class AverageColorSamplerTest +{ + #region Methods + + [TestMethod] + public void WhiteTest() + { + Span data = new Core.Color[16 * 16]; + data.Fill(new Core.Color(1f, 1f, 1f, 1f)); + Core.Color[] result = new Core.Color[1]; + + SamplerInfo info = new(2, 3, data[..6]); + new AverageColorSampler().Sample(info, result); + Assert.AreEqual(new Core.Color(1f, 1f, 1f, 1f), result[0]); + + info = new SamplerInfo(16, 16, data); + new AverageColorSampler().Sample(info, result); + Assert.AreEqual(new Core.Color(1f, 1f, 1f, 1f), result[0]); + } + + [TestMethod] + public void BlackTest() + { + Span data = new Core.Color[16 * 16]; + data.Fill(new Core.Color(1f, 0f, 0f, 0f)); + Core.Color[] result = new Core.Color[1]; + + SamplerInfo info = new(2, 3, data[..6]); + new AverageColorSampler().Sample(info, result); + Assert.AreEqual(new Core.Color(1f, 0f, 0f, 0f), result[0]); + + info = new SamplerInfo(16, 16, data); + new AverageColorSampler().Sample(info, result); + Assert.AreEqual(new Core.Color(1f, 0f, 0f, 0f), result[0]); + } + + [TestMethod] + public void GrayTest() + { + Span data = new Core.Color[16 * 16]; + for (int i = 0; i < data.Length; i++) + data[i] = (i % 2) == 0 ? new Core.Color(1f, 0f, 0f, 0f) : new Core.Color(1f, 1f, 1f, 1f); + Core.Color[] result = new Core.Color[1]; + + SamplerInfo info = new(2, 3, data[..6]); + new AverageColorSampler().Sample(info, result); + Assert.AreEqual(new Core.Color(1f, 0.5f, 0.5f, 0.5f), result[0]); + + info = new SamplerInfo(16, 16, data); + new AverageColorSampler().Sample(info, result); + Assert.AreEqual(new Core.Color(1f, 0.5f, 0.5f, 0.5f), result[0]); + } + + [TestMethod] + public void MixedTest() + { + Core.Color[] data = new Core.Color[16 * 16]; + for (int i = 0; i < data.Length; i++) + data[i] = (i % 5) switch + { + 0 => new Core.Color(1f, 1f, 0f, 0f), + 1 => new Core.Color(1f, 0f, 0.75f, 0f), + 2 => new Core.Color(0.5f, 0f, 0f, 0.5f), + 3 => new Core.Color(0f, 1f, 1f, 1f), + _ => new Core.Color(0f, 0f, 0f, 0f), + }; + Core.Color[] result = new Core.Color[1]; + + SamplerInfo info = new(2, 3, data[..6]); + new AverageColorSampler().Sample(info, result); + Assert.AreEqual(new Core.Color(0.5833333f, 0.5f, 0.291666657f, 0.25f), result[0]); + + info = new SamplerInfo(16, 16, data); + new AverageColorSampler().Sample(info, result); + Assert.AreEqual(new Core.Color(0.5019531f, 0.40234375f, 0.3486328f, 0.298828125f), result[0]); + } + + #endregion +} \ No newline at end of file diff --git a/Tests/RGB.NET.Presets.Tests/RGB.NET.Presets.Tests.csproj b/Tests/RGB.NET.Presets.Tests/RGB.NET.Presets.Tests.csproj new file mode 100644 index 00000000..57777390 --- /dev/null +++ b/Tests/RGB.NET.Presets.Tests/RGB.NET.Presets.Tests.csproj @@ -0,0 +1,20 @@ + + + + net7.0 + + false + + + + + + + + + + + + + + diff --git a/Tests/RGB.NET.Presets.Tests/Sampler/AverageByteSamplerTest.cs b/Tests/RGB.NET.Presets.Tests/Sampler/AverageByteSamplerTest.cs new file mode 100644 index 00000000..34a1e344 --- /dev/null +++ b/Tests/RGB.NET.Presets.Tests/Sampler/AverageByteSamplerTest.cs @@ -0,0 +1,127 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using RGB.NET.Core; +using RGB.NET.Presets.Textures.Sampler; + +namespace RGB.NET.Presets.Tests.Sampler; + +[TestClass] +public class AverageByteSamplerTest +{ + #region Methods + + [TestMethod] + public void WhiteTest() + { + Span colorData = new Color[16 * 16]; + colorData.Fill(new Color(1f, 1f, 1f, 1f)); + byte[] result = new byte[4]; + + Span data = new byte[colorData.Length * 4]; + int index = 0; + for (int i = 0; i < colorData.Length; i++) + { + data[index++] = colorData[i].GetA(); + data[index++] = colorData[i].GetR(); + data[index++] = colorData[i].GetG(); + data[index++] = colorData[i].GetB(); + } + + SamplerInfo info = new(2, 3, data[..(6 * 4)]); + new AverageByteSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 1f, 1f, 1f), new Color(result[0], result[1], result[2], result[3])); + + info = new SamplerInfo(16, 16, data); + new AverageByteSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 1f, 1f, 1f), new Color(result[0], result[1], result[2], result[3])); + } + + [TestMethod] + public void BlackTest() + { + Span colorData = new Color[16 * 16]; + colorData.Fill(new Color(1f, 0f, 0f, 0f)); + byte[] result = new byte[4]; + + Span data = new byte[colorData.Length * 4]; + int index = 0; + for (int i = 0; i < colorData.Length; i++) + { + data[index++] = colorData[i].GetA(); + data[index++] = colorData[i].GetR(); + data[index++] = colorData[i].GetG(); + data[index++] = colorData[i].GetB(); + } + + SamplerInfo info = new(2, 3, data[..(6 * 4)]); + new AverageByteSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 0f, 0f, 0f), new Color(result[0], result[1], result[2], result[3])); + + info = new SamplerInfo(16, 16, data); + new AverageByteSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 0f, 0f, 0f), new Color(result[0], result[1], result[2], result[3])); + } + + [TestMethod] + public void GrayTest() + { + Span colorData = new Color[16 * 16]; + for (int i = 0; i < colorData.Length; i++) + colorData[i] = (i % 2) == 0 ? new Color(1f, 0f, 0f, 0f) : new Color(1f, 1f, 1f, 1f); + byte[] result = new byte[4]; + + Span data = new byte[colorData.Length * 4]; + int index = 0; + for (int i = 0; i < colorData.Length; i++) + { + data[index++] = colorData[i].GetA(); + data[index++] = colorData[i].GetR(); + data[index++] = colorData[i].GetG(); + data[index++] = colorData[i].GetB(); + } + + SamplerInfo info = new(2, 3, data[..(6 * 4)]); + new AverageByteSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 0.5f, 0.5f, 0.5f), new Color(result[0], result[1], result[2], result[3])); + + info = new SamplerInfo(16, 16, data); + new AverageByteSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 0.5f, 0.5f, 0.5f), new Color(result[0], result[1], result[2], result[3])); + } + + [TestMethod] + public void MixedTest() + { + Color[] colorData = new Color[16 * 16]; + for (int i = 0; i < colorData.Length; i++) + colorData[i] = (i % 5) switch + { + 0 => new Color(1f, 1f, 0f, 0f), + 1 => new Color(1f, 0f, 0.75f, 0f), + 2 => new Color(0.5f, 0f, 0f, 0.5f), + 3 => new Color(0f, 1f, 1f, 1f), + _ => new Color(0f, 0f, 0f, 0f), + }; + byte[] result = new byte[4]; + + Span data = new byte[colorData.Length * 4]; + int index = 0; + for (int i = 0; i < colorData.Length; i++) + { + data[index++] = colorData[i].GetA(); + data[index++] = colorData[i].GetR(); + data[index++] = colorData[i].GetG(); + data[index++] = colorData[i].GetB(); + } + + SamplerInfo info = new(2, 3, data[..(6 * 4)]); + new AverageByteSampler().Sample(info, result); + Assert.AreEqual(new Color(149, 128, 74, 64), new Color(result[0], result[1], result[2], result[3])); + + info = new SamplerInfo(16, 16, data); + new AverageByteSampler().Sample(info, result); + Assert.AreEqual(new Color(128, 103, 89, 76), new Color(result[0], result[1], result[2], result[3])); + } + + #endregion +} \ No newline at end of file diff --git a/Tests/RGB.NET.Presets.Tests/Sampler/AverageFloatSamplerTest.cs b/Tests/RGB.NET.Presets.Tests/Sampler/AverageFloatSamplerTest.cs new file mode 100644 index 00000000..6795f2cd --- /dev/null +++ b/Tests/RGB.NET.Presets.Tests/Sampler/AverageFloatSamplerTest.cs @@ -0,0 +1,127 @@ +using System; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using RGB.NET.Core; +using RGB.NET.Presets.Textures.Sampler; + +namespace RGB.NET.Presets.Tests.Sampler; + +[TestClass] +public class AverageFloatSamplerTest +{ + #region Methods + + [TestMethod] + public void WhiteTest() + { + Span colorData = new Color[16 * 16]; + colorData.Fill(new Color(1f, 1f, 1f, 1f)); + float[] result = new float[4]; + + Span data = new float[colorData.Length * 4]; + int index = 0; + for (int i = 0; i < colorData.Length; i++) + { + data[index++] = colorData[i].A; + data[index++] = colorData[i].R; + data[index++] = colorData[i].G; + data[index++] = colorData[i].B; + } + + SamplerInfo info = new(2, 3, data[..(6 * 4)]); + new AverageFloatSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 1f, 1f, 1f), new Color(result[0], result[1], result[2], result[3])); + + info = new SamplerInfo(16, 16, data); + new AverageFloatSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 1f, 1f, 1f), new Color(result[0], result[1], result[2], result[3])); + } + + [TestMethod] + public void BlackTest() + { + Span colorData = new Color[16 * 16]; + colorData.Fill(new Color(1f, 0f, 0f, 0f)); + float[] result = new float[4]; + + Span data = new float[colorData.Length * 4]; + int index = 0; + for (int i = 0; i < colorData.Length; i++) + { + data[index++] = colorData[i].A; + data[index++] = colorData[i].R; + data[index++] = colorData[i].G; + data[index++] = colorData[i].B; + } + + SamplerInfo info = new(2, 3, data[..(6 * 4)]); + new AverageFloatSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 0f, 0f, 0f), new Color(result[0], result[1], result[2], result[3])); + + info = new SamplerInfo(16, 16, data); + new AverageFloatSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 0f, 0f, 0f), new Color(result[0], result[1], result[2], result[3])); + } + + [TestMethod] + public void GrayTest() + { + Span colorData = new Color[16 * 16]; + for (int i = 0; i < colorData.Length; i++) + colorData[i] = (i % 2) == 0 ? new Color(1f, 0f, 0f, 0f) : new Color(1f, 1f, 1f, 1f); + float[] result = new float[4]; + + Span data = new float[colorData.Length * 4]; + int index = 0; + for (int i = 0; i < colorData.Length; i++) + { + data[index++] = colorData[i].A; + data[index++] = colorData[i].R; + data[index++] = colorData[i].G; + data[index++] = colorData[i].B; + } + + SamplerInfo info = new(2, 3, data[..(6 * 4)]); + new AverageFloatSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 0.5f, 0.5f, 0.5f), new Color(result[0], result[1], result[2], result[3])); + + info = new SamplerInfo(16, 16, data); + new AverageFloatSampler().Sample(info, result); + Assert.AreEqual(new Color(1f, 0.5f, 0.5f, 0.5f), new Color(result[0], result[1], result[2], result[3])); + } + + [TestMethod] + public void MixedTest() + { + Color[] colorData = new Color[16 * 16]; + for (int i = 0; i < colorData.Length; i++) + colorData[i] = (i % 5) switch + { + 0 => new Color(1f, 1f, 0f, 0f), + 1 => new Color(1f, 0f, 0.75f, 0f), + 2 => new Color(0.5f, 0f, 0f, 0.5f), + 3 => new Color(0f, 1f, 1f, 1f), + _ => new Color(0f, 0f, 0f, 0f), + }; + float[] result = new float[4]; + + Span data = new float[colorData.Length * 4]; + int index = 0; + for (int i = 0; i < colorData.Length; i++) + { + data[index++] = colorData[i].A; + data[index++] = colorData[i].R; + data[index++] = colorData[i].G; + data[index++] = colorData[i].B; + } + + SamplerInfo info = new(2, 3, data[..(6 * 4)]); + new AverageFloatSampler().Sample(info, result); + Assert.AreEqual(new Color(0.5833333f, 0.5f, 0.291666657f, 0.25f), new Color(result[0], result[1], result[2], result[3])); + + info = new SamplerInfo(16, 16, data); + new AverageFloatSampler().Sample(info, result); + Assert.AreEqual(new Color(0.5019531f, 0.40234375f, 0.3486328f, 0.298828125f), new Color(result[0], result[1], result[2], result[3])); + } + + #endregion +} \ No newline at end of file