diff --git a/keyboards/massdrop/ctrl/keymaps/responsive_pattern/README.md b/keyboards/massdrop/ctrl/keymaps/responsive_pattern/README.md
index 5ee630dfb8..60c2d1f91f 100644
--- a/keyboards/massdrop/ctrl/keymaps/responsive_pattern/README.md
+++ b/keyboards/massdrop/ctrl/keymaps/responsive_pattern/README.md
@@ -1,5 +1,17 @@
-# THIS KEYMAP IS BROKEN
 
-The CTRL and ALT have both been switched to using the QMK RGB Matrix system,
-rendering any custom effects that used the old, custom Massdrop lighting system,
-BROKEN.
+
+Fn + P + Esc, Fn + P + `: reset effect to default
+
+Fn + P + Tab, Fn + P + Y: select previous color pattern
+Fn + P + Caps, Fn + P + H: select next color pattern
+
+Fn + P + A, Fn + P + J: (no effect for now)
+Fn + P + D, Fn + P + L: (no effect for now)
+
+
+Fn + P + Q, Fn + P + U: wave travel faster
+Fn + P + E, Fn + P + O: wave travel slower
+
+
+Fn + P + W, Fn + P + I: increase wave width
+Fn + P + S, Fn + P + K: decrease wave width
diff --git a/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c b/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c
index 58911aa757..dbf90b50a1 100644
--- a/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c
+++ b/keyboards/massdrop/ctrl/keymaps/responsive_pattern/keymap.c
@@ -1,41 +1,33 @@
 #include QMK_KEYBOARD_H
 
-// uint8_t keyboard_leds(void)
-#include <tmk_core/protocol/arm_atsam/main_arm_atsam.h>
+#include <math.h> // sqrtf, powf
 
+#ifdef CONSOLE_ENABLE
+
+#include <print.h>
 
-#if ISSI3733_LED_COUNT == 119
-#   define KEY_LED_COUNT 87
-#elif ISSI3733_LED_COUNT == 105
-#   define KEY_LED_COUNT 67
 #endif
 
-#define min(x, y) (x < y ? x : y)
-
-
-extern issi3733_led_t *lede;
-extern issi3733_led_t led_map[];
-
 enum ctrl_keycodes {
-    L_BRI = SAFE_RANGE, //LED Brightness Increase
-    L_BRD,              //LED Brightness Decrease
-    L_PTN,              //LED Pattern Select Next
-    L_PTP,              //LED Pattern Select Previous
-    L_PSI,              //LED Pattern Speed Increase
-    L_PSD,              //LED Pattern Speed Decrease
-    L_T_MD,             //LED Toggle Mode
-    L_T_ONF,            //LED Toggle On / Off
-    L_ON,               //LED On
-    L_OFF,              //LED Off
-    L_T_BR,             //LED Toggle Breath Effect
-    L_T_PTD,            //LED Toggle Scrolling Pattern Direction
-    U_T_AUTO,           //USB Extra Port Toggle Auto Detect / Always Active
-    U_T_AGCR,           //USB Toggle Automatic GCR control
-    DBG_TOG,            //DEBUG Toggle On / Off
-    DBG_MTRX,           //DEBUG Toggle Matrix Prints
-    DBG_KBD,            //DEBUG Toggle Keyboard Prints
-    DBG_MOU,            //DEBUG Toggle Mouse Prints
-    MD_BOOT,            //Restart into bootloader after hold timeout
+    L_BRI = SAFE_RANGE, //LED Brightness Increase                                   //Working
+    L_BRD,              //LED Brightness Decrease                                   //Working
+    L_PTN,              //LED Pattern Select Next                                   //Working
+    L_PTP,              //LED Pattern Select Previous                               //Working
+    L_PSI,              //LED Pattern Speed Increase                                //Working
+    L_PSD,              //LED Pattern Speed Decrease                                //Working
+    L_T_MD,             //LED Toggle Mode                                           //Working
+    L_T_ONF,            //LED Toggle On / Off                                       //Broken
+    L_ON,               //LED On                                                    //Broken
+    L_OFF,              //LED Off                                                   //Broken
+    L_T_BR,             //LED Toggle Breath Effect                                  //Working
+    L_T_PTD,            //LED Toggle Scrolling Pattern Direction                    //Working
+    U_T_AGCR,           //USB Toggle Automatic GCR control                          //Working
+    DBG_TOG,            //DEBUG Toggle On / Off                                     //
+    DBG_MTRX,           //DEBUG Toggle Matrix Prints                                //
+    DBG_KBD,            //DEBUG Toggle Keyboard Prints                              //
+    DBG_MOU,            //DEBUG Toggle Mouse Prints                                 //
+    MD_BOOT,            //Restart into bootloader after hold timeout                //Working
+
 
     L_SP_PR,            //LED Splash Pattern Select Previous
     L_SP_NE,            //LED Splash Pattern Select Next
@@ -48,10 +40,9 @@ enum ctrl_keycodes {
 
     L_CP_PR,            //LED Color Pattern Select Previous
     L_CP_NX,            //LEB Color Pattern Select Next
-};
 
-#define TG_NKRO MAGIC_TOGGLE_NKRO //Toggle 6KRO / NKRO mode
-#define ______ KC_TRNS
+    S_RESET            // reset all parameters
+};
 
 keymap_config_t keymap_config;
 
@@ -67,418 +58,46 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
     [1] = LAYOUT(
         _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,            KC_MUTE, _______, _______, \
         _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,   KC_MPLY, KC_MSTP, KC_VOLU, \
-        L_T_BR,  L_PSD,   L_BRI,   L_PSI,   _______, _______, _______, U_T_AUTO,U_T_AGCR,_______, MO(2),   _______, _______, _______,   KC_MPRV, KC_MNXT, KC_VOLD, \
+        L_T_BR,  L_PSD,   L_BRI,   L_PSI,   _______, _______, _______, _______, U_T_AGCR,_______, MO(2),   _______, _______, _______,   KC_MPRV, KC_MNXT, KC_VOLD, \
         L_T_PTD, L_PTP,   L_BRD,   L_PTN,   _______, _______, _______, _______, _______, _______, _______, _______, _______, \
-        _______, L_T_MD,  L_T_ONF, _______, _______, MD_BOOT, TG_NKRO, _______, _______, _______, _______, _______,                              _______, \
+        _______, L_T_MD,  L_T_ONF, _______, _______, MD_BOOT, NK_TOGG, _______, _______, _______, _______, _______,                              _______, \
         _______, _______, _______,                   _______,                            _______, _______, _______, _______,            _______, _______, _______ \
     ),
     [2] = LAYOUT(
-        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,            _______, _______, _______, \
-        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,   _______, _______, _______, \
+        S_RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,            _______, _______, _______, \
+        S_RESET, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,   _______, _______, _______, \
         L_CP_NX, L_SP_SL, L_SP_WD, L_SP_FA, _______, _______, L_CP_NX, L_SP_SL, L_SP_WD, L_SP_FA, _______, _______, _______, _______,   _______, _______, _______, \
         L_CP_PR, L_SP_PR, L_SP_NW, L_SP_NE, _______, _______, L_CP_PR, L_SP_PR, L_SP_NW, L_SP_NE, _______, _______, _______, \
-        _______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______,                              _______, \
+        _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,                              _______, \
         _______, _______, _______,                   _______,                            _______, _______, _______, _______,            _______, _______, _______ \
-    ),
+    )
     /*
     [X] = LAYOUT(
         _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,            _______, _______, _______, \
         _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,   _______, _______, _______, \
         _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,   _______, _______, _______, \
         _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, \
-        _______, _______, _______, _______, _______, _______, TG_NKRO, _______, _______, _______, _______, _______,                              _______, \
+        _______, _______, _______, _______, _______, _______, NK_TOGG, _______, _______, _______, _______, _______,                              _______, \
         _______, _______, _______,                   _______,                            _______, _______, _______, _______,            _______, _______, _______ \
     ),
     */
 };
 
-// see: /tmk_core/common/keycode.h
-uint8_t KEYCODE_TO_LED_ID[256];
-uint8_t DISTANCE_MAP[KEY_LED_COUNT+1][KEY_LED_COUNT+1];
-struct user_led_t {
-    uint8_t state;
-    uint8_t r;
-    uint8_t g;
-    uint8_t b;
-} USER_LED[KEY_LED_COUNT] = {
-
-};
-
+#define DISTANCE_NORAMLIZING_PARAMETER 3
 struct {
     uint8_t PATTERN_INDEX;
-    uint8_t WAVE_FRONT_WIDTH;
-    uint16_t WAVE_PERIOD;
-    uint8_t COLOR_PATTERN_INDEX;
-    uint8_t TRAVEL_DISTANCE;
+    float WAVE_WIDTH;
+    float WAVE_SPEED;
+    int COLOR_PATTERN_INDEX;
+    float TRAVEL_DISTANCE;
 } USER_CONFIG = {
     .PATTERN_INDEX = 1,
-    .WAVE_FRONT_WIDTH = 3,
-    .WAVE_PERIOD = 50,
+    .WAVE_WIDTH = 10, // width of the wave in keycaps
+    .WAVE_SPEED = 15, // travel how many keycaps per second
     .COLOR_PATTERN_INDEX = 0,
     .TRAVEL_DISTANCE = 25,
 };
 
-uint8_t ktli(uint16_t keycode){
-    if(keycode < 256){
-        // the array is initialized in `matrix_init_user()`
-        return KEYCODE_TO_LED_ID[keycode];
-    }
-    switch(keycode){
-    // definition of MO(layer): quantum/quantum_keycodes.h: line 614
-    case MO(1): return 82;
-    }
-    return 0;
-};
-
-// Runs just one time when the keyboard initializes.
-static void init_keycode_to_led_map(void){
-    uint16_t LED_MAP[MATRIX_ROWS][MATRIX_COLS] = LAYOUT(
-            1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,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,
-#if KEY_LED_COUNT >= 87
-            68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87
-#endif
-    );
-
-    uint16_t key = 0;
-    for(uint8_t y = 0; y < MATRIX_ROWS; ++y){
-        for(uint8_t x = 0; x < MATRIX_COLS; ++x){
-            key = keymaps[0][y][x];
-            if(key < 256){
-                KEYCODE_TO_LED_ID[key] = LED_MAP[y][x];
-            }
-        }
-    }
-}
-// https://docs.qmk.fm/#/feature_terminal
-#define KEY_POSITION_MAP_ROWS 6
-#define KEY_POSITION_MAP_COLUMNS 20
-static void init_distance_map(void){
-    uint16_t KEY_POSITION_MAP[KEY_POSITION_MAP_ROWS][KEY_POSITION_MAP_COLUMNS] = {
-        { KC_NO,   KC_ESC,  KC_NO,   KC_F1,  KC_F2,  KC_F3,  KC_F4,  KC_NO,  KC_F5,  KC_F6,   KC_F7,  KC_F8,   KC_F9,    KC_F10,  KC_F11,  KC_F12,  KC_NO,   KC_PSCR, KC_SLCK, KC_PAUS,  },
-        // { KC_NO,   KC_NO,   KC_NO,   KC_NO,  KC_NO,  KC_NO,  KC_NO,  KC_NO,  KC_NO,  KC_NO,   KC_NO,  KC_NO,   KC_NO,    KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,   KC_NO,    },
-        { KC_NO,   KC_GRV,  KC_1,    KC_2,   KC_3,   KC_4,   KC_5,   KC_6,   KC_7,   KC_8,    KC_9,   KC_0,    KC_MINS,  KC_EQL,  KC_BSPC, KC_BSPC, KC_NO,   KC_INS,  KC_HOME, KC_PGUP,  },
-        { KC_NO,   KC_TAB,  KC_Q,    KC_W,   KC_E,   KC_R,   KC_T,   KC_Y,   KC_U,   KC_I,    KC_O,   KC_P,    KC_LBRC,  KC_RBRC, KC_BSLS, KC_BSLS, KC_NO,   KC_DEL,  KC_END,  KC_PGDN,  },
-        { KC_NO,   KC_CAPS, KC_A,    KC_S,   KC_D,   KC_F,   KC_G,   KC_H,   KC_J,   KC_K,    KC_L,   KC_SCLN, KC_QUOT,  KC_ENT,  KC_ENT,  KC_ENT,  KC_NO,   KC_NO,   KC_NO,   KC_NO,    },
-        { KC_NO,   KC_LSFT, KC_Z,    KC_X,   KC_C,   KC_V,   KC_B,   KC_N,   KC_M,   KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,  KC_RSFT, KC_RSFT, KC_RSFT, KC_NO,   KC_NO,   KC_UP,   KC_NO,    },
-        { KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_RALT, KC_NO,  MO(1),   KC_APP,   KC_RCTL, KC_RCTL, KC_RCTL, KC_NO,   KC_LEFT, KC_DOWN, KC_RIGHT, },
-    };
-    uint8_t columns = KEY_POSITION_MAP_COLUMNS;
-    uint8_t rows = KEY_POSITION_MAP_ROWS;
-
-    for(uint8_t y = 0; y < rows; ++y){
-        for(uint8_t x = 0; x < columns; ++x){
-            uint8_t id1 = ktli(KEY_POSITION_MAP[y][x]);
-
-            for(uint8_t j = y; j < rows; ++j){
-                for(uint8_t i = 0; i < columns; ++i){
-                    uint8_t id2 = ktli(KEY_POSITION_MAP[j][i]);
-
-                    if(id1 == id2) continue;
-
-                    uint8_t dx = abs(i - x);
-                    uint8_t dy = abs(j - y);
-                    uint8_t dis = dx + dy;
-                    if(i < x && j > y){
-                        dis -= min(dx, dy);
-                    }
-
-                    uint8_t _dis = DISTANCE_MAP[id1][id2];
-                    if(_dis && _dis <= dis) continue;
-                    DISTANCE_MAP[id1][id2] = dis;
-                    DISTANCE_MAP[id2][id1] = dis;
-                }
-            }
-        }
-    }
-}
-void matrix_init_user(void) {
-    init_keycode_to_led_map();
-    init_distance_map();
-};
-
-// /tmk_core/protocol/arm_atsam/led_matrix.c: line 244
-uint8_t led_enabled;
-float led_animation_speed;
-uint8_t led_animation_direction;
-uint8_t led_animation_orientation;
-uint8_t led_animation_breathing;
-uint8_t led_animation_breathe_cur;
-uint8_t breathe_step;
-uint8_t breathe_dir;
-uint64_t led_next_run;
-
-uint8_t led_animation_id;
-uint8_t led_lighting_mode;
-
-issi3733_led_t *led_cur;
-uint8_t led_per_run;
-float breathe_mult;
-
-// overrided /tmk_core/protocol/arm_atsam/led_matrix.c: line 484
-void rgb_matrix_init_user(void){
-    led_animation_speed = ANIMATION_SPEED_STEP * 15;
-    led_per_run = 15;
-}
-
-// overrided /tmk_core/protocol/arm_atsam/led_matrix.c: line 262
-void led_matrix_run(void)
-{
-    float ro;
-    float go;
-    float bo;
-    float po;
-    uint8_t led_this_run = 0;
-    led_setup_t *f = (led_setup_t*)led_setups[led_animation_id];
-
-    if (led_cur == 0) //Denotes start of new processing cycle in the case of chunked processing
-    {
-        led_cur = led_map;
-
-        breathe_mult = 1;
-
-        if (led_animation_breathing)
-        {
-            led_animation_breathe_cur += breathe_step * breathe_dir;
-
-            if (led_animation_breathe_cur >= BREATHE_MAX_STEP)
-                breathe_dir = -1;
-            else if (led_animation_breathe_cur <= BREATHE_MIN_STEP)
-                breathe_dir = 1;
-
-            //Brightness curve created for 256 steps, 0 - ~98%
-            breathe_mult = 0.000015 * led_animation_breathe_cur * led_animation_breathe_cur;
-            if (breathe_mult > 1) breathe_mult = 1;
-            else if (breathe_mult < 0) breathe_mult = 0;
-        }
-    }
-
-    uint8_t fcur = 0;
-    uint8_t fmax = 0;
-
-    //Frames setup
-    while (f[fcur].end != 1)
-    {
-        fcur++; //Count frames
-    }
-
-    fmax = fcur; //Store total frames count
-
-    struct user_led_t user_led_cur;
-    while (led_cur < lede && led_this_run < led_per_run)
-    {
-        ro = 0;
-        go = 0;
-        bo = 0;
-
-        uint8_t led_index = led_cur - led_map;                  // only this part differs from the original function.
-        if(led_index < KEY_LED_COUNT){                          //
-            user_led_cur = USER_LED[led_index];                 // `struct user_led_t USER_LED[]` is stored globally.
-        }                                                       //
-                                                                //
-        if(led_index < KEY_LED_COUNT && user_led_cur.state){    // `user_led_cur` is just for convenience
-            ro = user_led_cur.r;                                //
-            go = user_led_cur.g;                                //
-            bo = user_led_cur.b;                                //
-        }                                                       //
-        else if (led_lighting_mode == LED_MODE_KEYS_ONLY && led_cur->scan == 255)
-        {
-            //Do not act on this LED
-        }
-        else if (led_lighting_mode == LED_MODE_NON_KEYS_ONLY && led_cur->scan != 255)
-        {
-            //Do not act on this LED
-        }
-        else if (led_lighting_mode == LED_MODE_INDICATORS_ONLY)
-        {
-            //Do not act on this LED (Only show indicators)
-        }
-        else
-        {
-            //Act on LED
-            for (fcur = 0; fcur < fmax; fcur++)
-            {
-
-                if (led_animation_orientation)
-                {
-                  po = led_cur->py;
-                }
-                else
-                {
-                  po = led_cur->px;
-                }
-
-                float pomod;
-                pomod = (float)(g_tick % (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)))
-                {
-                    pomod *= 100.0f;
-                    pomod = (uint32_t)pomod % 10000;
-                    pomod /= 100.0f;
-
-                    po -= pomod;
-
-                    if (po > 100) po -= 100;
-                    else if (po < 0) po += 100;
-                }
-                else if ((!led_animation_direction && f[fcur].ef & EF_SCR_L) || (led_animation_direction && (f[fcur].ef & EF_SCR_R)))
-                {
-                    pomod *= 100.0f;
-                    pomod = (uint32_t)pomod % 10000;
-                    pomod /= 100.0f;
-                    po += pomod;
-
-                    if (po > 100) po -= 100;
-                    else if (po < 0) po += 100;
-                }
-
-                //Check if LED's po is in current frame
-                if (po < f[fcur].hs) continue;
-                if (po > f[fcur].he) continue;
-                //note: < 0 or > 100 continue
-
-                //Calculate the po within the start-stop percentage for color blending
-                po = (po - f[fcur].hs) / (f[fcur].he - f[fcur].hs);
-
-                //Add in any color effects
-                if (f[fcur].ef & EF_OVER)
-                {
-                    ro = (po * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
-                    go = (po * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
-                    bo = (po * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
-                }
-                else if (f[fcur].ef & EF_SUBTRACT)
-                {
-                    ro -= (po * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
-                    go -= (po * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
-                    bo -= (po * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
-                }
-                else
-                {
-                    ro += (po * (f[fcur].re - f[fcur].rs)) + f[fcur].rs;// + 0.5;
-                    go += (po * (f[fcur].ge - f[fcur].gs)) + f[fcur].gs;// + 0.5;
-                    bo += (po * (f[fcur].be - f[fcur].bs)) + f[fcur].bs;// + 0.5;
-                }
-            }
-        }
-
-        //Clamp values 0-255
-        if (ro > 255) ro = 255; else if (ro < 0) ro = 0;
-        if (go > 255) go = 255; else if (go < 0) go = 0;
-        if (bo > 255) bo = 255; else if (bo < 0) bo = 0;
-
-        if (led_animation_breathing)
-        {
-            ro *= breathe_mult;
-            go *= breathe_mult;
-            bo *= breathe_mult;
-        }
-
-        *led_cur->rgb.r = (uint8_t)ro;
-        *led_cur->rgb.g = (uint8_t)go;
-        *led_cur->rgb.b = (uint8_t)bo;
-
-#ifdef USB_LED_INDICATOR_ENABLE
-        if (keyboard_leds())
-        {
-            uint8_t kbled = keyboard_leds();
-            if (
-                #if USB_LED_NUM_LOCK_SCANCODE != 255
-                (led_cur->scan == USB_LED_NUM_LOCK_SCANCODE && kbled & (1<<USB_LED_NUM_LOCK)) ||
-                #endif //NUM LOCK
-                #if USB_LED_CAPS_LOCK_SCANCODE != 255
-                (led_cur->scan == USB_LED_CAPS_LOCK_SCANCODE && kbled & (1<<USB_LED_CAPS_LOCK)) ||
-                #endif //CAPS LOCK
-                #if USB_LED_SCROLL_LOCK_SCANCODE != 255
-                (led_cur->scan == USB_LED_SCROLL_LOCK_SCANCODE && kbled & (1<<USB_LED_SCROLL_LOCK)) ||
-                #endif //SCROLL LOCK
-                #if USB_LED_COMPOSE_SCANCODE != 255
-                (led_cur->scan == USB_LED_COMPOSE_SCANCODE && kbled & (1<<USB_LED_COMPOSE)) ||
-                #endif //COMPOSE
-                #if USB_LED_KANA_SCANCODE != 255
-                (led_cur->scan == USB_LED_KANA_SCANCODE && kbled & (1<<USB_LED_KANA)) ||
-                #endif //KANA
-                (0))
-            {
-                if (*led_cur->rgb.r > 127) *led_cur->rgb.r = 0;
-                else *led_cur->rgb.r = 255;
-                if (*led_cur->rgb.g > 127) *led_cur->rgb.g = 0;
-                else *led_cur->rgb.g = 255;
-                if (*led_cur->rgb.b > 127) *led_cur->rgb.b = 0;
-                else *led_cur->rgb.b = 255;
-            }
-        }
-#endif //USB_LED_INDICATOR_ENABLE
-
-        led_cur++;
-        led_this_run++;
-    }
-}
-
-#define KEY_STROKES_LENGTH 20
-struct {
-    bool alive;
-    uint8_t led_id;
-    uint32_t time;
-} KEY_STROKES[KEY_STROKES_LENGTH] = {{}};
-
-
-
-
-void set_led_rgb(uint8_t led_id, uint8_t r, uint8_t g, uint8_t b){
-    issi3733_led_t *target_led = (led_map + led_id);
-    *target_led->rgb.r = r;
-    *target_led->rgb.g = g;
-    *target_led->rgb.b = b;
-}
-
-
-uint8_t DISTANCE_FROM_LAST_KEYSTROKE[KEY_LED_COUNT+1];
-void calculate_keystroke_distance(void){
-    bool alive;
-    uint8_t led_id, period_passed;
-    uint32_t t;
-
-
-    for(uint8_t i = 0; i <= KEY_LED_COUNT; ++i){
-        DISTANCE_FROM_LAST_KEYSTROKE[i] = 0;
-    }
-
-    for(uint8_t i = 0; i < KEY_STROKES_LENGTH; ++i){
-        if(KEY_STROKES[i].alive){
-            t = timer_elapsed32(KEY_STROKES[i].time);
-            alive = 0;
-            led_id = KEY_STROKES[i].led_id;
-            period_passed = t / USER_CONFIG.WAVE_PERIOD;
-
-            uint8_t delta_period;
-            for(uint8_t j = 1; j <= KEY_LED_COUNT; ++j){
-                delta_period = period_passed - DISTANCE_MAP[led_id][j];
-                if(( delta_period < USER_CONFIG.WAVE_FRONT_WIDTH) && (
-                    DISTANCE_MAP[led_id][j] <= USER_CONFIG.TRAVEL_DISTANCE
-                )){
-                    switch(USER_CONFIG.PATTERN_INDEX){
-                    case 3:
-                    case 4:
-                    case 5:
-                    case 6:
-                        DISTANCE_FROM_LAST_KEYSTROKE[j] += delta_period;
-                        break;
-                    default:
-                        DISTANCE_FROM_LAST_KEYSTROKE[j] = 1;
-                        break;
-                    }
-                    alive = 1;
-                }
-            }
-            KEY_STROKES[i].alive = alive;
-        }
-    }
-}
 
 #define COLOR_PATTERN_RGB_COUNT 18
 static uint8_t COLOR_PATTERNS[][COLOR_PATTERN_RGB_COUNT][3] = {
@@ -515,191 +134,300 @@ static uint8_t COLOR_PATTERNS[][COLOR_PATTERN_RGB_COUNT][3] = {
 static const uint8_t COLOR_PATTERNS_COUNT = (
         sizeof(COLOR_PATTERNS) / sizeof(COLOR_PATTERNS[0]));
 
-void set_user_led_rgb(uint8_t i, uint8_t r, uint8_t g, uint8_t b){
-    USER_LED[i-1].state = 1;
-    USER_LED[i-1].r = r;
-    USER_LED[i-1].g = g;
-    USER_LED[i-1].b = b;
-}
-void unset_user_led_rgb(uint8_t i){
-    USER_LED[i-1].state = 0;
-}
-void set_indicator_led_rgb(uint8_t i,
-        uint8_t layer, uint8_t r, uint8_t g, uint8_t b){
-    USER_LED[i-1].state |= 1 << layer;
-    USER_LED[i-1].r = r;
-    USER_LED[i-1].g = g;
-    USER_LED[i-1].b = b;
-}
-void unset_indicator_led_rgb(uint8_t i, uint8_t layer){
-    USER_LED[i-1].state &= ~(1 << layer);
-}
+/**
+ * trimed down version of `ISSI3733_LED_MAP`:
+ *
+ * `ISSI3733_LED_MAP` is defined in keyboards/massdrop/ctrl/config_led.h is not directly usable,
+ * the numbers inside this map could probably be related to the PCB layout instead of
+ * the actual physical layout,
+ *
+ * this `ISSI3733_LED_MAP` is used somewhere in protocol/ but is not globally accessible
+ * so one is created here
+ *
+ * x and y are coordinates of the physical layout
+ * KC_ESC is (0, 0), gap between function keys and number rows is 1.5
+ * +y is downwards
+ * 1 unit is width/height of 1 standard keycap
+ */
+#define MAX_LED_ID ISSI3733_LED_COUNT
+typedef struct led_info_s {
+    uint16_t id;
+    uint16_t scan;
+    float x;
+    float y;
+    uint8_t distance_to[MAX_LED_ID + 1];
+} led_info_t;
+led_info_t led_info[MAX_LED_ID + 1] = {
+ { .id = 0 },
+ { .id = 1,     .x = 0.0,       .y = 0.0,   .scan = 41  }, // ESC
+ { .id = 2,     .x = 2.0,       .y = 0.0,   .scan = 58  }, // F1
+ { .id = 3,     .x = 3.0,       .y = 0.0,   .scan = 59  }, // F2
+ { .id = 4,     .x = 3.5,       .y = 0.0,   .scan = 60  }, // F3
+ { .id = 5,     .x = 5.0,       .y = 0.0,   .scan = 61  }, // F4
+ { .id = 6,     .x = 6.5,       .y = 0.0,   .scan = 62  }, // F5
+ { .id = 7,     .x = 7.5,       .y = 0.0,   .scan = 63  }, // F6
+ { .id = 8,     .x = 8.5,       .y = 0.0,   .scan = 64  }, // F7
+ { .id = 9,     .x = 9.5,       .y = 0.0,   .scan = 65  }, // F8
+ { .id = 10,    .x = 11,        .y = 0.0,   .scan = 66  }, // F9
+ { .id = 11,    .x = 12,        .y = 0.0,   .scan = 67  }, // F10
+ { .id = 12,    .x = 13,        .y = 0.0,   .scan = 68  }, // F11
+ { .id = 13,    .x = 14,        .y = 0.0,   .scan = 69  }, // F12
+ { .id = 14,    .x = 15.5,      .y = 0.0,   .scan = 70  }, // Print
+ { .id = 15,    .x = 16.5,      .y = 0.0,   .scan = 71  }, // Scoll Lock
+ { .id = 16,    .x = 17.5,      .y = 0.0,   .scan = 72  }, // Pause
+ { .id = 17,    .x = 0.0,       .y = 1.5,   .scan = 53  }, // `
+ { .id = 18,    .x = 1.0,       .y = 1.5,   .scan = 30  }, // 1
+ { .id = 19,    .x = 2.0,       .y = 1.5,   .scan = 31  }, // 2
+ { .id = 20,    .x = 3.0,       .y = 1.5,   .scan = 32  }, // 3
+ { .id = 21,    .x = 3.5,       .y = 1.5,   .scan = 33  }, // 4
+ { .id = 22,    .x = 5.0,       .y = 1.5,   .scan = 34  }, // 5
+ { .id = 23,    .x = 6.0,       .y = 1.5,   .scan = 35  }, // 6
+ { .id = 24,    .x = 7.0,       .y = 1.5,   .scan = 36  }, // 7
+ { .id = 25,    .x = 8.0,       .y = 1.5,   .scan = 37  }, // 8
+ { .id = 26,    .x = 9.0,       .y = 1.5,   .scan = 38  }, // 9
+ { .id = 27,    .x = 10.0,      .y = 1.5,   .scan = 39  }, // 0
+ { .id = 28,    .x = 11.0,      .y = 1.5,   .scan = 45  }, // -
+ { .id = 29,    .x = 12.0,      .y = 1.5,   .scan = 46  }, // =
+ { .id = 30,    .x = 13.5,      .y = 1.5,   .scan = 42  }, // Backspace
+ { .id = 31,    .x = 15.5,      .y = 1.5,   .scan = 73  }, // Insert
+ { .id = 32,    .x = 16.6,      .y = 1.5,   .scan = 74  }, // Home
+ { .id = 33,    .x = 17.5,      .y = 1.5,   .scan = 75  }, // Page Up
+ { .id = 34,    .x = 0.2,       .y = 2.5,   .scan = 43  }, // Tab
+ { .id = 35,    .x = 1.5,       .y = 2.5,   .scan = 20  }, // Q
+ { .id = 36,    .x = 2.5,       .y = 2.5,   .scan = 26  }, // W
+ { .id = 37,    .x = 3.5,       .y = 2.5,   .scan = 8   }, // E
+ { .id = 38,    .x = 4.5,       .y = 2.5,   .scan = 21  }, // R
+ { .id = 39,    .x = 5.5,       .y = 2.5,   .scan = 23  }, // T
+ { .id = 40,    .x = 6.5,       .y = 2.5,   .scan = 28  }, // Y
+ { .id = 41,    .x = 7.5,       .y = 2.5,   .scan = 24  }, // U
+ { .id = 42,    .x = 8.5,       .y = 2.5,   .scan = 12  }, // I
+ { .id = 43,    .x = 9.5,       .y = 2.5,   .scan = 18  }, // O
+ { .id = 44,    .x = 10.5,      .y = 2.5,   .scan = 19  }, // P
+ { .id = 45,    .x = 11.5,      .y = 2.5,   .scan = 47  }, // [
+ { .id = 46,    .x = 12.5,      .y = 2.5,   .scan = 48  }, // ]
+ { .id = 47,    .x = 13.75,     .y = 2.5,   .scan = 49  }, /* \ */
+ { .id = 48,    .x = 15.5,      .y = 2.5,   .scan = 76  }, // Delete
+ { .id = 49,    .x = 16.5,      .y = 2.5,   .scan = 77  }, // End
+ { .id = 50,    .x = 17.5,      .y = 2.5,   .scan = 78  }, // Page Down
+ { .id = 51,    .x = 0.4,       .y = 3.5,   .scan = 57  }, // Caps Lock
+ { .id = 52,    .x = 2.5,       .y = 3.5,   .scan = 4   }, // A
+ { .id = 53,    .x = 3.5,       .y = 3.5,   .scan = 22  }, // S
+ { .id = 54,    .x = 4.5,       .y = 3.5,   .scan = 7   }, // D
+ { .id = 55,    .x = 5.5,       .y = 3.5,   .scan = 9   }, // F
+ { .id = 56,    .x = 6.5,       .y = 3.5,   .scan = 10  }, // G
+ { .id = 57,    .x = 7.5,       .y = 3.5,   .scan = 11  }, // H
+ { .id = 58,    .x = 8.5,       .y = 3.5,   .scan = 13  }, // J
+ { .id = 59,    .x = 9.5,       .y = 3.5,   .scan = 14  }, // K
+ { .id = 60,    .x = 10.5,      .y = 3.5,   .scan = 15  }, // L
+ { .id = 61,    .x = 11.5,      .y = 3.5,   .scan = 51  }, // ;
+ { .id = 62,    .x = 12.5,      .y = 3.5,   .scan = 52  }, // '
+ { .id = 63,    .x = 13.5,      .y = 3.5,   .scan = 40  }, // Enter
+ { .id = 64,    .x = 0.5,       .y = 4.5,   .scan = 225 }, // LSHIFT
+ { .id = 65,    .x = 2.25,      .y = 4.5,   .scan = 29  }, // Z
+ { .id = 66,    .x = 3.25,      .y = 4.5,   .scan = 27  }, // X
+ { .id = 67,    .x = 4.25,      .y = 4.5,   .scan = 6   }, // C
+ { .id = 68,    .x = 5.25,      .y = 4.5,   .scan = 25  }, // V
+ { .id = 69,    .x = 6.25,      .y = 4.5,   .scan = 5   }, // B
+ { .id = 70,    .x = 7.25,      .y = 4.5,   .scan = 17  }, // N
+ { .id = 71,    .x = 8.25,      .y = 4.5,   .scan = 16  }, // M
+ { .id = 72,    .x = 9.25,      .y = 4.5,   .scan = 54  }, // COMMA
+ { .id = 73,    .x = 10.25,     .y = 4.5,   .scan = 55  }, // DOT
+ { .id = 74,    .x = 11.25,     .y = 4.5,   .scan = 56  }, // SLASH
+ { .id = 75,    .x = 13.2,      .y = 4.5,   .scan = 229 }, // RSHIFT
+ { .id = 76,    .x = 16.5,      .y = 4.5,   .scan = 82  }, // UP
+ { .id = 77,    .x = 0.1,       .y = 5.5,   .scan = 224 }, // LCTRL
+ { .id = 78,    .x = 1.25,      .y = 5.5,   .scan = 227 }, // WIN
+ { .id = 79,    .x = 2.5,       .y = 5.5,   .scan = 226 }, // LALT
+ { .id = 80,    .x = 6.25,      .y = 5.5,   .scan = 44  }, // SPACE
 
