Beispiel #1
0
        private void Init()
        {
            // TODO: Check synapse version. https://chromasdk.io:54236/razer/chromasdk Version must be >= 3.X
            int status = 0;

            try
            {
                status = ChromaAnimationAPI.Init();
                if (status != 0)
                {
                    throw new InvalidOperationException("Chroma SDK exception. Status " + status);
                }
            }
            catch (Exception e)
            {
                MessageBox.Show("Error initializing Razer Chroma controller. Is Razer Synapse installed? Status=" + status);
                throw new InvalidOperationException("Error initializing Razer Chroma controller. Is Razer Synapse installed?", e);
            }
            baseKeyboardAnim = ChromaAnimationAPI.CreateAnimationInMemory((int)ChromaAnimationAPI.DeviceType.DE_2D, (int)ChromaAnimationAPI.Device2D.Keyboard);
            if (baseKeyboardAnim == -1)
            { // TODO: Returns -1 if the keyboard is not connected? Check how it works
                MessageBox.Show("Error initializing Razer Chroma controller. Check that your keyboard is connected and Razer Synapse is installed");
                throw new InvalidOperationException("CreateAnimationInMemory ChromaSDK returned -1");
            }
            // is AddFrame needed?
            ChromaAnimationAPI.AddFrame(baseKeyboardAnim, 1, new int[MAX_KEYBOARD_COLS * MAX_KEYBOARD_ROWS], MAX_KEYBOARD_COLS * MAX_KEYBOARD_ROWS);
        }
    int GetColorArraySize2D(Device2D device)
    {
        int maxRow    = ChromaAnimationAPI.GetMaxRow(device);
        int maxColumn = ChromaAnimationAPI.GetMaxColumn(device);

        return(maxRow * maxColumn);
    }
Beispiel #3
0
 void OnApplicationQuit()
 {
     _mWaitForExit = false;
     ChromaAnimationAPI.StopAll();
     ChromaAnimationAPI.CloseAll();
     ChromaAnimationAPI.Uninit();
 }
 public void OnApplicationQuit()
 {
     if (ChromaAnimationAPI.IsInitialized())
     {
         ChromaAnimationAPI.Uninit();
     }
 }
    int InvertColor(int color)
    {
        int red   = 255 - (color & 0xFF);
        int green = 255 - ((color >> 8) & 0xFF);
        int blue  = 255 - ((color >> 16) & 0xFF);

        return(ChromaAnimationAPI.GetRGB(red, green, blue));
    }
        static void Main(string[] args)
        {
            SampleApp sampleApp = new SampleApp();

            sampleApp.Start();

            if (sampleApp.GetInitResult() == RazerErrors.RZRESULT_SUCCESS)
            {
                int selectedIndex = 1;

                sampleApp.ExecuteItem(selectedIndex);

                DateTime inputTimer = DateTime.MinValue;

                while (true)
                {
                    if (inputTimer < DateTime.Now)
                    {
                        Console.Clear();
                        PrintLegend(sampleApp, selectedIndex);
                        inputTimer = DateTime.Now + TimeSpan.FromMilliseconds(100);
                    }
                    ConsoleKeyInfo keyInfo = Console.ReadKey();

                    if (keyInfo.Key == ConsoleKey.UpArrow)
                    {
                        if (selectedIndex > 1)
                        {
                            --selectedIndex;
                        }
                    }
                    else if (keyInfo.Key == ConsoleKey.DownArrow)
                    {
                        if (selectedIndex < MAX_ITEMS)
                        {
                            ++selectedIndex;
                        }
                    }
                    else if (keyInfo.Key == ConsoleKey.Escape)
                    {
                        break;
                    }
                    else if (keyInfo.Key == ConsoleKey.Enter)
                    {
                        sampleApp.ExecuteItem(selectedIndex);
                    }
                    Thread.Sleep(1);
                }

                ChromaAnimationAPI.StopAll();
                ChromaAnimationAPI.CloseAll();
                sampleApp.OnApplicationQuit();
            }

            Console.WriteLine("{0}", "C# Chroma Sample App [EXIT]");
        }
Beispiel #7
0
        private void SendHeadsetData(LEDData data)
        {
            byte[] colorArray = data.Mousepad.ToByteArray();

            for (int i = 0; i < 2; i++)
            {
                int color = ChromaAnimationAPI.GetRGB(colorArray[i * 3], colorArray[i * 3 + 1], colorArray[i * 3 + 2]);
                ChromaAnimationAPI.Set1DColor(baseHeadsetAnim, 0, i, color);
            }
            ChromaAnimationAPI.PreviewFrame(baseHeadsetAnim, 0);
        }
