public LightingComponent(LightingMode lightingMode = LightingMode.Knockout, LightMapSize mLightMapSize = LightMapSize.Full, int mBluriness = 0)
        {
            mLight = new KryptonEngine(MilkShake.Game, "KryptonEffect");
            mLight.Initialize();

            // [Settings]
            mLight.LightMapSize = mLightMapSize;
            mLight.Bluriness = mBluriness;
            mLightingMode = lightingMode;

            mRenderTarget = new RenderTarget2D(MilkShake.Graphics, Globals.ScreenWidth, Globals.ScreenHeight);
        }
Beispiel #2
0
 internal static extern void Manager_SetLightingMode(IntPtr handle, LightingMode value);
Beispiel #3
0
        /// <summary>
        /// Draws the tank model, using the current animation settings.
        /// </summary>
        public void Draw(Matrix world, Matrix view, Matrix projection, LightingMode lightMode, bool textureEnable)
        {
            // Set the world matrix as the root transform of the model.
            tankModel.Root.Transform = world;

            // Calculate matrices based on the current animation position.
            Matrix wheelRotation = Matrix.CreateRotationX(wheelRotationValue);
            Matrix steerRotation = Matrix.CreateRotationY(steerRotationValue);
            Matrix turretRotation = Matrix.CreateRotationY(turretRotationValue);
            Matrix cannonRotation = Matrix.CreateRotationX(cannonRotationValue);
            Matrix hatchRotation = Matrix.CreateRotationX(hatchRotationValue);

            // Apply matrices to the relevant bones.
            leftBackWheelBone.Transform = wheelRotation * leftBackWheelTransform;
            rightBackWheelBone.Transform = wheelRotation * rightBackWheelTransform;
            leftFrontWheelBone.Transform = wheelRotation * leftFrontWheelTransform;
            rightFrontWheelBone.Transform = wheelRotation * rightFrontWheelTransform;
            leftSteerBone.Transform = steerRotation * leftSteerTransform;
            rightSteerBone.Transform = steerRotation * rightSteerTransform;
            turretBone.Transform = turretRotation * turretTransform;
            cannonBone.Transform = cannonRotation * cannonTransform;
            hatchBone.Transform = hatchRotation * hatchTransform;

            // Look up combined bone matrices for the entire model.
            tankModel.CopyAbsoluteBoneTransformsTo(boneTransforms);

            // Draw the model.
            foreach (ModelMesh mesh in tankModel.Meshes)
            {
                foreach (BasicEffect effect in mesh.Effects)
                {
                    effect.World = boneTransforms[mesh.ParentBone.Index];
                    effect.View = view;
                    effect.Projection = projection;

                    switch (lightMode)
                    {
                        case LightingMode.NoLighting:
                            effect.LightingEnabled = false;
                            break;

                        case LightingMode.OneVertexLight:
                            effect.EnableDefaultLighting();
                            effect.PreferPerPixelLighting = false;
                            effect.DirectionalLight1.Enabled = false;
                            effect.DirectionalLight2.Enabled = false;
                            break;

                        case LightingMode.ThreeVertexLights:
                            effect.EnableDefaultLighting();
                            effect.PreferPerPixelLighting = false;
                            break;

                        case LightingMode.ThreePixelLights:
                            effect.EnableDefaultLighting();
                            effect.PreferPerPixelLighting = true;
                            break;
                    }

                    effect.SpecularColor = new Vector3(0.8f, 0.8f, 0.6f);
                    effect.SpecularPower = 16;
                    effect.TextureEnabled = textureEnable;
                }

                mesh.Draw();
            }
        }
Beispiel #4
0
            public override void OnClicked()
            {
                if (LightMode == LightingMode.ThreePixelLights)
                    LightMode = 0;
                else
                    LightMode++;

                base.OnClicked();
            }