-void refresh_pattern_indicators(void){
-    static uint8_t GRV_123456[] = {
-        KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6,
-    };
+#define MAX_CACHED_SCAN_CODE 231
+ { .id = 81,    .x = 10.25,     .y = 5.5,   .scan = 230 }, // RALT
 
-    if(layer_state >= 0x04){
-        for(uint8_t i = 0; i < 7; ++i){
-            if(i == USER_CONFIG.PATTERN_INDEX){
-                set_indicator_led_rgb(ktli(GRV_123456[i]), 2, 0, 0, 255);
-            } else{
-                set_indicator_led_rgb(ktli(GRV_123456[i]), 2, 0, 255, 0);
+#define FN_KEY_LED_ID 82
+#define FN_KEY_SCAN_CODE 20737
+ { .id = 82,    .x = 11.5,      .y = 5.5,   .scan = 20737 }, // FN
+ { .id = 83,    .x = 12.7,      .y = 5.5,   .scan = 101 }, // APP
+ { .id = 84,    .x = 13.75,     .y = 5.5,   .scan = 228 }, // RCTRL
+ { .id = 85,    .x = 15.5,      .y = 5.5,   .scan = 80  }, // LEFT
+ { .id = 86,    .x = 16.5,      .y = 5.5,   .scan = 81  }, // DOWN
+ { .id = 87,    .x = 17.5,      .y = 5.5,   .scan = 79  }, // RIGHT
+
+#define MAX_LED_ID_WITH_SCANCODE 87
+
+ { .id = 88,    .x = 18.5,      .y = 6.5,   .scan = 255 },
+ { .id = 89,    .x = 16.917,    .y = 6.5,   .scan = 255 },
+ { .id = 90,    .x = 15.333,    .y = 6.5,   .scan = 255 },
+ { .id = 91,    .x = 13.75,     .y = 6.5,   .scan = 255 },
+ { .id = 92,    .x = 12.167,    .y = 6.5,   .scan = 255 },
+ { .id = 93,    .x = 10.583,    .y = 6.5,   .scan = 255 },
+ { .id = 94,    .x = 9,         .y = 6.5,   .scan = 255 },
+ { .id = 95,    .x = 7.417,     .y = 6.5,   .scan = 255 },
+ { .id = 96,    .x = 5.833,     .y = 6.5,   .scan = 255 },
+ { .id = 97,    .x = 4.25,      .y = 6.5,   .scan = 255 },
+ { .id = 98,    .x = 2.667,     .y = 6.5,   .scan = 255 },
+ { .id = 99,    .x = 1.083,     .y = 6.5,   .scan = 255 },
+ { .id = 100,   .x = -0.5,      .y = 6.5,   .scan = 255 },
+ { .id = 101,   .x = -0.5,      .y = 4.75,  .scan = 255 },
+ { .id = 102,   .x = -0.5,      .y = 3,     .scan = 255 },
+ { .id = 103,   .x = -0.5,      .y = 1.25,  .scan = 255 },
+ { .id = 104,   .x = -0.5,      .y = -0.5,  .scan = 255 },
+ { .id = 105,   .x = 1.083,     .y = -0.5,  .scan = 255 },
+ { .id = 106,   .x = 2.667,     .y = -0.5,  .scan = 255 },
+ { .id = 107,   .x = 4.25,      .y = -0.5,  .scan = 255 },
+ { .id = 108,   .x = 5.833,     .y = -0.5,  .scan = 255 },
+ { .id = 109,   .x = 7.417,     .y = -0.5,  .scan = 255 },
+ { .id = 110,   .x = 9,         .y = -0.5,  .scan = 255 },
+ { .id = 111,   .x = 10.583,    .y = -0.5,  .scan = 255 },
+ { .id = 112,   .x = 12.167,    .y = -0.5,  .scan = 255 },
+ { .id = 113,   .x = 13.75,     .y = -0.5,  .scan = 255 },
+ { .id = 114,   .x = 15.333,    .y = -0.5,  .scan = 255 },
+ { .id = 115,   .x = 16.917,    .y = -0.5,  .scan = 255 },
+ { .id = 116,   .x = 18.5,      .y = 1.25,  .scan = 255 },
+ { .id = 117,   .x = 18.5,      .y = 3,     .scan = 255 },
+ { .id = 118,   .x = 18.5,      .y = 4.75,  .scan = 255 },
+ { .id = 119,   .x = 18.5,      .y = 6.5,   .scan = 255 },
+};
+
+/**
+ * there are a few variables are used here
+ * keycode, scancode, led id
+ *
+ * scancode relates to actual physical key press
+ *
+ * keycode is software key press, or scancode with modifiers (shift, ctrl, alt, etc.),
+ * keycode with the value less than 255 are usually the same with scan code (I hope so)
+ *
+ * the led pattern are running based on led id, because led on the keyboard
+ * are not limited to keys only
+ */
+led_info_t* get_led_info_by_scancode(uint16_t scancode){
+    static bool init = false;
+    static led_info_t* scancode_to_led_info[MAX_CACHED_SCAN_CODE + 1];
+    if(!init){
+        for(int i = 1; i <= MAX_LED_ID_WITH_SCANCODE; ++i){
+            uint16_t scan = led_info[i].scan;
+            if(scan <= MAX_CACHED_SCAN_CODE){
+                scancode_to_led_info[scan] = (led_info + i);
             }
         }
-    } else{
-        for(uint8_t i = 0; i < 7; ++i){
-            unset_indicator_led_rgb(ktli(GRV_123456[i]), 2);
-        }
+        init = true;
     }
-}
-void refresh_color_pattern_indicators(void){
-    static uint8_t ZXCVBNM_COMM_DOT[] = {
-        KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT,
-    };
 
-    if(layer_state >= 0x04){
-        uint8_t (*c)[3] = &COLOR_PATTERNS[USER_CONFIG.COLOR_PATTERN_INDEX][0];
-        for(uint8_t i = 0; i < 9; ++i){
-            set_indicator_led_rgb(ktli(ZXCVBNM_COMM_DOT[i]),
-                    2, c[i][0], c[i][1], c[i][2]);
-        }
-    } else{
-        for(uint8_t i = 0; i < 9; ++i){
-            unset_indicator_led_rgb(ktli(ZXCVBNM_COMM_DOT[i]), 2);
-        }
+    if(scancode <= MAX_CACHED_SCAN_CODE){
+        return scancode_to_led_info[scancode];
+    } else if(scancode == FN_KEY_SCAN_CODE){ // FN
+        return (led_info + FN_KEY_LED_ID);
     }
+    return led_info;
 }
 
+
+
+void init_led_info(void){
+    for(int i = 1; i <= MAX_LED_ID; ++i){
+        led_info_t *entry1 = led_info + i;
+        for(int j = i; j <= MAX_LED_ID; ++j){
+            led_info_t *entry2 = led_info + j;
+            /**
+             * distance is tripled because
+             * convertion from float to int reduces accuracy
+             *
+             */
+            uint8_t distance = (uint8_t)sqrtf(
+                    powf(entry1->x - entry2->x, 2.0) +
+                    powf(entry1->y - entry2->y, 2.0)) *
+                    DISTANCE_NORAMLIZING_PARAMETER;
+            entry1->distance_to[j] = distance;
+            entry2->distance_to[i] = distance;
+        }
+    }
+};
+
+
+// Runs just one time when the keyboard initializes.
+void matrix_init_user(void) {
+    init_led_info();
+};
+
+typedef struct keystroke_s {
+    uint16_t scancode;
+    uint32_t timer;
+    bool active;
+} keystroke_t;
+
+#define MAX_ACTIVE_KEYSTORKES 10
+keystroke_t ACTIVE_KEYSTROKES[MAX_ACTIVE_KEYSTORKES];
+
+void reset_led_for_instruction(int led_instruction_index){
+    led_instructions[led_instruction_index].id0 = 0;
+    led_instructions[led_instruction_index].id1 = 0;
+    led_instructions[led_instruction_index].id2 = 0;
+    led_instructions[led_instruction_index].id3 = 0;
+};
+void add_led_to_instruction(int led_instruction_index, int led_id){
+    if(32 >= led_id && led_id >= 1){
+        led_instructions[led_instruction_index].id0 += ( 1 << (led_id - 1) );
+    } else if(64 >= led_id){
+        led_instructions[led_instruction_index].id1 += ( 1 << (led_id - 33) );
+    } else if(96 >= led_id){
+        led_instructions[led_instruction_index].id2 += ( 1 << (led_id - 65) );
+    } else if(128 >= led_id){
+        led_instructions[led_instruction_index].id3 += ( 1 << (led_id - 97) );
+    }
+};
+
+
+void wave_effect(void);
+void set_wave_color(int);
 // Runs constantly in the background, in a loop.
 void matrix_scan_user(void) {
-    static uint32_t scan_timer = 0;
-    static uint8_t last_layer = 0;
-
-    uint8_t layer = 0;
-    if(layer_state >= 0x04){
-        layer = 2;
-    } else if(layer_state >= 0x02){
-        layer = 1;
-    }
-
-    calculate_keystroke_distance();
-
-
-    #define USE_PATTERN 0
-    #define BLACK_RGB 1
-    #define COLOR_RGB 2
-    uint8_t ci; // color index
-    uint8_t *rgb;
-    uint8_t handle_type;
-    uint8_t distance;
-    for(uint8_t i = 1; i <= KEY_LED_COUNT; ++i){
-        if(USER_LED[i-1].state >= 2) continue;
-
-        handle_type = USE_PATTERN;
-        distance = DISTANCE_FROM_LAST_KEYSTROKE[i];
-
-        switch(USER_CONFIG.PATTERN_INDEX){
-        case 0: handle_type = USE_PATTERN; break;
-        case 1: handle_type = distance ? USE_PATTERN : BLACK_RGB; break;
-        case 2: handle_type = distance ? BLACK_RGB : USE_PATTERN; break;
-        case 3: handle_type = distance ? COLOR_RGB : BLACK_RGB; break;
-        case 4: handle_type = distance ? COLOR_RGB : USE_PATTERN; break;
-        case 5:
-        case 6: handle_type = distance ? COLOR_RGB : USE_PATTERN; break;
-        }
-        switch(handle_type){
-        case USE_PATTERN: unset_user_led_rgb(i); break;
-        case BLACK_RGB: set_user_led_rgb(i, 0, 0, 0); break;
-        case COLOR_RGB:
-            ci = (DISTANCE_FROM_LAST_KEYSTROKE[i] * COLOR_PATTERN_RGB_COUNT /
-                    USER_CONFIG.WAVE_FRONT_WIDTH) % COLOR_PATTERN_RGB_COUNT;
-            rgb = &COLOR_PATTERNS[USER_CONFIG.COLOR_PATTERN_INDEX][ci][0];
-
-            set_user_led_rgb(i, rgb[0], rgb[1], rgb[2]);
-            break;
-        }
-    }
-
-
-    // could be moved to process_record_user()
-    if(layer != last_layer){
-
-        static uint8_t QWEASDP[] = {
-            KC_Q, KC_W, KC_E, KC_A, KC_S, KC_D, KC_P,
-        };
-        static uint8_t YUIOHJKL[] = {
-            KC_Y, KC_U, KC_I, KC_O, KC_H, KC_J, KC_K, KC_L,
-        };
-
-        switch(last_layer){
-        case 1:
-            for(uint8_t i = 0; i < 7; ++i){
-                unset_indicator_led_rgb(ktli(QWEASDP[i]), 1);
-            }
-            break;
-        case 2:
-            for(uint8_t i = 0; i < 6; ++i){
-                unset_indicator_led_rgb(ktli(QWEASDP[i]), 2);
-            }
-            for(uint8_t i = 0; i < 8; ++i){
-                unset_indicator_led_rgb(ktli(YUIOHJKL[i]), 2);
-            }
-            unset_indicator_led_rgb(ktli(KC_TAB), 2);
-            unset_indicator_led_rgb(ktli(KC_CAPS), 2);
-            break;
-        }
-
-
-        switch(layer){
-        case 1:
-            for(uint8_t i = 0; i < 7; ++i){
-                set_indicator_led_rgb(ktli(QWEASDP[i]), 1, 255, 0, 0);
-            }
-            break;
-        case 2:
-            for(uint8_t i = 0; i < 6; ++i){
-                set_indicator_led_rgb(ktli(QWEASDP[i]), 2, 0, 255, 0);
-            }
-            for(uint8_t i = 0; i < 8; ++i){
-                set_indicator_led_rgb(ktli(YUIOHJKL[i]), 2, 0, 255, 0);
-            }
-            set_indicator_led_rgb(ktli(KC_TAB), 2, 0, 255, 0);
-            set_indicator_led_rgb(ktli(KC_CAPS), 2, 0, 255, 0);
-            break;
-        }
-
-        refresh_pattern_indicators();
-        refresh_color_pattern_indicators();
-        last_layer = layer;
-    }
-
-
-    switch(layer){
-    case 0:
-        if(timer_elapsed32(scan_timer) > 2000){
-            scan_timer = timer_read32();
-        } else if(timer_elapsed32(scan_timer) > 1000){
-            // set_user_led_rgb(ktli(KC_F5), 255, 255, 255);
-        }
-        break;
-    case 1:
-        break;
-    case 2:
-        break;
-    }
-
+    wave_effect();
+    set_wave_color(USER_CONFIG.PATTERN_INDEX);
 };
 
+
 #define MODS_SHIFT  (get_mods() & MOD_BIT(KC_LSHIFT) || get_mods() & MOD_BIT(KC_RSHIFT))
 #define MODS_CTRL  (get_mods() & MOD_BIT(KC_LCTL) || get_mods() & MOD_BIT(KC_RCTRL))
 #define MODS_ALT  (get_mods() & MOD_BIT(KC_LALT) || get_mods() & MOD_BIT(KC_RALT))
 
+void register_keystroke(uint16_t keycode){
+    if(get_led_info_by_scancode(keycode)->id){
+        uint32_t oldest_keystroke_lifespan = 0;
+        int8_t oldest_keystroke_index = -1;
+        bool registered = false;
+
+        keystroke_t *keystroke = ACTIVE_KEYSTROKES;
+        for(int i = 0; i < MAX_ACTIVE_KEYSTORKES; ++i){
+            if(!keystroke->active){
+                keystroke->scancode = keycode;
+                keystroke->timer = timer_read32();
+                keystroke->active = true;
+                registered = true;
+                break;
+            }
+
+            uint32_t lifespan = timer_elapsed32(keystroke->timer);
+            if(lifespan > oldest_keystroke_lifespan){
+                oldest_keystroke_index = i;
+                oldest_keystroke_lifespan = lifespan;
+            }
+
+            ++keystroke;
+        }
+
+        // override the oldest keystroke
+        if(!registered){
+            keystroke = ACTIVE_KEYSTROKES + oldest_keystroke_index;
+            keystroke->scancode = keycode;
+            keystroke->timer = timer_read32();
+            keystroke->active = true; // presumably active already
+        }
+    }
+}
+
 bool process_record_user(uint16_t keycode, keyrecord_t *record) {
     static uint32_t key_timer;
 
-
     switch (keycode) {
         case L_BRI:
             if (record->event.pressed) {
@@ -777,11 +505,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
                 led_animation_direction = !led_animation_direction;
             }
             return false;
-        case U_T_AUTO:
-            if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
-                TOGGLE_FLAG_AND_PRINT(usb_extra_manual, "USB extra port manual mode");
-            }
-            return false;
         case U_T_AGCR:
             if (record->event.pressed && MODS_SHIFT && MODS_CTRL) {
                 TOGGLE_FLAG_AND_PRINT(usb_gcr_auto, "USB GCR auto mode");
@@ -819,20 +542,16 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
 
 
 
+        case S_RESET:
+            // reset all parameters
 
+            USER_CONFIG.PATTERN_INDEX = 1;
+            USER_CONFIG.WAVE_WIDTH = 10;
+            USER_CONFIG.WAVE_SPEED = 15;
+            USER_CONFIG.COLOR_PATTERN_INDEX = 0;
+            USER_CONFIG.TRAVEL_DISTANCE = 25;
 
-
-
-
-
-
-
-
-
-
-
-
-
+            return false;
         case L_SP_PR: // previous dripple pattern
         case L_SP_NE: // next dripple pattern
             if (record->event.pressed) {
@@ -844,55 +563,53 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
                 if(USER_CONFIG.PATTERN_INDEX <= 4){
                     USER_CONFIG.TRAVEL_DISTANCE = 25;
                     USER_CONFIG.COLOR_PATTERN_INDEX = 0;
-                    USER_CONFIG.WAVE_PERIOD = 50;
+                    USER_CONFIG.WAVE_SPEED = 10;
                 }
 
                 switch(USER_CONFIG.PATTERN_INDEX){
                 case 0: // None
                     break;
                 case 1: // background off, wave on
-                    USER_CONFIG.WAVE_FRONT_WIDTH = 2;
+                    USER_CONFIG.WAVE_WIDTH = 2;
                     break;
                 case 2: // background on, wave off
-                    USER_CONFIG.WAVE_FRONT_WIDTH = 5;
+                    USER_CONFIG.WAVE_WIDTH = 5;
                     break;
                 case 3: // background off, rainbow wave
-                    USER_CONFIG.WAVE_FRONT_WIDTH = 10;
+                    USER_CONFIG.WAVE_WIDTH = 10;
                     break;
                 case 4: // background on, rainbow wave
-                    USER_CONFIG.WAVE_FRONT_WIDTH = 10;
+                    USER_CONFIG.WAVE_WIDTH = 10;
                     break;
                 case 5:
-                    USER_CONFIG.WAVE_FRONT_WIDTH = 10;
+                    USER_CONFIG.WAVE_WIDTH = 10;
 
                     USER_CONFIG.COLOR_PATTERN_INDEX = 2;
                     USER_CONFIG.TRAVEL_DISTANCE = 0;
-                    USER_CONFIG.WAVE_PERIOD = 100;
+                    USER_CONFIG.WAVE_SPEED = 10;
                     break;
                 case 6:
-                    USER_CONFIG.WAVE_FRONT_WIDTH = 25;
+                    USER_CONFIG.WAVE_WIDTH = 10;
 
                     USER_CONFIG.COLOR_PATTERN_INDEX = 3;
                     USER_CONFIG.TRAVEL_DISTANCE = 2;
-                    USER_CONFIG.WAVE_PERIOD = 10;
+                    USER_CONFIG.WAVE_SPEED = 10;
                     break;
                 }
 
                 // remove effect after changing pattern
-                for(int i = 0; i < KEY_STROKES_LENGTH; ++i){
-                    KEY_STROKES[i].alive = 0;
+                for(int i = 0; i < MAX_ACTIVE_KEYSTORKES; ++i){
+                    ACTIVE_KEYSTROKES[i].active = 0;
                 }
-                refresh_pattern_indicators();
-                refresh_color_pattern_indicators();
             }
             return false;
         case L_SP_WD:
         case L_SP_NW:
             if(record->event.pressed){
                 short incre = keycode == L_SP_WD ? 1 : -1;
-                USER_CONFIG.WAVE_FRONT_WIDTH += incre;
-                if(USER_CONFIG.WAVE_FRONT_WIDTH < 1){
-                    USER_CONFIG.WAVE_FRONT_WIDTH = 1;
+                USER_CONFIG.WAVE_WIDTH += incre;
+                if(USER_CONFIG.WAVE_WIDTH < 1){
+                    USER_CONFIG.WAVE_WIDTH = 1;
                 }
             }
             return false;
@@ -901,9 +618,11 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
             if(record->event.pressed){
                 short incre = keycode == L_SP_FA ? -1 : 1;
 
-                USER_CONFIG.WAVE_PERIOD += 10 * incre;
-                if(USER_CONFIG.WAVE_PERIOD < 10){
-                    USER_CONFIG.WAVE_PERIOD = 10;
+                USER_CONFIG.WAVE_SPEED += incre;
+                if(USER_CONFIG.WAVE_SPEED > 50){
+                    USER_CONFIG.WAVE_SPEED = 50;
+                } else if(USER_CONFIG.WAVE_SPEED < 1){
+                    USER_CONFIG.WAVE_SPEED = 1;
                 }
             }
             return false;
@@ -914,23 +633,135 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
                 uint8_t incre = keycode == L_CP_PR ? COLOR_PATTERNS_COUNT - 1 : 1;
                 USER_CONFIG.COLOR_PATTERN_INDEX += incre;
                 USER_CONFIG.COLOR_PATTERN_INDEX %= COLOR_PATTERNS_COUNT;
-                refresh_color_pattern_indicators();
+                set_wave_color(USER_CONFIG.COLOR_PATTERN_INDEX);
             }
             return false;
+
         default:
-            if (record->event.pressed){
-                uint8_t led_id = ktli(keycode);
-                if(led_id){
-                    for(int i = 0; i < KEY_STROKES_LENGTH; ++i){
-                        if(!KEY_STROKES[i].alive){
-                            KEY_STROKES[i].alive = 1;
-                            KEY_STROKES[i].led_id = led_id;
-                            KEY_STROKES[i].time = timer_read32();
-                            break;
-                        }
-                    }
-                }
+
+
+            if(record->event.pressed){
+                register_keystroke(keycode);
+
+#ifdef CONSOLE_ENABLE
+                led_info_t *entry = get_led_info_by_scancode(keycode);
+                uprintf(("KL: kc: %u, led id: %u, x: %f, y: %f, "
+                        "col: %u, row: %u, pressed: %u, time: %u\n"),
+                        keycode, entry->id, entry->x, entry->y,
+                        record->event.key.col, record->event.key.row,
+                        record->event.pressed, record->event.time);
+#endif
             }
             return true; //Process all other keycodes normally
     }
 }
+
+led_instruction_t led_instructions[] = {
+    //LEDs are normally inactive, no processing is performed on them
+    //Flags are used in matching criteria for an LED to be active and indicate how to color it
+    //Flags can be found in tmk_core/protocol/arm_atsam/led_matrix.h (prefixed with LED_FLAG_)
+    //LED IDs can be found in config_led.h in the keyboard's directory
+    //Examples are below
+
+    //All LEDs use the user's selected pattern (this is the factory default)
+    { .flags = LED_FLAG_USE_ROTATE_PATTERN },
+
+    //Specific LEDs use the user's selected pattern while all others are off
+    // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_ROTATE_PATTERN, .id0 = 0xFFFFFFFF, .id1 = 0xAAAAAAAA, .id2 = 0x55555555, .id3 = 0x11111111 },
+
+    //Specific LEDs use specified RGB values while all others are off
+    // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0xFF, .id1 = 0x00FF, .id2 = 0x0000FF00, .id3 = 0xFF000000, .r = 75, .g = 150, .b = 225 },
+
+    //All LEDs use the user's selected pattern
+    //On layer 1, all key LEDs (except the top row which keeps active pattern) are red while all edge LEDs are green
+    //When layer 1 is active, key LEDs use red    (id0  32 -  17: 1111 1111 1111 1111 0000 0000 0000 0000 = 0xFFFF0000) (except top row 16 - 1)
+    //When layer 1 is active, key LEDs use red    (id1  64 -  33: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF)
+    //When layer 1 is active, key LEDs use red    (id2  87 -  65: 0000 0000 0111 1111 1111 1111 1111 1111 = 0x007FFFFF)
+    //When layer 1 is active, edge LEDs use green (id2  95 -  88: 1111 1111 1000 0000 0000 0000 0000 0000 = 0xFF800000)
+    //When layer 1 is active, edge LEDs use green (id3 119 -  96: 0000 0000 1111 1111 1111 1111 1111 1111 = 0x00FFFFFF)
+    // { .flags = LED_FLAG_USE_ROTATE_PATTERN },
+
+    #define WAVE_LED_INSTRUCTION_START 1
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0, .id1 = 0, .id2 = 0, .g = 255 },
+    #define WAVE_LED_INSTRUCTION_END 18
+
+    //All key LEDs use red while edge LEDs use the active pattern
+    //All key LEDs use red     (id0  32 -   1: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF)
+    //All key LEDs use red     (id1  64 -  33: 1111 1111 1111 1111 1111 1111 1111 1111 = 0xFFFFFFFF)
+    //All key LEDs use red     (id2  87 -  65: 0000 0000 0111 1111 1111 1111 1111 1111 = 0x007FFFFF)
+    //Edge uses active pattern (id2  95 -  88: 1111 1111 1000 0000 0000 0000 0000 0000 = 0xFF800000)
+    //Edge uses active pattern (id3 119 -  96: 0000 0000 1111 1111 1111 1111 1111 1111 = 0x00FFFFFF)
+    // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB, .id0 = 0xFFFFFFFF, .id1 = 0xFFFFFFFF, .id2 = 0x007FFFFF, .r = 255 },
+    // { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_ROTATE_PATTERN , .id2 = 0xFF800000, .id3 = 0x00FFFFFF },
+
+     { .flags = LED_FLAG_MATCH_ID | LED_FLAG_USE_RGB | LED_FLAG_MATCH_LAYER,
+     .id1 = 0b00001111001111000000011110011110,
+     .r = 0, .g = 255, .b = 60, .layer = 2 },
+
+    //end must be set to 1 to indicate end of instruction set
+     { .end = 1 }
+};
+
+
+void set_wave_color(int color_pattern_index){
+    for(int i = WAVE_LED_INSTRUCTION_START; i < WAVE_LED_INSTRUCTION_END; ++i){
+        for(int j = 0; j < COLOR_PATTERN_RGB_COUNT; ++j){
+            led_instructions[i].r = COLOR_PATTERNS[color_pattern_index][i][0];
+            led_instructions[i].g = COLOR_PATTERNS[color_pattern_index][i][1];
+            led_instructions[i].b = COLOR_PATTERNS[color_pattern_index][i][2];
+        }
+    }
+};
+
+void wave_effect(void){
+    for(int i = WAVE_LED_INSTRUCTION_START; i < WAVE_LED_INSTRUCTION_END; ++i){
+        reset_led_for_instruction(i);
+    }
+    int wave_led_instruction_span = WAVE_LED_INSTRUCTION_END - WAVE_LED_INSTRUCTION_START;
+
+
+    keystroke_t *keystroke = ACTIVE_KEYSTROKES;
+    for(int i = 0; i < MAX_ACTIVE_KEYSTORKES; ++i, ++keystroke){
+        if(!keystroke->active) continue;
+        bool active = false;
+
+        uint16_t keystroke_led_id = get_led_info_by_scancode(keystroke->scancode)->id;
+
+        float elapsed_s = timer_elapsed32(keystroke->timer) / 1000.0f;
+        float travel = elapsed_s * USER_CONFIG.WAVE_SPEED;
+
+        for(uint16_t id = 1; id <= MAX_LED_ID; ++id){
+            float normalized_distance =
+                    led_info[id].distance_to[keystroke_led_id] /
+                    (float)DISTANCE_NORAMLIZING_PARAMETER;
+
+            if(travel >= normalized_distance && travel - normalized_distance >= 0 &&
+                    normalized_distance >= travel - USER_CONFIG.WAVE_WIDTH){
+                int portion = (travel - normalized_distance) *
+                        wave_led_instruction_span / USER_CONFIG.WAVE_WIDTH;
+                add_led_to_instruction(portion, id);
+
+                active = true;
+            }
+        }
+
+        keystroke->active = active;
+    }
+};