Beispiel #8
0
        private void SendGeneralData(LEDData data)
        {
            byte[] colorArray = data.General.ToByteArray();

            for (int i = 0; i < 5; i++)
            {
                int color = ChromaAnimationAPI.GetRGB(colorArray[i * 3], colorArray[i * 3 + 1], colorArray[i * 3 + 2]);
                ChromaAnimationAPI.Set1DColor(baseGeneralAnim, 0, i, color);
            }
            ChromaAnimationAPI.PreviewFrame(baseGeneralAnim, 0);
        }
Beispiel #9
0
        private void SendMousepadData(LEDData data)
        {
            byte[] colorArray = data.Mousepad.ToByteArray();

            for (int i = 0; i < 16; i++)
            {
                int color = ChromaAnimationAPI.GetRGB(colorArray[i * 3], colorArray[i * 3 + 1], colorArray[i * 3 + 2]);
                ChromaAnimationAPI.Set1DColor(baseMousepadAnim, 0, 16 - i, color); // inverted order
            }
            ChromaAnimationAPI.PreviewFrame(baseMousepadAnim, 0);
        }
Beispiel #10
0
        private int CreateAnimation(ChromaAnimationAPI.DeviceType deviceType, int device)
        {
            int anim = ChromaAnimationAPI.CreateAnimationInMemory((int)deviceType, device);

            if (anim == -1)
            {
                MessageBox.Show("Error initializing Razer Chroma controller. CreateAnimationInMemory returned -1. " +
                                "Check that your mouse is connected and Razer Synapse is installed");
                throw new InvalidOperationException("CreateAnimationInMemory ChromaSDK returned -1");
            }
            return(anim);
        }
    void SetupAnimation2D(string path, Device2D device)
    {
        int animationId = ChromaAnimationAPI.GetAnimation(path);

        if (animationId == -1)
        {
            animationId = ChromaAnimationAPI.CreateAnimationInMemory((int)DeviceType.DE_2D, (int)device);
            ChromaAnimationAPI.CopyAnimation(animationId, path);
            ChromaAnimationAPI.CloseAnimation(animationId);
            ChromaAnimationAPI.MakeBlankFramesName(path, 1, 0.1f, 0);
        }
    }
 void OnApplicationQuit()
 {
     _mWaitForExit = false;
     if (null != _mThread)
     {
         _mThread.Join();
         _mThread = null;
     }
     ChromaAnimationAPI.StopAll();
     ChromaAnimationAPI.CloseAll();
     ChromaAnimationAPI.Uninit();
 }
    int MultiplyNonZeroTargetColorLerp(int color1, int color2, int inputColor)
    {
        if (inputColor == 0)
        {
            return(inputColor);
        }
        float red   = (inputColor & 0xFF) / 255.0f;
        float green = ((inputColor & 0xFF00) >> 8) / 255.0f;
        float blue  = ((inputColor & 0xFF0000) >> 16) / 255.0f;
        float t     = (red + green + blue) / 3.0f;

        return(ChromaAnimationAPI.LerpColor(color1, color2, t));
    }