Beispiel #5
0
 /// <summary>
 /// Creates a new champion instance.
 /// </summary>
 /// <param name="ledCount">Number of LEDs in the strip</param>
 /// <param name="gameState">Game state data</param>
 /// <param name="preferredLightMode">Preferred light mode</param>
 /// <param name="preferredCastMode">Preferred ability cast mode (Normal, Quick Cast, Quick Cast with Indicator)</param>
 public static TwistedFateModule Create(int ledCount, GameState gameState, LightingMode preferredLightMode, AbilityCastPreference preferredCastMode = AbilityCastPreference.Normal)
 {
     return(new TwistedFateModule(ledCount, gameState, CHAMPION_NAME, preferredLightMode, preferredCastMode));
 }
Beispiel #6
0
        private TwistedFateModule(int ledCount, GameState gameState, string championName, LightingMode preferredLightMode, AbilityCastPreference preferredCastMode)
            : base(ledCount, championName, gameState, preferredLightMode, true)
        {
            // Initialization for the champion module occurs here.

            // Set preferred cast mode. It's a player choice (Quick cast, Quick cast with indicator, or Normal cast)
            PreferredCastMode = preferredCastMode;

            // Set cast modes for abilities.
            Dictionary <AbilityKey, AbilityCastMode> abilityCastModes = new Dictionary <AbilityKey, AbilityCastMode>()
            {
                [AbilityKey.Q] = AbilityCastMode.Normal(),
                [AbilityKey.W] = AbilityCastMode.Instant(6000, 1),
                [AbilityKey.E] = AbilityCastMode.UnCastable(),
                [AbilityKey.R] = AbilityCastMode.Instant(6000, 1, AbilityCastMode.Normal()),
            };

            AbilityCastModes = abilityCastModes;

            // Preload all the animations you'll want to use. MAKE SURE that each animation file
            // has its Build Action set to "Content" and "Copy to Output Directory" is set to "Always".

            /* PreloadAnimation("q_cast.txt");
             * PreloadAnimation("w_loop.txt");
             * PreloadAnimation("r_cast.txt");*/

            ChampionInfoLoaded += OnChampionInfoLoaded;
        }
        // Variables


        // Cooldown

        /// <summary>
        /// Creates a new champion instance.
        /// </summary>
        /// <param name="ledCount">Number of LEDs in the strip</param>
        /// <param name="gameState">Game state data</param>
        /// <param name="preferredLightMode">Preferred light mode</param>
        /// <param name="preferredCastMode">Preferred ability cast mode (Normal, Quick Cast, Quick Cast with Indicator)</param>
        public static FarsightAlterationModule Create(int ledCount, GameState gameState, int itemSlot, LightingMode preferredLightMode, AbilityCastPreference preferredCastMode = AbilityCastPreference.Normal)
        {
            return(new FarsightAlterationModule(ledCount, gameState, ITEM_ID, itemSlot, preferredLightMode, preferredCastMode));
        }
        private FarsightAlterationModule(int ledCount, GameState gameState, int itemID, int itemSlot, LightingMode preferredLightMode, AbilityCastPreference preferredCastMode)
            : base(itemID, itemSlot, gameState, preferredLightMode)
        {
            // Initialization for the item module occurs here.

            // Set preferred cast mode. It's a player choice (Quick cast, Quick cast with indicator, or Normal cast)
            PreferredCastMode = preferredCastMode;

            ItemCast         += OnItemActivated;
            GameStateUpdated += OnGameStateUpdated;
            // Set item cast mode.
            // For Oracle Lens, for example:
            // It's Instant Cast (press it, and the trinket activates)
            // For a ward, it's normal cast (press & click)
            ItemCastMode = AbilityCastMode.Normal();

            // Preload all the animations you'll want to use. MAKE SURE that each animation file
            // has its Build Action set to "Content" and "Copy to Output Directory" is set to "Always".

            animator = AnimationModule.Create(ledCount);
            animator.NewFrameReady += (_, ls, mode) => DispatchNewFrame(ls, mode);

            animator.PreloadAnimation(ITEM_ANIMATION_PATH + "FarsightAlteration/activation.txt");
        }
        public override void Unpack(string[] keywords)
        {
            if (HasFeature(keywords, DefineFeature._MAX2LAYER))
            {
                perfMode = PerformanceMode.Fastest;
            }
            else if (HasFeature(keywords, DefineFeature._MAX3LAYER))
            {
                perfMode = PerformanceMode.Balanced;
            }
            else
            {
                perfMode = PerformanceMode.BestQuality;
            }

            emissiveArray = HasFeature(keywords, DefineFeature._USEEMISSIVEMETAL);
            samplerMode   = SamplerMode.Default;
            if (HasFeature(keywords, DefineFeature._USELODMIP))
            {
                samplerMode = SamplerMode.LODSampler;
            }
            else if (HasFeature(keywords, DefineFeature._USEGRADMIP))
            {
                samplerMode = SamplerMode.GradientSampler;
            }

            uvMode = HasFeature(keywords, DefineFeature._WORLDUV) ? UVMode.WorldSpace : UVMode.UV;



            if (HasFeature(keywords, DefineFeature._MAX4TEXTURES))
            {
                maxTextureCount = MaxTextureCount.Four;
            }
            else if (HasFeature(keywords, DefineFeature._MAX8TEXTURES))
            {
                maxTextureCount = MaxTextureCount.Eight;
            }
            else if (HasFeature(keywords, DefineFeature._MAX12TEXTURES))
            {
                maxTextureCount = MaxTextureCount.Twelve;
            }
            else
            {
                maxTextureCount = MaxTextureCount.Sixteen;
            }

            disableHeightBlend = HasFeature(keywords, DefineFeature._DISABLEHEIGHTBLENDING);

            lightingMode = LightingMode.Automatic;
            if (HasFeature(keywords, DefineFeature._BDRF1))
            {
                lightingMode = LightingMode.StandardShader;
            }
            else if (HasFeature(keywords, DefineFeature._BDRF2))
            {
                lightingMode = LightingMode.Simplified;
            }
            else if (HasFeature(keywords, DefineFeature._BDRF3))
            {
                lightingMode = LightingMode.BlinnPhong;
            }

            perTexUVScale        = (HasFeature(keywords, DefineFeature._PERTEXUVSCALEOFFSET));
            perTexInterpContrast = HasFeature(keywords, DefineFeature._PERTEXINTERPCONTRAST);
            perTexBrightness     = HasFeature(keywords, DefineFeature._PERTEXBRIGHTNESS);
            perTexContrast       = HasFeature(keywords, DefineFeature._PERTEXCONTRAST);
            perTexAOStr          = (HasFeature(keywords, DefineFeature._PERTEXAOSTR));
            perTexMetallic       = (HasFeature(keywords, DefineFeature._PERTEXMETALLIC));
            perTexNormStr        = (HasFeature(keywords, DefineFeature._PERTEXNORMSTR));
            perTexSmoothStr      = (HasFeature(keywords, DefineFeature._PERTEXSMOOTHSTR));
            perTexTint           = (HasFeature(keywords, DefineFeature._PERTEXTINT));

            shaderModel = ShaderModel.Automatic;
            if (HasFeature(keywords, DefineFeature._FORCEMODEL46))
            {
                shaderModel = ShaderModel.Force46;
            }
            if (HasFeature(keywords, DefineFeature._FORCEMODEL50))
            {
                shaderModel = ShaderModel.Force50;
            }

            debugOutput = DebugOutput.None;
            if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_ALBEDO))
            {
                debugOutput = DebugOutput.Albedo;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_HEIGHT))
            {
                debugOutput = DebugOutput.Height;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_NORMAL))
            {
                debugOutput = DebugOutput.Normal;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SMOOTHNESS))
            {
                debugOutput = DebugOutput.Smoothness;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_METAL))
            {
                debugOutput = DebugOutput.Metallic;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_AO))
            {
                debugOutput = DebugOutput.AO;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_EMISSION))
            {
                debugOutput = DebugOutput.Emission;
            }
        }
