/*-------------------------------------------------------------------*\ | RGBController_EVisionV2Keyboard.cpp | | | | Generic RGB Interface for EVision V2 RGB Keyboard | | | | Le Philousophe 25 Dec 2022 | \*-------------------------------------------------------------------*/ #define NA 0xFFFFFFFF #include #include "hsv.h" #include "RGBControllerKeyNames.h" #include "RGBController_EVisionV2Keyboard.h" using namespace std::chrono_literals; static unsigned int evisionv2_matrix[EVISION_V2_MATRIX_HEIGHT][EVISION_V2_MATRIX_WIDTH] = { /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 19 20 */ { 0, NA, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, NA, NA, NA, NA }, { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }, { 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 }, { 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, NA, NA, NA, 72, 73, 74, NA }, { 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, NA, 87, NA, 88, NA, 89, 90, 91, 92 }, { 93, 94, 95, NA, NA, NA, 96, NA, NA, NA, 97, 98, 99, 100, 101, 102, 103, NA, 104, 105, NA } }; static unsigned int endorfy_matrix[EVISION_V2_MATRIX_HEIGHT][EVISION_V2_MATRIX_WIDTH] = { /* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 19 20 */ { 0, NA, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, NA, NA, NA, NA }, { 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36 }, { 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57 }, { 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, NA, 70, NA, NA, NA, 71, 72, 73, NA }, { 74, NA, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, NA, NA, 86, NA, 87, 88, 89, 90 }, { 91, 92, 93, NA, NA, NA, 94, NA, NA, NA, 95, 96, 97, 98, 99, 100, 101, 102, NA, 103, NA } }; static const char *led_evisionv2[] = { KEY_EN_ESCAPE, //00 KEY_EN_F1, KEY_EN_F2, KEY_EN_F3, KEY_EN_F4, KEY_EN_F5, KEY_EN_F6, KEY_EN_F7, KEY_EN_F8, KEY_EN_F9, KEY_EN_F10, //10 KEY_EN_F11, KEY_EN_F12, KEY_EN_PRINT_SCREEN, KEY_EN_SCROLL_LOCK, KEY_EN_PAUSE_BREAK, KEY_EN_BACK_TICK, //16 KEY_EN_1, KEY_EN_2, KEY_EN_3, KEY_EN_4, //20 KEY_EN_5, KEY_EN_6, KEY_EN_7, KEY_EN_8, KEY_EN_9, KEY_EN_0, KEY_EN_MINUS, KEY_EN_EQUALS, KEY_EN_BACKSPACE, KEY_EN_INSERT, KEY_EN_HOME, //30 KEY_EN_PAGE_UP, KEY_EN_NUMPAD_LOCK, KEY_EN_NUMPAD_DIVIDE, KEY_EN_NUMPAD_TIMES, KEY_EN_NUMPAD_MINUS, KEY_EN_TAB, //37 KEY_EN_Q, KEY_EN_W, KEY_EN_E, //40 KEY_EN_R, KEY_EN_T, KEY_EN_Y, KEY_EN_U, KEY_EN_I, KEY_EN_O, KEY_EN_P, KEY_EN_LEFT_BRACKET, KEY_EN_RIGHT_BRACKET, KEY_EN_ANSI_BACK_SLASH, //50 KEY_EN_DELETE, KEY_EN_END, KEY_EN_PAGE_DOWN, KEY_EN_NUMPAD_7, KEY_EN_NUMPAD_8, KEY_EN_NUMPAD_9, KEY_EN_NUMPAD_PLUS, KEY_EN_CAPS_LOCK, //58 KEY_EN_A, KEY_EN_S, KEY_EN_D, KEY_EN_F, KEY_EN_G, KEY_EN_H, KEY_EN_J, KEY_EN_K, KEY_EN_L, KEY_EN_SEMICOLON, KEY_EN_QUOTE, KEY_EN_POUND, //70 KEY_EN_ISO_ENTER, KEY_EN_NUMPAD_4, KEY_EN_NUMPAD_5, KEY_EN_NUMPAD_6, KEY_EN_LEFT_SHIFT, //75 KEY_EN_ISO_BACK_SLASH, KEY_EN_Z, KEY_EN_X, KEY_EN_C, KEY_EN_V, //80 KEY_EN_B, KEY_EN_N, KEY_EN_M, KEY_EN_COMMA, KEY_EN_PERIOD, KEY_EN_FORWARD_SLASH, KEY_EN_RIGHT_SHIFT, KEY_EN_UP_ARROW, KEY_EN_NUMPAD_1, KEY_EN_NUMPAD_2, //90 KEY_EN_NUMPAD_3, KEY_EN_NUMPAD_ENTER, KEY_EN_LEFT_CONTROL, //93 KEY_EN_LEFT_WINDOWS, KEY_EN_LEFT_ALT, KEY_EN_SPACE, KEY_EN_RIGHT_ALT, KEY_EN_RIGHT_WINDOWS, KEY_EN_RIGHT_FUNCTION, KEY_EN_RIGHT_CONTROL, //100 KEY_EN_LEFT_ARROW, KEY_EN_DOWN_ARROW, KEY_EN_RIGHT_ARROW, KEY_EN_NUMPAD_0, KEY_EN_NUMPAD_PERIOD, }; static const char *led_endorfy[] = { KEY_EN_ESCAPE, //00 KEY_EN_F1, KEY_EN_F2, KEY_EN_F3, KEY_EN_F4, KEY_EN_F5, KEY_EN_F6, KEY_EN_F7, KEY_EN_F8, KEY_EN_F9, KEY_EN_F10, //10 KEY_EN_F11, KEY_EN_F12, KEY_EN_PRINT_SCREEN, KEY_EN_SCROLL_LOCK, KEY_EN_PAUSE_BREAK, KEY_EN_BACK_TICK, //16 KEY_EN_1, KEY_EN_2, KEY_EN_3, KEY_EN_4, //20 KEY_EN_5, KEY_EN_6, KEY_EN_7, KEY_EN_8, KEY_EN_9, KEY_EN_0, KEY_EN_MINUS, KEY_EN_EQUALS, KEY_EN_BACKSPACE, KEY_EN_INSERT, KEY_EN_HOME, //30 KEY_EN_PAGE_UP, KEY_EN_NUMPAD_LOCK, KEY_EN_NUMPAD_DIVIDE, KEY_EN_NUMPAD_TIMES, KEY_EN_NUMPAD_MINUS, KEY_EN_TAB, //37 KEY_EN_Q, KEY_EN_W, KEY_EN_E, //40 KEY_EN_R, KEY_EN_T, KEY_EN_Y, KEY_EN_U, KEY_EN_I, KEY_EN_O, KEY_EN_P, KEY_EN_LEFT_BRACKET, KEY_EN_RIGHT_BRACKET, KEY_EN_ANSI_BACK_SLASH, //50 KEY_EN_DELETE, KEY_EN_END, KEY_EN_PAGE_DOWN, KEY_EN_NUMPAD_7, KEY_EN_NUMPAD_8, KEY_EN_NUMPAD_9, KEY_EN_NUMPAD_PLUS, KEY_EN_CAPS_LOCK, //58 KEY_EN_A, KEY_EN_S, KEY_EN_D, KEY_EN_F, KEY_EN_G, KEY_EN_H, KEY_EN_J, KEY_EN_K, KEY_EN_L, KEY_EN_SEMICOLON, KEY_EN_QUOTE, KEY_EN_ANSI_ENTER, //70 KEY_EN_NUMPAD_4, KEY_EN_NUMPAD_5, KEY_EN_NUMPAD_6, KEY_EN_LEFT_SHIFT, KEY_EN_Z, //75 KEY_EN_X, KEY_EN_C, KEY_EN_V, KEY_EN_B, //80 KEY_EN_N, KEY_EN_M, KEY_EN_COMMA, KEY_EN_PERIOD, KEY_EN_FORWARD_SLASH, KEY_EN_RIGHT_SHIFT, KEY_EN_UP_ARROW, KEY_EN_NUMPAD_1, KEY_EN_NUMPAD_2, KEY_EN_NUMPAD_3, //90 KEY_EN_NUMPAD_ENTER, KEY_EN_LEFT_CONTROL, KEY_EN_LEFT_WINDOWS, //93 KEY_EN_LEFT_ALT, KEY_EN_SPACE, KEY_EN_RIGHT_ALT, KEY_EN_RIGHT_FUNCTION, KEY_EN_MENU, KEY_EN_RIGHT_CONTROL, KEY_EN_LEFT_ARROW, //100 KEY_EN_DOWN_ARROW, KEY_EN_RIGHT_ARROW, KEY_EN_NUMPAD_0, KEY_EN_NUMPAD_PERIOD, }; /**------------------------------------------------------------------*\ @name EVision V2 Keyboard @category Keyboard @type USB @save :white_check_mark: @direct :white_check_mark: @effects :white_check_mark: @detectors DetectEVisionV2Keyboard @comment The Evision V2 controller implements all hardware modes found in the OEM software. Some options may not be named correctly like directions for some modes. \*-------------------------------------------------------------------*/ RGBController_EVisionV2Keyboard::RGBController_EVisionV2Keyboard(EVisionV2KeyboardController* controller_ptr, EVisionV2KeyboardPart part_) { controller = controller_ptr; part = part_; name = "EVision Keyboard Device"; vendor = "Evision"; type = DEVICE_TYPE_KEYBOARD; description = "EVision Keyboard Device"; location = controller->GetLocation(); serial = controller->GetSerial(); layout = controller->layout; switch(part) { case EVISION_V2_KEYBOARD_PART_KEYBOARD: SetupKeyboardModes(); break; case EVISION_V2_KEYBOARD_PART_LOGO: case EVISION_V2_KEYBOARD_PART_EDGE: SetupLogoEdgeModes(); break; case ENDORFY_KEYBOARD_PART_EDGE: SetupEdgeModes(); break; } SetupZones(); LoadConfig(); keepalive_thread_run = false; keepalive_thread = nullptr; if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD) { keepalive_thread_run = true; keepalive_thread = new std::thread(&RGBController_EVisionV2Keyboard::KeepaliveThread, this); } } RGBController_EVisionV2Keyboard::~RGBController_EVisionV2Keyboard() { if(keepalive_thread) { keepalive_thread_run = false; keepalive_thread->join(); delete keepalive_thread; } delete controller; } void RGBController_EVisionV2Keyboard::SetupKeyboardModes() { mode Direct; Direct.name = "Direct"; Direct.value = EVISION_V2_MODE_DIRECT; Direct.flags = MODE_FLAG_HAS_PER_LED_COLOR; Direct.color_mode = MODE_COLORS_PER_LED; modes.push_back(Direct); mode ColorWave; ColorWave.name = "Color Wave short"; ColorWave.value = EVISION_V2_MODE_COLOR_WAVE_SHORT; ColorWave.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; ColorWave.speed_min = EVISION_V2_SPEED_SLOWEST; ColorWave.speed_max = EVISION_V2_SPEED_FASTEST; ColorWave.speed = EVISION_V2_SPEED_NORMAL; ColorWave.colors_min = 1; ColorWave.colors_max = 1; ColorWave.color_mode = MODE_COLORS_RANDOM; ColorWave.colors.resize(1); ColorWave.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; ColorWave.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; ColorWave.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(ColorWave); mode ColorWaveLong; ColorWaveLong.name = "Color Wave long"; ColorWaveLong.value = EVISION_V2_MODE_COLOR_WAVE_LONG; ColorWaveLong.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; ColorWaveLong.speed_min = EVISION_V2_SPEED_SLOWEST; ColorWaveLong.speed_max = EVISION_V2_SPEED_FASTEST; ColorWaveLong.speed = EVISION_V2_SPEED_NORMAL; ColorWaveLong.colors_min = 1; ColorWaveLong.colors_max = 1; ColorWaveLong.color_mode = MODE_COLORS_RANDOM; ColorWaveLong.colors.resize(1); ColorWaveLong.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; ColorWaveLong.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; ColorWaveLong.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(ColorWaveLong); mode ColorWheel; ColorWheel.name = "Color Wheel"; ColorWheel.value = EVISION_V2_MODE_COLOR_WHEEL; ColorWheel.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; ColorWheel.speed_min = EVISION_V2_SPEED_SLOWEST; ColorWheel.speed_max = EVISION_V2_SPEED_FASTEST; ColorWheel.speed = EVISION_V2_SPEED_NORMAL; ColorWheel.colors_min = 1; ColorWheel.colors_max = 1; ColorWheel.color_mode = MODE_COLORS_RANDOM; ColorWheel.colors.resize(1); ColorWheel.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; ColorWheel.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; ColorWheel.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(ColorWheel); mode SpectrumCycle; SpectrumCycle.name = "Spectrum Cycle"; SpectrumCycle.value = EVISION_V2_MODE_SPECTRUM_CYCLE; SpectrumCycle.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; SpectrumCycle.speed_min = EVISION_V2_SPEED_SLOWEST; SpectrumCycle.speed_max = EVISION_V2_SPEED_FASTEST; SpectrumCycle.speed = EVISION_V2_SPEED_NORMAL; SpectrumCycle.color_mode = MODE_COLORS_NONE; SpectrumCycle.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; SpectrumCycle.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; SpectrumCycle.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(SpectrumCycle); mode Breathing; Breathing.name = "Breathing"; Breathing.value = EVISION_V2_MODE_BREATHING; Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Breathing.speed_min = EVISION_V2_SPEED_SLOWEST; Breathing.speed_max = EVISION_V2_SPEED_FASTEST; Breathing.speed = EVISION_V2_SPEED_NORMAL; Breathing.colors_min = 1; Breathing.colors_max = 1; Breathing.color_mode = MODE_COLORS_RANDOM; Breathing.colors.resize(1); Breathing.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Breathing.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Breathing.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Breathing); mode Static; Static.name = "Static"; Static.value = EVISION_V2_MODE_STATIC; Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Static.colors_min = 1; Static.colors_max = 1; Static.color_mode = MODE_COLORS_RANDOM; Static.colors.resize(1); Static.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Static.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Static.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Static); mode Reactive; Reactive.name = "Reactive"; Reactive.value = EVISION_V2_MODE_REACTIVE; Reactive.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Reactive.speed_min = EVISION_V2_SPEED_SLOWEST; Reactive.speed_max = EVISION_V2_SPEED_FASTEST; Reactive.speed = EVISION_V2_SPEED_NORMAL; Reactive.colors_min = 1; Reactive.colors_max = 1; Reactive.color_mode = MODE_COLORS_RANDOM; Reactive.colors.resize(1); Reactive.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Reactive.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Reactive.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Reactive); mode ReactiveRipple; ReactiveRipple.name = "Reactive Ripple"; ReactiveRipple.value = EVISION_V2_MODE_REACTIVE_RIPPLE; ReactiveRipple.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; ReactiveRipple.speed_min = EVISION_V2_SPEED_SLOWEST; ReactiveRipple.speed_max = EVISION_V2_SPEED_FASTEST; ReactiveRipple.speed = EVISION_V2_SPEED_NORMAL; ReactiveRipple.colors_min = 1; ReactiveRipple.colors_max = 1; ReactiveRipple.color_mode = MODE_COLORS_RANDOM; ReactiveRipple.colors.resize(1); ReactiveRipple.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; ReactiveRipple.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; ReactiveRipple.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(ReactiveRipple); mode ReactiveLine; ReactiveLine.name = "Reactive Line"; ReactiveLine.value = EVISION_V2_MODE_REACTIVE_LINE; ReactiveLine.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; ReactiveLine.speed_min = EVISION_V2_SPEED_SLOWEST; ReactiveLine.speed_max = EVISION_V2_SPEED_FASTEST; ReactiveLine.speed = EVISION_V2_SPEED_NORMAL; ReactiveLine.colors_min = 1; ReactiveLine.colors_max = 1; ReactiveLine.color_mode = MODE_COLORS_RANDOM; ReactiveLine.colors.resize(1); ReactiveLine.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; ReactiveLine.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; ReactiveLine.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(ReactiveLine); mode Starlight; Starlight.name = "Starlight"; Starlight.value = EVISION_V2_MODE_STARLIGHT_FAST; Starlight.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Starlight.speed_min = EVISION_V2_SPEED_SLOWEST; Starlight.speed_max = EVISION_V2_SPEED_FASTEST; Starlight.speed = EVISION_V2_SPEED_NORMAL; Starlight.colors_min = 1; Starlight.colors_max = 1; Starlight.color_mode = MODE_COLORS_RANDOM; Starlight.colors.resize(1); Starlight.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Starlight.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Starlight.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Starlight); mode Blooming; Blooming.name = "Blooming"; Blooming.value = EVISION_V2_MODE_BLOOMING; Blooming.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Blooming.speed_min = EVISION_V2_SPEED_SLOWEST; Blooming.speed_max = EVISION_V2_SPEED_FASTEST; Blooming.speed = EVISION_V2_SPEED_NORMAL; Blooming.color_mode = MODE_COLORS_NONE; Blooming.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Blooming.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Blooming.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Blooming); mode RainbowWaveVertical; RainbowWaveVertical.name = "Rainbow Wave vertical"; RainbowWaveVertical.value = EVISION_V2_MODE_RAINBOW_WAVE_VERTICAL; RainbowWaveVertical.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_DIRECTION_UD | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; RainbowWaveVertical.speed_min = EVISION_V2_SPEED_SLOWEST; RainbowWaveVertical.speed_max = EVISION_V2_SPEED_FASTEST; RainbowWaveVertical.speed = EVISION_V2_SPEED_NORMAL; RainbowWaveVertical.color_mode = MODE_COLORS_NONE; RainbowWaveVertical.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; RainbowWaveVertical.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; RainbowWaveVertical.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(RainbowWaveVertical); mode Hurricane; Hurricane.name = "Hurricane"; Hurricane.value = EVISION_V2_MODE_HURRICANE; Hurricane.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Hurricane.speed_min = EVISION_V2_SPEED_SLOWEST; Hurricane.speed_max = EVISION_V2_SPEED_FASTEST; Hurricane.speed = EVISION_V2_SPEED_NORMAL; Hurricane.colors_min = 1; Hurricane.colors_max = 1; Hurricane.color_mode = MODE_COLORS_RANDOM; Hurricane.colors.resize(1); Hurricane.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Hurricane.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Hurricane.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Hurricane); mode Accumulate; Accumulate.name = "Accumulate"; Accumulate.value = EVISION_V2_MODE_ACCUMULATE; Accumulate.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Accumulate.speed_min = EVISION_V2_SPEED_SLOWEST; Accumulate.speed_max = EVISION_V2_SPEED_FASTEST; Accumulate.speed = EVISION_V2_SPEED_NORMAL; Accumulate.colors_min = 1; Accumulate.colors_max = 1; Accumulate.color_mode = MODE_COLORS_RANDOM; Accumulate.colors.resize(1); Accumulate.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Accumulate.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Accumulate.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Accumulate); mode StarlightSlow; StarlightSlow.name = "Starlight slow"; StarlightSlow.value = EVISION_V2_MODE_STARLIGHT_SLOW; StarlightSlow.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; StarlightSlow.speed_min = EVISION_V2_SPEED_SLOWEST; StarlightSlow.speed_max = EVISION_V2_SPEED_FASTEST; StarlightSlow.speed = EVISION_V2_SPEED_NORMAL; StarlightSlow.colors_min = 1; StarlightSlow.colors_max = 1; StarlightSlow.color_mode = MODE_COLORS_RANDOM; StarlightSlow.colors.resize(1); StarlightSlow.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; StarlightSlow.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; StarlightSlow.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(StarlightSlow); mode Visor; Visor.name = "Visor"; Visor.value = EVISION_V2_MODE_VISOR; Visor.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Visor.speed_min = EVISION_V2_SPEED_SLOWEST; Visor.speed_max = EVISION_V2_SPEED_FASTEST; Visor.speed = EVISION_V2_SPEED_NORMAL; Visor.colors_min = 1; Visor.colors_max = 1; Visor.color_mode = MODE_COLORS_RANDOM; Visor.colors.resize(1); Visor.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Visor.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Visor.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Visor); mode Surmount; Surmount.name = "Surmount"; Surmount.value = EVISION_V2_MODE_SURMOUNT; Surmount.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Surmount.colors_min = 1; Surmount.colors_max = 1; Surmount.color_mode = MODE_COLORS_MODE_SPECIFIC; Surmount.colors.resize(1); Surmount.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Surmount.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Surmount.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Surmount); mode RainbowCircle; RainbowCircle.name = "Rainbow Circle"; RainbowCircle.value = EVISION_V2_MODE_RAINBOW_WAVE_CIRCLE; RainbowCircle.flags = MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; RainbowCircle.color_mode = MODE_COLORS_NONE; RainbowCircle.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; RainbowCircle.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; RainbowCircle.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(RainbowCircle); for(unsigned int i = 0; i < 10; i++) { mode Custom; Custom.name = "Custom "; Custom.name += std::to_string(i+1); Custom.value = EVISION_V2_MODE_CUSTOM | i << 8; Custom.flags = MODE_FLAG_HAS_PER_LED_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_MANUAL_SAVE; Custom.color_mode = MODE_COLORS_PER_LED; Custom.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Custom.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Custom.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Custom); } } void RGBController_EVisionV2Keyboard::SetupLogoEdgeModes() { mode ColorWave; ColorWave.name = "Color Wave"; ColorWave.value = EVISION_V2_MODE2_COLOR_WAVE; ColorWave.flags = MODE_FLAG_HAS_DIRECTION_LR | MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; ColorWave.speed_min = EVISION_V2_SPEED_SLOWEST; ColorWave.speed_max = EVISION_V2_SPEED_FASTEST; ColorWave.speed = EVISION_V2_SPEED_NORMAL; ColorWave.colors_min = 1; ColorWave.colors_max = 1; ColorWave.color_mode = MODE_COLORS_RANDOM; ColorWave.colors.resize(1); ColorWave.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; ColorWave.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; ColorWave.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(ColorWave); mode Breathing; Breathing.name = "Breathing"; Breathing.value = EVISION_V2_MODE2_BREATHING; Breathing.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Breathing.speed_min = EVISION_V2_SPEED_SLOWEST; Breathing.speed_max = EVISION_V2_SPEED_FASTEST; Breathing.speed = EVISION_V2_SPEED_NORMAL; Breathing.colors_min = 1; Breathing.colors_max = 1; Breathing.color_mode = MODE_COLORS_RANDOM; Breathing.colors.resize(1); Breathing.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Breathing.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Breathing.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Breathing); mode Yoyo; Yoyo.name = "Yoyo"; Yoyo.value = EVISION_V2_MODE2_YOYO; Yoyo.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Yoyo.speed_min = EVISION_V2_SPEED_SLOWEST; Yoyo.speed_max = EVISION_V2_SPEED_FASTEST; Yoyo.speed = EVISION_V2_SPEED_NORMAL; Yoyo.colors_min = 1; Yoyo.colors_max = 1; Yoyo.color_mode = MODE_COLORS_RANDOM; Yoyo.colors.resize(1); Yoyo.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Yoyo.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Yoyo.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Yoyo); mode Blink; Blink.name = "Blink"; Blink.value = EVISION_V2_MODE2_BLINK; Blink.flags = MODE_FLAG_HAS_SPEED | MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Blink.speed_min = EVISION_V2_SPEED_SLOWEST; Blink.speed_max = EVISION_V2_SPEED_FASTEST; Blink.speed = EVISION_V2_SPEED_NORMAL; Blink.colors_min = 1; Blink.colors_max = 1; Blink.color_mode = MODE_COLORS_RANDOM; Blink.colors.resize(1); Blink.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Blink.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Blink.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Blink); mode Static; Static.name = "Static"; Static.value = EVISION_V2_MODE2_STATIC; Static.flags = MODE_FLAG_HAS_MODE_SPECIFIC_COLOR | MODE_FLAG_HAS_RANDOM_COLOR | MODE_FLAG_HAS_BRIGHTNESS | MODE_FLAG_AUTOMATIC_SAVE; Static.colors_min = 1; Static.colors_max = 1; Static.color_mode = MODE_COLORS_RANDOM; Static.colors.resize(1); Static.brightness_min = EVISION_V2_BRIGHTNESS_LOWEST; Static.brightness_max = EVISION_V2_BRIGHTNESS_HIGHEST; Static.brightness = EVISION_V2_BRIGHTNESS_HIGHEST; modes.push_back(Static); mode Off; Off.name = "Off"; Off.value = EVISION_V2_MODE2_OFF; Off.flags = MODE_FLAG_AUTOMATIC_SAVE; modes.push_back(Off); } void RGBController_EVisionV2Keyboard::SetupEdgeModes() { mode Freeze; Freeze.name = "Freeze"; Freeze.value = ENDORFY_MODE2_FREEZE; Freeze.flags = MODE_FLAG_AUTOMATIC_SAVE; modes.push_back(Freeze); mode ColorWave; ColorWave.name = "Color Wave"; ColorWave.value = ENDORFY_MODE2_COLOR_WAVE; ColorWave.flags = MODE_FLAG_AUTOMATIC_SAVE; modes.push_back(ColorWave); mode Spectrum; Spectrum.name = "Spectrum Cycle"; Spectrum.value = ENDORFY_MODE2_SPECTRUM_CYCLE; Spectrum.flags = MODE_FLAG_AUTOMATIC_SAVE; modes.push_back(Spectrum); mode Breathing; Breathing.name = "Breathing"; Breathing.value = ENDORFY_MODE2_BREATHING; Breathing.flags = MODE_FLAG_AUTOMATIC_SAVE; modes.push_back(Breathing); mode Static; Static.name = "Static"; Static.value = ENDORFY_MODE2_STATIC; Static.flags = MODE_FLAG_AUTOMATIC_SAVE; modes.push_back(Static); mode Off; Off.name = "Off"; Off.value = ENDORFY_MODE2_OFF; Off.flags = MODE_FLAG_AUTOMATIC_SAVE; modes.push_back(Off); } void RGBController_EVisionV2Keyboard::SetupZones() { unsigned short leds_count; unsigned int *matrix_map; const char **led_names; switch(layout) { case EVISION_V2_KEYBOARD_LAYOUT: led_names = led_evisionv2; matrix_map = (unsigned int *)evisionv2_matrix; leds_count = 106; break; case ENDORFY_KEYBOARD_LAYOUT: led_names = led_endorfy; matrix_map = (unsigned int *)endorfy_matrix; leds_count = 104; break; } /*-------------------------------------------------*\ | Clear any existing color/LED configuration | \*-------------------------------------------------*/ zone KB_zone; KB_zone.name = ZONE_EN_KEYBOARD; KB_zone.type = ZONE_TYPE_MATRIX; KB_zone.leds_count = leds_count; KB_zone.leds_min = KB_zone.leds_count; KB_zone.leds_max = KB_zone.leds_count; KB_zone.matrix_map = new matrix_map_type; KB_zone.matrix_map->height = EVISION_V2_MATRIX_HEIGHT; KB_zone.matrix_map->width = EVISION_V2_MATRIX_WIDTH; KB_zone.matrix_map->map = matrix_map; zones.push_back(KB_zone); /*-------------------------------------------------*\ | Clear any existing color/LED configuration | \*-------------------------------------------------*/ leds.clear(); colors.clear(); /*---------------------------------------------------------*\ | Set up zones | \*---------------------------------------------------------*/ for(std::size_t zone_index = 0; zone_index < zones.size(); zone_index++) { for(unsigned int led_index = 0; led_index < zones[zone_index].leds_count; led_index++) { led new_led; new_led.name = led_names[led_index]; new_led.value = led_index; leds.push_back(new_led); } } SetupColors(); } void RGBController_EVisionV2Keyboard::LoadConfig() { EvisionV2ModeConfig config; controller->GetMode(part, config); int mode = config.mode; if((part == EVISION_V2_KEYBOARD_PART_KEYBOARD) && (mode == EVISION_V2_MODE_CUSTOM)) { mode |= config.ledmode << 8; } config.direction = (config.direction == 0) ? 0 : 1; // Define default colors for(int mode_index = 0; mode_index < (int)modes.size(); mode_index++) { if(config.random_colours) { if(modes[mode_index].flags & MODE_FLAG_HAS_RANDOM_COLOR) { modes[mode_index].color_mode = MODE_COLORS_RANDOM; } if(modes[mode_index].colors.size() > 0) { modes[mode_index].colors[0] = 0xffffff; } } else { if(modes[mode_index].flags & MODE_FLAG_HAS_MODE_SPECIFIC_COLOR) { modes[mode_index].color_mode = MODE_COLORS_MODE_SPECIFIC; } if(modes[mode_index].colors.size() > 0) { modes[mode_index].colors[0] = config.colour; } } if(modes[mode_index].value == mode) { modes[mode_index].brightness = config.brightness; modes[mode_index].speed = config.speed; if(modes[mode_index].flags & MODE_FLAG_HAS_DIRECTION_LR) { modes[mode_index].direction = (1 - config.direction) + MODE_DIRECTION_LEFT; } else if(modes[mode_index].flags & MODE_FLAG_HAS_DIRECTION_UD) { modes[mode_index].direction = (1 - config.direction) + MODE_DIRECTION_UP; } else if(modes[mode_index].flags & MODE_FLAG_HAS_DIRECTION_HV) { modes[mode_index].direction = (1 - config.direction) + MODE_DIRECTION_HORIZONTAL; } if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD) { if(mode == EVISION_V2_MODE_SURMOUNT) { switch(config.ledmode) { case EVISION_V2_SURMOUNT_MODE_COLOR_RED: modes[mode_index].colors[0] = ToRGBColor(0xff, 0, 0); break; case EVISION_V2_SURMOUNT_MODE_COLOR_YELLOW: modes[mode_index].colors[0] = ToRGBColor(0xff, 0xff, 0); break; case EVISION_V2_SURMOUNT_MODE_COLOR_GREEN: modes[mode_index].colors[0] = ToRGBColor(0, 0xff, 0); break; case EVISION_V2_SURMOUNT_MODE_COLOR_CYAN: modes[mode_index].colors[0] = ToRGBColor(0, 0xff, 0xff); break; default: break; } } else if(config.mode == EVISION_V2_MODE_CUSTOM) { controller->GetLedsCustom(config.ledmode, colors); } } active_mode = mode_index; } } } void RGBController_EVisionV2Keyboard::ResizeZone(int /*zone*/, int /*new_size*/) { /*---------------------------------------------------------*\ | This device does not support resizing zones | \*---------------------------------------------------------*/ } void RGBController_EVisionV2Keyboard::DeviceUpdateLEDs() { if(part != EVISION_V2_KEYBOARD_PART_KEYBOARD) { return; } controller->SetLedsDirect(colors); has_color_set = true; last_update_time = std::chrono::steady_clock::now(); } void RGBController_EVisionV2Keyboard::UpdateZoneLEDs(int /*zone*/) { DeviceUpdateLEDs(); } void RGBController_EVisionV2Keyboard::UpdateSingleLED(int led) { if(part != EVISION_V2_KEYBOARD_PART_KEYBOARD) { return; } controller->SetLedDirect(led, colors[led]); has_color_set = true; last_update_time = std::chrono::steady_clock::now(); } void RGBController_EVisionV2Keyboard::SetCustomMode() { if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD) { active_mode = EVISION_V2_MODE_DIRECT; } else { active_mode = EVISION_V2_MODE2_STATIC; } } void RGBController_EVisionV2Keyboard::DeviceUpdateMode() { mode set_mode = modes[active_mode]; // No mode set packets required for Direct mode if((part == EVISION_V2_KEYBOARD_PART_KEYBOARD) && (set_mode.value == EVISION_V2_MODE_DIRECT)) { return; } EvisionV2ModeConfig config; config.mode = set_mode.value & 0xff; config.brightness = set_mode.brightness; config.speed = set_mode.speed; config.direction = 1 - (set_mode.direction & 0x1); config.random_colours = (set_mode.color_mode == MODE_COLORS_RANDOM); config.colour = 0; if(modes[active_mode].colors.size() > 0) { config.colour = set_mode.colors[0]; } config.ledmode = 0; if(part == EVISION_V2_KEYBOARD_PART_KEYBOARD) { if(config.mode == EVISION_V2_MODE_SURMOUNT) { hsv_t temp; rgb2hsv(config.colour, &temp); if(temp.hue <= 30 || temp.hue > 300) { config.ledmode = EVISION_V2_SURMOUNT_MODE_COLOR_RED; } else if(temp.hue > 30 && temp.hue <= 90) { config.ledmode = EVISION_V2_SURMOUNT_MODE_COLOR_YELLOW; } else if(temp.hue > 90 && temp.hue <= 150) { config.ledmode = EVISION_V2_SURMOUNT_MODE_COLOR_GREEN; } else if(temp.hue > 150 && temp.hue <= 300) { config.ledmode = EVISION_V2_SURMOUNT_MODE_COLOR_CYAN; } } else if(config.mode == EVISION_V2_MODE_CUSTOM) { config.ledmode = (set_mode.value >> 8) & 0xff; } } controller->SetMode(part, config); if((part == EVISION_V2_KEYBOARD_PART_KEYBOARD) && (config.mode == EVISION_V2_MODE_CUSTOM)) { controller->GetLedsCustom(config.ledmode, colors); SignalUpdate(); } } void RGBController_EVisionV2Keyboard::DeviceSaveMode() { if(part != EVISION_V2_KEYBOARD_PART_KEYBOARD) { return; } int value = modes[active_mode].value; if((value & 0xff) == EVISION_V2_MODE_CUSTOM) { controller->SetLedsCustom((value >> 8) & 0xff, colors); } } void RGBController_EVisionV2Keyboard::KeepaliveThread() { bool was_active = false; while(keepalive_thread_run.load()) { if(modes[active_mode].value == EVISION_V2_MODE_DIRECT && has_color_set) { if((std::chrono::steady_clock::now() - last_update_time) > std::chrono::milliseconds(200)) { controller->RefreshLedDirect(); last_update_time = std::chrono::steady_clock::now(); was_active = true; } } else if(was_active) { controller->EndLedsDirect(); was_active = false; } std::this_thread::sleep_for(100ms); } controller->EndLedsDirect(); }