|
38 | 38 | # include "velocikey.h"
|
39 | 39 | #endif
|
40 | 40 |
|
| 41 | +#ifndef MIN |
| 42 | +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) |
| 43 | +#endif |
| 44 | + |
41 | 45 | #ifdef RGBLIGHT_SPLIT
|
42 | 46 | /* for split keyboard */
|
43 | 47 | # define RGBLIGHT_SPLIT_SET_CHANGE_MODE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_MODE
|
44 | 48 | # define RGBLIGHT_SPLIT_SET_CHANGE_HSVS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_HSVS
|
45 | 49 | # define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS rgblight_status.change_flags |= (RGBLIGHT_STATUS_CHANGE_MODE | RGBLIGHT_STATUS_CHANGE_HSVS)
|
| 50 | +# define RGBLIGHT_SPLIT_SET_CHANGE_LAYERS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_LAYERS |
46 | 51 | # define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_TIMER
|
47 | 52 | # define RGBLIGHT_SPLIT_ANIMATION_TICK rgblight_status.change_flags |= RGBLIGHT_STATUS_ANIMATION_TICK
|
48 | 53 | #else
|
49 | 54 | # define RGBLIGHT_SPLIT_SET_CHANGE_MODE
|
50 | 55 | # define RGBLIGHT_SPLIT_SET_CHANGE_HSVS
|
51 | 56 | # define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS
|
| 57 | +# define RGBLIGHT_SPLIT_SET_CHANGE_LAYERS |
52 | 58 | # define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE
|
53 | 59 | # define RGBLIGHT_SPLIT_ANIMATION_TICK
|
54 | 60 | #endif
|
@@ -97,6 +103,10 @@ LED_TYPE led[RGBLED_NUM];
|
97 | 103 | # define LED_ARRAY led
|
98 | 104 | #endif
|
99 | 105 |
|
| 106 | +#ifdef RGBLIGHT_LAYERS |
| 107 | +rgblight_segment_t const * const *rgblight_layers = NULL; |
| 108 | +#endif |
| 109 | + |
100 | 110 | static uint8_t clipping_start_pos = 0;
|
101 | 111 | static uint8_t clipping_num_leds = RGBLED_NUM;
|
102 | 112 | static uint8_t effect_start_pos = 0;
|
@@ -604,11 +614,67 @@ void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_se
|
604 | 614 | void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val) { rgblight_sethsv_range(hue, sat, val, (uint8_t)RGBLED_NUM / 2, (uint8_t)RGBLED_NUM); }
|
605 | 615 | #endif // ifndef RGBLIGHT_SPLIT
|
606 | 616 |
|
| 617 | +#ifdef RGBLIGHT_LAYERS |
| 618 | +void rgblight_set_layer_state(uint8_t layer, bool enabled) { |
| 619 | + uint8_t mask = 1 << layer; |
| 620 | + if (enabled) { |
| 621 | + rgblight_status.enabled_layer_mask |= mask; |
| 622 | + } else { |
| 623 | + rgblight_status.enabled_layer_mask &= ~mask; |
| 624 | + } |
| 625 | + RGBLIGHT_SPLIT_SET_CHANGE_LAYERS; |
| 626 | + // Static modes don't have a ticker running to update the LEDs |
| 627 | + if (rgblight_status.timer_enabled == false) { |
| 628 | + rgblight_mode_noeeprom(rgblight_config.mode); |
| 629 | + } |
| 630 | +} |
| 631 | + |
| 632 | +bool rgblight_get_layer_state(uint8_t layer) { |
| 633 | + uint8_t mask = 1 << layer; |
| 634 | + return (rgblight_status.enabled_layer_mask & mask) != 0; |
| 635 | +} |
| 636 | + |
| 637 | +// Write any enabled LED layers into the buffer |
| 638 | +static void rgblight_layers_write(void) { |
| 639 | + uint8_t i = 0; |
| 640 | + // For each layer |
| 641 | + for (const rgblight_segment_t * const *layer_ptr = rgblight_layers; i < RGBLIGHT_MAX_LAYERS; layer_ptr++, i++) { |
| 642 | + if (!rgblight_get_layer_state(i)) { |
| 643 | + continue; // Layer is disabled |
| 644 | + } |
| 645 | + const rgblight_segment_t * segment_ptr = pgm_read_ptr(layer_ptr); |
| 646 | + if (segment_ptr == NULL) { |
| 647 | + break; // No more layers |
| 648 | + } |
| 649 | + // For each segment |
| 650 | + while (1) { |
| 651 | + rgblight_segment_t segment; |
| 652 | + memcpy_P(&segment, segment_ptr, sizeof(rgblight_segment_t)); |
| 653 | + if (segment.index == RGBLIGHT_END_SEGMENT_INDEX) { |
| 654 | + break; // No more segments |
| 655 | + } |
| 656 | + // Write segment.count LEDs |
| 657 | + LED_TYPE * const limit = &led[MIN(segment.index + segment.count, RGBLED_NUM)]; |
| 658 | + for (LED_TYPE *led_ptr = &led[segment.index]; led_ptr < limit; led_ptr++) { |
| 659 | + sethsv(segment.hue, segment.sat, segment.val, led_ptr); |
| 660 | + } |
| 661 | + segment_ptr++; |
| 662 | + } |
| 663 | + } |
| 664 | +} |
| 665 | +#endif |
| 666 | + |
607 | 667 | #ifndef RGBLIGHT_CUSTOM_DRIVER
|
608 | 668 | void rgblight_set(void) {
|
609 | 669 | LED_TYPE *start_led;
|
610 | 670 | uint16_t num_leds = clipping_num_leds;
|
611 | 671 |
|
| 672 | +# ifdef RGBLIGHT_LAYERS |
| 673 | + if (rgblight_layers != NULL) { |
| 674 | + rgblight_layers_write(); |
| 675 | + } |
| 676 | +# endif |
| 677 | + |
612 | 678 | if (!rgblight_config.enable) {
|
613 | 679 | for (uint8_t i = effect_start_pos; i < effect_end_pos; i++) {
|
614 | 680 | led[i].r = 0;
|
@@ -652,6 +718,11 @@ void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo) {
|
652 | 718 |
|
653 | 719 | /* for split keyboard slave side */
|
654 | 720 | void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom) {
|
| 721 | +# ifdef RGBLIGHT_LAYERS |
| 722 | + if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_LAYERS) { |
| 723 | + rgblight_status.enabled_layer_mask = syncinfo->status.enabled_layer_mask; |
| 724 | + } |
| 725 | +# endif |
655 | 726 | if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_MODE) {
|
656 | 727 | if (syncinfo->config.enable) {
|
657 | 728 | rgblight_config.enable = 1; // == rgblight_enable_noeeprom();
|
|
0 commit comments