Beispiel #14
0
        private void SendKeypadData(LEDData data)
        {
            byte[] colorArray = data.Keypad.ToByteArray();

            for (int col = 0; col < 4; col++)
            {
                for (int row = 0; row < 5; row++)
                {
                    int index = col * 5 + row;
                    int color = ChromaAnimationAPI.GetRGB(colorArray[index * 3], colorArray[index * 3 + 1], colorArray[index * 3 + 2]);
                    ChromaAnimationAPI.Set2DColor(baseKeypadAnim, 0, col, row, color);
                }
            }
            ChromaAnimationAPI.PreviewFrame(baseKeypadAnim, 0);
        }
        private void PlayAnimation(string name, int duration, bool loop = false)
        {
            if (_scheduledBackground != null)
            {
                _scheduledBackground.Dispose();
                _scheduledBackground = null;
            }

            ChromaAnimationAPI.PlayAnimationName(ANIMATION_PATH + "/" + name + ".chroma", loop);

            if (duration > 0)
            {
                _scheduledBackground = ExecutionPlan.Delay(duration, PlayBackground);
            }
        }
    int MinColor(int color1, int color2)
    {
        int redColor1   = color1 & 0xFF;
        int greenColor1 = (color1 >> 8) & 0xFF;
        int blueColor1  = (color1 >> 16) & 0xFF;

        int redColor2   = color2 & 0xFF;
        int greenColor2 = (color2 >> 8) & 0xFF;
        int blueColor2  = (color2 >> 16) & 0xFF;

        int red   = Mathf.Min(redColor1, redColor2) & 0xFF;
        int green = Mathf.Min(greenColor1, greenColor2) & 0xFF;
        int blue  = Mathf.Min(blueColor1, blueColor2) & 0xFF;

        return(ChromaAnimationAPI.GetRGB(red, green, blue));
    }
    int SubtractColor(int color1, int color2)
    {
        int redColor1   = color1 & 0xFF;
        int greenColor1 = (color1 >> 8) & 0xFF;
        int blueColor1  = (color1 >> 16) & 0xFF;

        int redColor2   = color2 & 0xFF;
        int greenColor2 = (color2 >> 8) & 0xFF;
        int blueColor2  = (color2 >> 16) & 0xFF;

        int red   = Mathf.Max(redColor1 - redColor2, 0) & 0xFF;
        int green = Mathf.Max(greenColor1 - greenColor2, 0) & 0xFF;
        int blue  = Mathf.Max(blueColor1 - blueColor2, 0) & 0xFF;

        return(ChromaAnimationAPI.GetRGB(red, green, blue));
    }
    int MultiplyColor(int color1, int color2)
    {
        int redColor1   = color1 & 0xFF;
        int greenColor1 = (color1 >> 8) & 0xFF;
        int blueColor1  = (color1 >> 16) & 0xFF;

        int redColor2   = color2 & 0xFF;
        int greenColor2 = (color2 >> 8) & 0xFF;
        int blueColor2  = (color2 >> 16) & 0xFF;

        int red   = (int)Mathf.Floor(255 * ((redColor1 / 255.0f) * (redColor2 / 255.0f)));
        int green = (int)Mathf.Floor(255 * ((greenColor1 / 255.0f) * (greenColor2 / 255.0f)));
        int blue  = (int)Mathf.Floor(255 * ((blueColor1 / 255.0f) * (blueColor2 / 255.0f)));

        return(ChromaAnimationAPI.GetRGB(red, green, blue));
    }
Beispiel #19
0
        private void Init()
        {
            // TODO: Check synapse version. https://chromasdk.io:54236/razer/chromasdk Version must be >= 3.X
            int status = 0;

            try
            {
                status = ChromaAnimationAPI.Init();
                if (status != 0)
                {
                    throw new InvalidOperationException("Chroma SDK exception. Status " + status);
                }
            }
            catch (Exception e)
            {
                string errorString = "Please make sure that Razer Synapse 3 is installed and updated to the latest version.";
                switch ((long)status)
                {
                case RZRESULT_DLL_NOT_FOUND:
                    errorString = "Couldn't find Chroma SDK. This is usually caused because Razer Synapse 3 is not installed or updated to the latest version.";
                    break;

                case RZRESULT_SERVICE_NOT_ACTIVE:
                    errorString = "The Chroma SDK service is not active. This is usually caused because Razer Synapse VERSION 3 is not installed or updated to the latest version.";
                    break;
                }
                MessageBox.Show("Error initializing Razer Chroma controller. Status=" + status + "\n" + errorString);
                throw new InvalidOperationException("Error initializing Razer Chroma controller. Is Razer Synapse installed?", e);
            }

            baseKeyboardAnim = CreateAnimation(ChromaAnimationAPI.DeviceType.DE_2D, (int)ChromaAnimationAPI.Device2D.Keyboard);
            //ChromaAnimationAPI.AddFrame(baseKeyboardAnim, 1, new int[MAX_KEYBOARD_COLS * MAX_KEYBOARD_ROWS], MAX_KEYBOARD_COLS * MAX_KEYBOARD_ROWS);

            baseMouseAnim = CreateAnimation(ChromaAnimationAPI.DeviceType.DE_2D, (int)ChromaAnimationAPI.Device2D.Mouse);

            baseMousepadAnim = CreateAnimation(ChromaAnimationAPI.DeviceType.DE_1D, (int)ChromaAnimationAPI.Device1D.Mousepad);

            baseHeadsetAnim = CreateAnimation(ChromaAnimationAPI.DeviceType.DE_1D, (int)ChromaAnimationAPI.Device1D.Headset);

            baseKeypadAnim = CreateAnimation(ChromaAnimationAPI.DeviceType.DE_2D, (int)ChromaAnimationAPI.Device2D.Keypad);

            baseGeneralAnim = CreateAnimation(ChromaAnimationAPI.DeviceType.DE_1D, (int)ChromaAnimationAPI.Device1D.ChromaLink);


            disposed = false;
        }