Beispiel #10
0
        public void massUpdateLEDsRectangle(int startX, int startY, int endX, int endY, int velo, LightingMode mode = LightingMode.Set, int velo2 = 0, int velo3 = 0)
        {
            List <int> xs = new List <int>();
            List <int> ys = new List <int>();

            for (int x = startX; x <= endX; x++)
            {
                for (int y = startY; y <= endY; y++)
                {
                    xs.Add(x);
                    ys.Add(y);
                }
            }
            massUpdateLEDs(xs, ys, velo, mode, velo2, velo3);
        }
Beispiel #11
0
        private WardingTotemModule(int ledCount, GameState gameState, int itemID, int itemSlot, LightingMode preferredLightMode, AbilityCastPreference preferredCastMode)
            : base(itemID, itemSlot, gameState, preferredLightMode)
        {
            // Initialization for the item module occurs here.

            // Set preferred cast mode. It's a player choice (Quick cast, Quick cast with indicator, or Normal cast)
            PreferredCastMode = preferredCastMode;

            ItemCast += OnItemActivated;

            /*GameStateUpdated += OnGameStateUpdated;
             * OnGameStateUpdated(gameState);*/

            // Set item cast mode.
            // For Oracle Lens, for example:
            // It's Instant Cast (press it, and the trinket activates)
            // For a ward, it's normal cast (press & click)
            ItemCastMode = AbilityCastMode.Normal();

            ItemCooldownController.SetCooldown(this.ItemID, GetCooldownPerCharge(gameState)); // Game bug? Set the cooldown to 0, because everytime

            // Since it's a ward trinket, setup ward recharging

            /*Task.Run(async () =>
             * {
             *  while (true)
             *  {
             *      if (wardCharges < 2)
             *      {
             *          await Task.Delay(cooldownPerCharge);
             *          wardCharges++;
             *      } else
             *      {
             *          await Task.Delay(300);
             *      }
             *  }
             *
             * });*/

            // Preload all the animations you'll want to use. MAKE SURE that each animation file
            // has its Build Action set to "Content" and "Copy to Output Directory" is set to "Always".

            animator = AnimationModule.Create(ledCount);
            animator.NewFrameReady += (_, ls, mode) => DispatchNewFrame(ls, mode);
        }
        public override void Unpack(string[] keywords)
        {
            if (HasFeature(keywords, DefineFeature._MAX2LAYER))
            {
                perfMode = PerformanceMode.Fastest;
            }
            else if (HasFeature(keywords, DefineFeature._MAX3LAYER))
            {
                perfMode = PerformanceMode.Balanced;
            }
            else
            {
                perfMode = PerformanceMode.BestQuality;
            }

            useCustomSplatMaps = (HasFeature(keywords, DefineFeature._CUSTOMSPLATTEXTURES));
            disableNormals     = (HasFeature(keywords, DefineFeature._NONOMALMAP));

            packMode = HasFeature(keywords, DefineFeature._PACKINGHQ) ? TextureArrayConfig.PackingMode.Quality : TextureArrayConfig.PackingMode.Fastest;

            emissiveArray = HasFeature(keywords, DefineFeature._USEEMISSIVEMETAL);
            samplerMode   = SamplerMode.Default;
            if (HasFeature(keywords, DefineFeature._USELODMIP))
            {
                samplerMode = SamplerMode.LODSampler;
            }
            else if (HasFeature(keywords, DefineFeature._USEGRADMIP))
            {
                samplerMode = SamplerMode.GradientSampler;
            }
            // force gradient sampling for stochastic mode
            if (samplerMode == SamplerMode.Default && System.Array.Exists(keywords, e => e == "_STOCHASTIC"))
            {
                samplerMode = SamplerMode.GradientSampler;
            }

            perPixelNormal = HasFeature(keywords, DefineFeature._PERPIXNORMAL);
            uvMode         = HasFeature(keywords, DefineFeature._WORLDUV) ? UVMode.WorldSpace : UVMode.UV;

            perTexHeightOffset   = HasFeature(keywords, DefineFeature._PERTEXHEIGHTOFFSET);
            perTexHeightContrast = HasFeature(keywords, DefineFeature._PERTEXHEIGHTCONTRAST);

            if (HasFeature(keywords, DefineFeature._MAX4TEXTURES))
            {
                maxTextureCount = MaxTextureCount.Four;
            }
            else if (HasFeature(keywords, DefineFeature._MAX8TEXTURES))
            {
                maxTextureCount = MaxTextureCount.Eight;
            }
            else if (HasFeature(keywords, DefineFeature._MAX12TEXTURES))
            {
                maxTextureCount = MaxTextureCount.Twelve;
            }
            else if (HasFeature(keywords, DefineFeature._MAX20TEXTURES))
            {
                maxTextureCount = MaxTextureCount.Twenty;
            }
            else if (HasFeature(keywords, DefineFeature._MAX24TEXTURES))
            {
                maxTextureCount = MaxTextureCount.TwentyFour;
            }
            else if (HasFeature(keywords, DefineFeature._MAX28TEXTURES))
            {
                maxTextureCount = MaxTextureCount.TwentyEight;
            }
            else if (HasFeature(keywords, DefineFeature._MAX32TEXTURES))
            {
                maxTextureCount = MaxTextureCount.ThirtyTwo;
            }
            else
            {
                maxTextureCount = MaxTextureCount.Sixteen;
            }

            disableHeightBlend = HasFeature(keywords, DefineFeature._DISABLEHEIGHTBLENDING);

            lightingMode = LightingMode.Automatic;
            if (HasFeature(keywords, DefineFeature._BDRF1))
            {
                lightingMode = LightingMode.StandardShader;
            }
            else if (HasFeature(keywords, DefineFeature._BDRF2))
            {
                lightingMode = LightingMode.Simplified;
            }
            else if (HasFeature(keywords, DefineFeature._BDRF3))
            {
                lightingMode = LightingMode.BlinnPhong;
            }
            else if (HasFeature(keywords, DefineFeature._BDRFLAMBERT))
            {
                lightingMode = LightingMode.Lambert;
            }

            perTexUVScale        = (HasFeature(keywords, DefineFeature._PERTEXUVSCALEOFFSET));
            perTexInterpContrast = HasFeature(keywords, DefineFeature._PERTEXINTERPCONTRAST);
            perTexBrightness     = HasFeature(keywords, DefineFeature._PERTEXBRIGHTNESS);
            perTexContrast       = HasFeature(keywords, DefineFeature._PERTEXCONTRAST);
            perTexSaturation     = HasFeature(keywords, DefineFeature._PERTEXSATURATION);
            perTexAOStr          = (HasFeature(keywords, DefineFeature._PERTEXAOSTR));
            perTexMetallic       = (HasFeature(keywords, DefineFeature._PERTEXMETALLIC));
            perTexNormStr        = (HasFeature(keywords, DefineFeature._PERTEXNORMSTR));
            perTexSmoothStr      = (HasFeature(keywords, DefineFeature._PERTEXSMOOTHSTR));
            perTexTint           = (HasFeature(keywords, DefineFeature._PERTEXTINT));

            shaderModel = ShaderModel.Automatic;
            if (HasFeature(keywords, DefineFeature._FORCEMODEL46))
            {
                shaderModel = ShaderModel.Force46;
            }
            if (HasFeature(keywords, DefineFeature._FORCEMODEL50))
            {
                shaderModel = ShaderModel.Force50;
            }

            debugOutput = DebugOutput.None;
            if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_ALBEDO))
            {
                debugOutput = DebugOutput.Albedo;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_HEIGHT))
            {
                debugOutput = DebugOutput.Height;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_NORMAL))
            {
                debugOutput = DebugOutput.Normal;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SMOOTHNESS))
            {
                debugOutput = DebugOutput.Smoothness;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_METAL))
            {
                debugOutput = DebugOutput.Metallic;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_AO))
            {
                debugOutput = DebugOutput.AO;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_EMISSION))
            {
                debugOutput = DebugOutput.Emission;
            }
