diff --git a/keyboards/massdrop/ctrl/keymaps/default/keymap.c b/keyboards/massdrop/ctrl/keymaps/default/keymap.c index ac58f336e3c8..0407e28c63d0 100644 --- a/keyboards/massdrop/ctrl/keymaps/default/keymap.c +++ b/keyboards/massdrop/ctrl/keymaps/default/keymap.c @@ -200,4 +200,16 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { default: return true; //Process all other keycodes normally } -} \ No newline at end of file +} + +led_instruction_t led_instructions[] = { + // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 10, .id1 = 9, .r = 255, .g = 0, .b = 0 }, + // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_PATTERN, .id0 = 4, .id1 = 0, .pattern_id = 8 }, + // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 8, .id1 = 0, .r = 0, .g = 255, .b = 0 }, + // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_PATTERN, .id = 16, .id1 = 0, .pattern_id = 9 }, + // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 32, .id1 = 0, .r = 0, .g = 0, .b = 255 }, + // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_ROTATE_PATTERN, .id0 = 64, .id1 = 0}, + // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_MATCH_LAYER | LED_FLAG_USE_ROTATE_PATTERN, .id0 = 262144, .id1 = 0, .layer = 0 }, + // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_MATCH_LAYER | LED_FLAG_USE_ROTATE_PATTERN, .id = 16777216, .id1 = 0, .layer = 1 }, + { .end = 1 } +}; \ No newline at end of file diff --git a/tmk_core/protocol/arm_atsam/led_matrix.c b/tmk_core/protocol/arm_atsam/led_matrix.c index 7ee1dad224fc..1fbd49c3ce06 100644 --- a/tmk_core/protocol/arm_atsam/led_matrix.c +++ b/tmk_core/protocol/arm_atsam/led_matrix.c @@ -257,12 +257,87 @@ issi3733_led_t *led_cur; uint8_t led_per_run = 15; float breathe_mult; +void led_run_pattern(led_setup_t *f, float* ro, float* go, float* bo) { + float px; + + uint8_t fcur = 0; + uint8_t fmax = 0; + + //Frames setup + while (f[fcur].end != 1) + { + fcur++; //Count frames + } + + fmax = fcur; //Store total frames count + + for (fcur = 0; fcur < fmax; fcur++) + { + px = led_cur->px; + float pxmod; + pxmod = (float)(disp.frame % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed; + + //Add in any moving effects + if ((!led_animation_direction && f[fcur].ef & EF_SCR_R) || (led_animation_direction && (f[fcur].ef & EF_SCR_L))) + { + pxmod *= 100.0f; + pxmod = (uint32_t)pxmod % 10000; + pxmod /= 100.0f; + + px -= pxmod; + + if (px > 100) px -= 100; + else if (px < 0) px += 100; + } + else if ((!led_animation_direction && f[fcur].ef & EF_SCR_L) || (led_animation_direction && (f[fcur].ef & EF_SCR_R))) + { + pxmod *= 100.0f; + pxmod = (uint32_t)pxmod % 10000; + pxmod /= 100.0f; + px += pxmod; + + if (px > 100) px -= 100; + else if (px < 0) px += 100; + } + + //Check if LED's px is in current frame + if (px < f[fcur].hs) continue; + if (px > f[fcur].he) continue; + //note: < 0 or > 100 continue + + //Calculate the px within the start-stop percentage for color blending + px = (px - f[fcur].hs) / (f[fcur].he - f[fcur].hs); + + //Add in any color effects + if (f[fcur].ef & EF_OVER) + { + *ro = (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5; + *go = (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5; + *bo = (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5; + } + else if (f[fcur].ef & EF_SUBTRACT) + { + *ro -= (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5; + *go -= (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5; + *bo -= (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5; + } + else + { + *ro += (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5; + *go += (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5; + *bo += (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5; + } + } +} + +__attribute__((weak)) +led_instruction_t led_instructions[] = { { .end = 1 } }; + void led_matrix_run(led_setup_t *f) { float ro; float go; float bo; - float px; uint8_t led_this_run = 0; if (led_cur == 0) //Denotes start of new processing cycle in the case of chunked processing @@ -289,17 +364,6 @@ void led_matrix_run(led_setup_t *f) } } - uint8_t fcur = 0; - uint8_t fmax = 0; - - //Frames setup - while (f[fcur].end != 1) - { - fcur++; //Count frames - } - - fmax = fcur; //Store total frames count - while (led_cur < lede && led_this_run < led_per_run) { ro = 0; @@ -320,62 +384,72 @@ void led_matrix_run(led_setup_t *f) } else { - //Act on LED - for (fcur = 0; fcur < fmax; fcur++) - { - px = led_cur->px; - float pxmod; - pxmod = (float)(disp.frame % (uint32_t)(1000.0f / led_animation_speed)) / 10.0f * led_animation_speed; + led_instruction_t *led_cur_instruction; + led_cur_instruction = led_instructions; - //Add in any moving effects - if ((!led_animation_direction && f[fcur].ef & EF_SCR_R) || (led_animation_direction && (f[fcur].ef & EF_SCR_L))) - { - pxmod *= 100.0f; - pxmod = (uint32_t)pxmod % 10000; - pxmod /= 100.0f; - - px -= pxmod; - - if (px > 100) px -= 100; - else if (px < 0) px += 100; - } - else if ((!led_animation_direction && f[fcur].ef & EF_SCR_L) || (led_animation_direction && (f[fcur].ef & EF_SCR_R))) - { - pxmod *= 100.0f; - pxmod = (uint32_t)pxmod % 10000; - pxmod /= 100.0f; - px += pxmod; - - if (px > 100) px -= 100; - else if (px < 0) px += 100; - } + //Act on LED + if (led_cur_instruction->end) { + // If no instructions, use normal pattern + led_run_pattern(f, &ro, &go, &bo); + } else { + uint8_t skip; + + while (!led_cur_instruction->end) { + skip = 0; + + if (led_cur_instruction->flags & LED_FLAG_MATCH_ID) { + if ( + led_cur_instruction->id0 == 0 && + led_cur_instruction->id1 == 0 && + led_cur_instruction->id2 == 0 && + led_cur_instruction->id3 == 0 && + led_cur->id == 0 + ) { + // + } else if ( + (0 <= led_cur->id && led_cur->id <= 31) && + (~led_cur_instruction->id0 & ((uint32_t) 1UL << led_cur->id)) + ) { + skip = 1; + } else if ( + (32 <= led_cur->id && led_cur->id <= 63) && + (~led_cur_instruction->id1 & ((uint32_t) 1UL << (led_cur->id - 32))) + ) { + skip = 1; + } else if ( + (64 <= led_cur->id && led_cur->id <= 95) && + (~led_cur_instruction->id2 & ((uint32_t) 1UL << (led_cur->id - 64))) + ) { + skip = 1; + } else if ( + (96 <= led_cur->id && led_cur->id <= 127) && + (~led_cur_instruction->id3 & ((uint32_t) 1UL << (led_cur->id - 96))) + ) { + skip = 1; + } + } - //Check if LED's px is in current frame - if (px < f[fcur].hs) continue; - if (px > f[fcur].he) continue; - //note: < 0 or > 100 continue + if (led_cur_instruction->flags & LED_FLAG_MATCH_LAYER) { + if (layer_state == 0 && led_cur_instruction->layer == 0) { + // + } else if (~layer_state & (1UL << led_cur_instruction->layer)) { + skip = 1; + } + } - //Calculate the px within the start-stop percentage for color blending - px = (px - f[fcur].hs) / (f[fcur].he - f[fcur].hs); + if (!skip) { + if (led_cur_instruction->flags & LED_FLAG_USE_RGB) { + ro = led_cur_instruction->r; + go = led_cur_instruction->g; + bo = led_cur_instruction->b; + } else if (led_cur_instruction->flags & LED_FLAG_USE_PATTERN) { + led_run_pattern(led_setups[led_cur_instruction->pattern_id], &ro, &go, &bo); + } else if (led_cur_instruction->flags & LED_FLAG_USE_ROTATE_PATTERN) { + led_run_pattern(f, &ro, &go, &bo); + } + } - //Add in any color effects - if (f[fcur].ef & EF_OVER) - { - ro = (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5; - go = (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5; - bo = (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5; - } - else if (f[fcur].ef & EF_SUBTRACT) - { - ro -= (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5; - go -= (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5; - bo -= (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5; - } - else - { - ro += (px * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5; - go += (px * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5; - bo += (px * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5; + led_cur_instruction++; } } } diff --git a/tmk_core/protocol/arm_atsam/led_matrix.h b/tmk_core/protocol/arm_atsam/led_matrix.h index 01b078b7112c..67c4224d7f5f 100644 --- a/tmk_core/protocol/arm_atsam/led_matrix.h +++ b/tmk_core/protocol/arm_atsam/led_matrix.h @@ -112,6 +112,28 @@ typedef struct led_setup_s { uint8_t end; //Set to signal end of the setup } led_setup_t; +//LED Extra Instructions +#define LED_FLAG_NULL 0x00 +#define LED_FLAG_MATCH_ID 0x01 +#define LED_FLAG_MATCH_LAYER 0x02 +#define LED_FLAG_USE_RGB 0x10 +#define LED_FLAG_USE_PATTERN 0x20 +#define LED_FLAG_USE_ROTATE_PATTERN 0x40 + +typedef struct led_instruction_s { + uint16_t flags; // Bitfield for LED instructions + uint32_t id0; // Bitwise id, IDs 0-31 + uint32_t id1; // Bitwise id, IDs 32-63 + uint32_t id2; // Bitwise id, IDs 64-95 + uint32_t id3; // Bitwise id, IDs 96-127 + uint8_t layer; + uint8_t r; + uint8_t g; + uint8_t b; + uint8_t pattern_id; + uint8_t end; +} led_instruction_t; + extern issi3733_driver_t issidrv[ISSI3733_DRIVER_COUNT]; extern uint8_t gcr_desired; @@ -130,6 +152,9 @@ extern uint8_t breathe_dir; extern const uint8_t led_setups_count; extern void *led_setups[]; +extern led_instruction_t led_instructions[]; + +extern uint32_t layer_state; extern issi3733_led_t *led_cur; extern issi3733_led_t *lede;