Beispiel #20
0
        private void SendKeyboardData(LEDData data)
        {
            byte[] colorArray = data.Keyboard.ToByteArray();

            int black = ChromaAnimationAPI.GetRGB(0, 0, 0);

            foreach (Keyboard.RZKEY key in numPadKeys)
            {
                ChromaAnimationAPI.SetKeyColor(baseKeyboardAnim, 0, (int)key, black);
            }
            for (int i = 0; i < 88; i++) // TODO: NUMPAD
            {
                int color = ChromaAnimationAPI.GetRGB(colorArray[i * 3], colorArray[i * 3 + 1], colorArray[i * 3 + 2]);
                ChromaAnimationAPI.SetKeyColor(baseKeyboardAnim, 0, (int)indexKeyMap[i], color);
            }
            ChromaAnimationAPI.PreviewFrame(baseKeyboardAnim, 0);
        }
Beispiel #21
0
        public static void Update()
        {
            string curr = "Animations/Key.chroma";

            ChromaAnimationAPI.CloseAnimationName(curr);

            for (int i = 0; i < 127; i++)
            {
                try
                {
                    ChromaAnimationAPI.SetKeyColorAllFramesRGBName(curr, (int)chromaKeys[i], rValue[i], gValue[i], bValue[i]);
                }
                catch
                {
                }
            }

            ChromaAnimationAPI.PlayAnimationName(curr, true);
        }
Beispiel #22
0
        private void SendMouseData(LEDData data)
        {
            byte[] colorArray = data.Mouse.ToByteArray();

            for (int i = 0; i < 16; i++)
            {
                int color = ChromaAnimationAPI.GetRGB(colorArray[i * 3], colorArray[i * 3 + 1], colorArray[i * 3 + 2]);

                ushort number;
                byte   upper;
                byte   lower;
                if (i == 0) // logo and bottom leds
                {
                    foreach (RZLED2 led in MOUSE_BOTTOM_LEDS)
                    {
                        number = Convert.ToUInt16(RZLED2.RZLED2_LOGO);
                        upper  = (byte)(number >> 8);
                        lower  = (byte)(number & 0xff);
                        ChromaAnimationAPI.Set2DColor(baseMouseAnim, 0, upper, lower, color);
                    }
                }
                else if (i == 1) // scrollwheel and backlight
                {
                    number = Convert.ToUInt16(RZLED2.RZLED2_SCROLLWHEEL);
                    upper  = (byte)(number >> 8);
                    lower  = (byte)(number & 0xff);
                    ChromaAnimationAPI.Set2DColor(baseMouseAnim, 0, upper, lower, color);

                    number = Convert.ToUInt16(RZLED2.RZLED2_BACKLIGHT);
                    upper  = (byte)(number >> 8);
                    lower  = (byte)(number & 0xff);
                    ChromaAnimationAPI.Set2DColor(baseMouseAnim, 0, upper, lower, color);
                }
                else
                {
                    number = Convert.ToUInt16(MOUSE_LEDS[i]);
                    upper  = (byte)(number >> 8);
                    lower  = (byte)(number & 0xff);
                    ChromaAnimationAPI.Set2DColor(baseMouseAnim, 0, upper, lower, color);
                }
            }
            ChromaAnimationAPI.PreviewFrame(baseMouseAnim, 0);
        }
        public bool Start()
        {
            // try
            // {
            var appInfo = new APPINFOTYPE
            {
                Title           = "RainbowKnight",
                Description     = "Hollow Knight RainbowKnight mod",
                Author_Name     = "Webcretaire",
                Author_Contact  = "https://github.com/Webcretaire/HollowKnight.RainbowKnight",
                SupportedDevice = (int)ChromaAnimationAPI.Device.Keyboard |
                                  (int)ChromaAnimationAPI.Device.Mouse |
                                  (int)ChromaAnimationAPI.Device.ChromaLink,
                Category = 0x02     // 0x01 = Utility ; 0x02 = Game
            };

            _mResult = ChromaAnimationAPI.InitSDK(ref appInfo);
            switch (_mResult)
            {
            case RazerErrors.RZRESULT_DLL_NOT_FOUND:
                LogError("Chroma DLL is not found! " + RazerErrors.GetResultString(_mResult));
                return(false);

            case RazerErrors.RZRESULT_DLL_INVALID_SIGNATURE:
                LogError("Chroma DLL has an invalid signature! " + RazerErrors.GetResultString(_mResult));
                return(false);

            case RazerErrors.RZRESULT_SUCCESS:
                return(true);

            default:
                LogError("Failed to initialize Chroma! " + RazerErrors.GetResultString(_mResult));
                return(false);
            }
            // }
            // catch (Exception e)
            // {
            //     LogError("Error during Chroma Helper Start: " + e.Message);
            //     return false;
            // }
        }