#if __MICROSPLAT_PROCTEX__
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT0))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput0;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT1))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput1;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT2))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput2;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT3))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput3;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT4))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput4;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT5))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput5;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT6))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput6;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT7))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput7;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT0A))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput0A;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT1A))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput1A;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT2A))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput2A;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT3A))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput3A;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT4A))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput4A;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT5A))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput5A;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT6A))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput6A;
            }
            else if (HasFeature(keywords, DefineFeature._DEBUG_OUTPUT_SPLAT7A))
            {
                debugOutput = DebugOutput.ProceduralSplatOutput7A;
            }
#endif
        }
Beispiel #13
0
        /// <summary>
        /// Update the virtual LED strip with the given LED color data.
        /// </summary>
        public void UpdateUI(Led[] leds, LightingMode mode)
        {
            if (updatingUI)
            {
                return;
            }
            updatingUI = true;
            Task.Run(() => // HACK This is done asynchronously but the fact is that it's very slow. 10ms to draw stuff...
            {
                if (currentLightingMode == LightingMode.Keyboard)
                {
                    if (mode == LightingMode.Keyboard)
                    {
                        if (lastDrawnMode != LightingMode.Keyboard)
                        {
                            canvas.Clear(Color.White);
                        }
                        int i = 0;
                        foreach (var led in leds)
                        {
                            byte[] col          = led.color.ToRGB();
                            SolidBrush colBrush = new SolidBrush(Color.FromArgb(col[0], col[1], col[2]));
                            KeyboardKey key     = keyboardLayout[i];
                            canvas.FillRectangle(colBrush, new Rectangle(key.X, key.Y, (key.Width ?? 20) - 2, (key.Height ?? 20) - 2));
                            i++;
                        }
                        lastDrawnMode = LightingMode.Keyboard;
                    }
                    else
                    {
                        SolidBrush blackBrush = new SolidBrush(Color.Black);
                        if (lastDrawnMode != LightingMode.Line)
                        {
                            for (int i = 0; i < 88; i++)
                            {
                                KeyboardKey key = keyboardLayout[i];
                                canvas.FillRectangle(blackBrush, new Rectangle(key.X, key.Y, (key.Width ?? 20) - 2, (key.Height ?? 20) - 2));
                                i++;
                            }
                        }
                        for (int i = 0; i < leds.Length; i++)
                        {
                            byte[] col = leds[i].color.ToRGB();
                            // SolidBrush colBrush = new SolidBrush(Color.FromArgb((int)(leds[i].color.v*255), col[0], col[1], col[2]));
                            SolidBrush colBrush = new SolidBrush(Color.FromArgb(col[0], col[1], col[2]));
                            int x = (int)Utils.Scale(i, 0, leds.Length, 0, 22);
                            for (int j = 0; j < 6; j++)
                            {
                                canvas.FillRectangle(colBrush, new Rectangle(x * 20, j * 20, 18, 18));
                            }
                        }
                        lastDrawnMode = LightingMode.Line;
                    }
                }
                else
                {
                    int i = 0;
                    foreach (var led in leds)
                    {
                        byte[] col          = led.color.ToRGB();
                        SolidBrush colBrush = new SolidBrush(Color.FromArgb(col[0], col[1], col[2]));
                        canvas.FillRectangle(colBrush, new Rectangle(0 + i * 10, 0, 10, 10));
                        i++;
                    }
                    lastDrawnMode = LightingMode.Line;
                }

                updatingUI = false;
            });
        }