Beispiel #24
0
        public static void Init()
        {
            _mResult = ChromaAnimationAPI.Init();
            switch (_mResult)
            {
            case RazerErrors.RZRESULT_DLL_NOT_FOUND:
                Console.Error.WriteLine("Chroma DLL is not found! {0}", RazerErrors.GetResultString(_mResult));
                break;

            case RazerErrors.RZRESULT_DLL_INVALID_SIGNATURE:
                Console.Error.WriteLine("Chroma DLL has an invalid signature! {0}", RazerErrors.GetResultString(_mResult));
                break;

            case RazerErrors.RZRESULT_SUCCESS:
                break;

            default:
                Console.Error.WriteLine("Failed to initialize Chroma! {0}", RazerErrors.GetResultString(_mResult));
                break;
            }

            Update();
        }
    public void Start()
    {
        ChromaAnimationAPI._sStreamingAssetPath = Application.streamingAssetsPath;
        _mResult      = ChromaAnimationAPI.Init();
        _mInitialized = true;
        switch (_mResult)
        {
        case RazerErrors.RZRESULT_DLL_NOT_FOUND:
            Debug.LogError(string.Format("Chroma DLL is not found! {0}", RazerErrors.GetResultString(_mResult)));
            break;

        case RazerErrors.RZRESULT_DLL_INVALID_SIGNATURE:
            Debug.LogError(string.Format("Chroma DLL has an invalid signature! {0}", RazerErrors.GetResultString(_mResult)));
            break;

        case RazerErrors.RZRESULT_SUCCESS:
            break;

        default:
            Debug.LogError(string.Format("Failed to initialize Chroma! {0}", RazerErrors.GetResultString(_mResult)));
            break;
        }
    }
 void SetKeyColorRGB(int[] colors, int rzkey, int red, int green, int blue)
 {
     SetKeyColor(colors, rzkey, ChromaAnimationAPI.GetRGB(red, green, blue));
 }
 int GetKeyColorIndex(int row, int column)
 {
     return(ChromaAnimationAPI.GetMaxColumn(Device2D.Keyboard) * row + column);
 }
    public void GameLoop()
    {
        int sizeChromaLink = GetColorArraySize1D(Device1D.ChromaLink);
        int sizeHeadset    = GetColorArraySize1D(Device1D.Headset);
        int sizeKeyboard   = GetColorArraySize2D(Device2D.Keyboard);
        int sizeKeypad     = GetColorArraySize2D(Device2D.Keypad);
        int sizeMouse      = GetColorArraySize2D(Device2D.Mouse);
        int sizeMousepad   = GetColorArraySize1D(Device1D.Mousepad);

        int[] colorsChromaLink = new int[sizeChromaLink];
        int[] colorsHeadset    = new int[sizeHeadset];
        int[] colorsKeyboard   = new int[sizeKeyboard];
        int[] colorsKeypad     = new int[sizeKeypad];
        int[] colorsMouse      = new int[sizeMouse];
        int[] colorsMousepad   = new int[sizeMousepad];

        int[] tempColorsChromaLink = new int[sizeChromaLink];
        int[] tempColorsHeadset    = new int[sizeHeadset];
        int[] tempColorsKeyboard   = new int[sizeKeyboard];
        int[] tempColorsKeypad     = new int[sizeKeypad];
        int[] tempColorsMouse      = new int[sizeMouse];
        int[] tempColorsMousepad   = new int[sizeMousepad];

        while (_mWaitForExit)
        {
            // start with a blank frame
            Array.Clear(colorsChromaLink, 0, sizeChromaLink);
            Array.Clear(colorsHeadset, 0, sizeHeadset);
            Array.Clear(colorsKeyboard, 0, sizeKeyboard);
            Array.Clear(colorsKeypad, 0, sizeKeypad);
            Array.Clear(colorsMouse, 0, sizeMouse);
            Array.Clear(colorsMousepad, 0, sizeMousepad);

#if !USE_ARRAY_EFFECTS
            SetupAnimation1D(ANIMATION_FINAL_CHROMA_LINK, Device1D.ChromaLink);
            SetupAnimation1D(ANIMATION_FINAL_HEADSET, Device1D.Headset);
            SetupAnimation2D(ANIMATION_FINAL_KEYBOARD, Device2D.Keyboard);
            SetupAnimation2D(ANIMATION_FINAL_KEYPAD, Device2D.Keypad);
            SetupAnimation2D(ANIMATION_FINAL_MOUSE, Device2D.Mouse);
            SetupAnimation1D(ANIMATION_FINAL_MOUSEPAD, Device1D.Mousepad);
#endif

            BlendAnimations(_mScene,
                            colorsChromaLink, tempColorsChromaLink,
                            colorsHeadset, tempColorsHeadset,
                            colorsKeyboard, tempColorsKeyboard,
                            colorsKeypad, tempColorsKeypad,
                            colorsMouse, tempColorsMouse,
                            colorsMousepad, tempColorsMousepad);

            if (_mAmmo)
            {
                // SHow health animation
                {
                    int[] keys =
                    {
                        (int)Keyboard.RZKEY.RZKEY_F1,
                        (int)Keyboard.RZKEY.RZKEY_F2,
                        (int)Keyboard.RZKEY.RZKEY_F3,
                        (int)Keyboard.RZKEY.RZKEY_F4,
                        (int)Keyboard.RZKEY.RZKEY_F5,
                        (int)Keyboard.RZKEY.RZKEY_F6,
                    };
                    int keysLength = keys.Length;

                    float t  = _mTimeMS * 0.002f;
                    float hp = (float)Math.Abs(Math.Cos(Math.PI / 2.0f + t));
                    for (int i = 0; i < keysLength; ++i)
                    {
                        int color;
                        if (((i + 1) / ((float)keysLength + 1)) < hp)
                        {
                            color = ChromaAnimationAPI.GetRGB(0, 255, 0);
                        }
                        else
                        {
                            color = ChromaAnimationAPI.GetRGB(0, 100, 0);
                        }
                        int key = keys[i];
                        SetKeyColor(colorsKeyboard, key, color);
                    }
                }

                // Show ammo animation
                {
                    int[] keys =
                    {
                        (int)Keyboard.RZKEY.RZKEY_F7,
                        (int)Keyboard.RZKEY.RZKEY_F8,
                        (int)Keyboard.RZKEY.RZKEY_F9,
                        (int)Keyboard.RZKEY.RZKEY_F10,
                        (int)Keyboard.RZKEY.RZKEY_F11,
                        (int)Keyboard.RZKEY.RZKEY_F12,
                    };
                    int keysLength = keys.Length;

                    float t  = _mTimeMS * 0.001f;
                    float hp = (float)Math.Abs(Math.Cos(Math.PI / 2.0f + t));
                    for (int i = 0; i < keysLength; ++i)
                    {
                        int color;
                        if (((i + 1) / ((float)keysLength + 1)) < hp)
                        {
                            color = ChromaAnimationAPI.GetRGB(255, 255, 0);
                        }
                        else
                        {
                            color = ChromaAnimationAPI.GetRGB(100, 100, 0);
                        }
                        int key = keys[i];
                        SetKeyColor(colorsKeyboard, key, color);
                    }
                }
            }

            if (_mHotkeys)
            {
                // Show hotkeys
                SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_ESC, 255, 255, 0);
                SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_W, 255, 0, 0);
                SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_A, 255, 0, 0);
                SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_S, 255, 0, 0);
                SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_D, 255, 0, 0);

                if (_mAmmo)
                {
                    SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_A, 0, 255, 0);
                }

                // Highlight R if rainbow is active
                if (_mScene._mEffects[_mIndexRainbow]._mState)
                {
                    SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_R, 0, 255, 0);
                }

                // Highlight S if spiral is active
                if (_mScene._mEffects[_mIndexSpiral]._mState)
                {
                    SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_S, 0, 255, 0);
                }

                // Highlight L if landscape is active
                if (_mScene._mEffects[_mIndexLandscape]._mState)
                {
                    SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_L, 0, 255, 0);
                }

                // Highlight L if landscape is active
                if (_mScene._mEffects[_mIndexFire]._mState)
                {
                    SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_F, 0, 255, 0);
                }

                if (_mHotkeys)
                {
                    SetKeyColorRGB(colorsKeyboard, (int)Keyboard.RZKEY.RZKEY_H, 0, 255, 0);
                }
            }

#if USE_ARRAY_EFFECTS
            ChromaAnimationAPI.SetEffectCustom1D((int)Device1D.ChromaLink, colorsChromaLink);
            ChromaAnimationAPI.SetEffectCustom1D((int)Device1D.Headset, colorsHeadset);
            ChromaAnimationAPI.SetEffectCustom1D((int)Device1D.Mousepad, colorsMousepad);

            ChromaAnimationAPI.SetCustomColorFlag2D((int)Device2D.Keyboard, colorsKeyboard);
            ChromaAnimationAPI.SetEffectKeyboardCustom2D((int)Device2D.Keyboard, colorsKeyboard);

            ChromaAnimationAPI.SetEffectCustom2D((int)Device2D.Keypad, colorsKeypad);
            ChromaAnimationAPI.SetEffectCustom2D((int)Device2D.Mouse, colorsMouse);
#else
            ChromaAnimationAPI.UpdateFrameName(ANIMATION_FINAL_CHROMA_LINK, 0, 0.1f, colorsChromaLink, sizeChromaLink);
            ChromaAnimationAPI.UpdateFrameName(ANIMATION_FINAL_HEADSET, 0, 0.1f, colorsHeadset, sizeHeadset);
            ChromaAnimationAPI.UpdateFrameName(ANIMATION_FINAL_KEYBOARD, 0, 0.1f, colorsKeyboard, sizeKeyboard);
            ChromaAnimationAPI.UpdateFrameName(ANIMATION_FINAL_KEYPAD, 0, 0.1f, colorsKeypad, sizeKeypad);
            ChromaAnimationAPI.UpdateFrameName(ANIMATION_FINAL_MOUSE, 0, 0.1f, colorsMouse, sizeMouse);
            ChromaAnimationAPI.UpdateFrameName(ANIMATION_FINAL_MOUSEPAD, 0, 0.1f, colorsMousepad, sizeMousepad);

            // display the change
            ChromaAnimationAPI.PreviewFrameName(ANIMATION_FINAL_CHROMA_LINK, 0);
            ChromaAnimationAPI.PreviewFrameName(ANIMATION_FINAL_HEADSET, 0);
            ChromaAnimationAPI.PreviewFrameName(ANIMATION_FINAL_KEYBOARD, 0);
            ChromaAnimationAPI.PreviewFrameName(ANIMATION_FINAL_KEYPAD, 0);
            ChromaAnimationAPI.PreviewFrameName(ANIMATION_FINAL_MOUSE, 0);
            ChromaAnimationAPI.PreviewFrameName(ANIMATION_FINAL_MOUSEPAD, 0);
#endif

            Thread.Sleep(33); //30 FPS
        }
    }
    void BlendAnimation2D(Effect effect, DeviceFrameIndex deviceFrameIndex, int device, Device2D device2D, string animationName,
                          int[] colors, int[] tempColors)
    {
        int size       = GetColorArraySize2D(device2D);
        int frameId    = deviceFrameIndex._mFrameIndex[device];
        int frameCount = ChromaAnimationAPI.GetFrameCountName(animationName);

        if (frameId < frameCount)
        {
            //cout << animationName << ": " << (1 + frameId) << " of " << frameCount << endl;
            float duration;
            int   animationId = ChromaAnimationAPI.GetAnimation(animationName);
            ChromaAnimationAPI.GetFrame(animationId, frameId, out duration, tempColors, size);
            for (int i = 0; i < size; ++i)
            {
                int color1    = colors[i];     //target
                int tempColor = tempColors[i]; //source

                // BLEND
                int color2;
                if (effect._mBlend == "none")
                {
                    color2 = tempColor; //source
                }
                else if (effect._mBlend == "invert")
                {
                    if (tempColor != 0)                  //source
                    {
                        color2 = InvertColor(tempColor); //source inverted
                    }
                    else
                    {
                        color2 = 0;
                    }
                }
                else if (effect._mBlend == "thresh")
                {
                    color2 = Thresh(effect._mPrimaryColor, effect._mSecondaryColor, tempColor); //source
                }
                else // if (effect._mBlend == "lerp") //default
                {
                    color2 = MultiplyNonZeroTargetColorLerp(effect._mPrimaryColor, effect._mSecondaryColor, tempColor); //source
                }

                // MODE
                if (effect._mMode == "max")
                {
                    colors[i] = MaxColor(color1, color2);
                }
                else if (effect._mMode == "min")
                {
                    colors[i] = MinColor(color1, color2);
                }
                else if (effect._mMode == "average")
                {
                    colors[i] = AverageColor(color1, color2);
                }
                else if (effect._mMode == "multiply")
                {
                    colors[i] = MultiplyColor(color1, color2);
                }
                else if (effect._mMode == "add")
                {
                    colors[i] = AddColor(color1, color2);
                }
                else if (effect._mMode == "subtract")
                {
                    colors[i] = SubtractColor(color1, color2);
                }
                else // if (effect._mMode == "replace") //default
                {
                    if (color2 != 0)
                    {
                        colors[i] = color2;
                    }
                }
            }
            deviceFrameIndex._mFrameIndex[device] = (frameId + frameCount + effect._mSpeed) % frameCount;
        }
    }
    public IEnumerator Start()
    {
        ChromaAnimationAPI._sStreamingAssetPath = Application.streamingAssetsPath;

        ChromaSDK.APPINFOTYPE appInfo = new APPINFOTYPE();
        appInfo.Title       = "Razer Chroma CSharp Game Loop Sample Application";
        appInfo.Description = "A sample application using Razer Chroma SDK";

        appInfo.Author_Name    = "Razer";
        appInfo.Author_Contact = "https://developer.razer.com/chroma";

        //appInfo.SupportedDevice =
        //    0x01 | // Keyboards
        //    0x02 | // Mice
        //    0x04 | // Headset
        //    0x08 | // Mousepads
        //    0x10 | // Keypads
        //    0x20   // ChromaLink devices
        //    ;
        appInfo.SupportedDevice = (0x01 | 0x02 | 0x04 | 0x08 | 0x10 | 0x20);
        appInfo.Category        = 1;
        int result = ChromaAnimationAPI.InitSDK(ref appInfo);

        switch (result)
        {
        case RazerErrors.RZRESULT_DLL_NOT_FOUND:
            Debug.LogError(string.Format("Chroma DLL is not found! {0}", RazerErrors.GetResultString(result)));
            yield break;

        case RazerErrors.RZRESULT_DLL_INVALID_SIGNATURE:
            Debug.LogError(string.Format("Chroma DLL has an invalid signature! {0}", RazerErrors.GetResultString(result)));
            yield break;

        case RazerErrors.RZRESULT_SUCCESS:
            Debug.Log("ChromaSDK initialized!");
            yield return(new WaitForSeconds(0.1f));

            break;

        default:
            Debug.LogError(string.Format("Failed to initialize Chroma! {0}", RazerErrors.GetResultString(result)));
            yield break;
        }

        // setup scene
        _mScene = new Scene();

        Effect effect = new Effect();

        effect._mAnimation = "Animations/Landscape";
        effect._mSpeed     = 1;
        effect._mBlend     = "none";
        effect._mState     = false;
        effect._mMode      = "replace";
        _mScene._mEffects.Add(effect);
        _mIndexLandscape = (int)_mScene._mEffects.Count - 1;

        effect             = new Effect();
        effect._mAnimation = "Animations/Fire";
        effect._mSpeed     = 1;
        effect._mBlend     = "none";
        effect._mState     = false;
        effect._mMode      = "replace";
        _mScene._mEffects.Add(effect);
        _mIndexFire = (int)_mScene._mEffects.Count - 1;

        effect             = new Effect();
        effect._mAnimation = "Animations/Rainbow";
        effect._mSpeed     = 1;
        effect._mBlend     = "none";
        effect._mState     = false;
        effect._mMode      = "replace";
        _mScene._mEffects.Add(effect);
        _mIndexRainbow = (int)_mScene._mEffects.Count - 1;

        effect             = new Effect();
        effect._mAnimation = "Animations/Spiral";
        effect._mSpeed     = 1;
        effect._mBlend     = "none";
        effect._mState     = false;
        effect._mMode      = "replace";
        _mScene._mEffects.Add(effect);
        _mIndexSpiral = (int)_mScene._mEffects.Count - 1;

        ThreadStart ts = new ThreadStart(GameLoop);

        _mThread = new Thread(ts);
        _mThread.Start();
    }