qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

typing_heatmap_anim.h (4619B)


      1 #if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP)
      2 RGB_MATRIX_EFFECT(TYPING_HEATMAP)
      3 #    ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
      4 #        ifndef RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP
      5 #            define RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP 32
      6 #        endif
      7 
      8 #        ifndef RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS
      9 #            define RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS 25
     10 #        endif
     11 
     12 #        ifndef RGB_MATRIX_TYPING_HEATMAP_SPREAD
     13 #            define RGB_MATRIX_TYPING_HEATMAP_SPREAD 40
     14 #        endif
     15 
     16 #        ifndef RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT
     17 #            define RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT 16
     18 #        endif
     19 void process_rgb_matrix_typing_heatmap(uint8_t row, uint8_t col) {
     20 #        ifdef RGB_MATRIX_TYPING_HEATMAP_SLIM
     21     // Limit effect to pressed keys
     22     g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP);
     23 #        else
     24     if (g_led_config.matrix_co[row][col] == NO_LED) { // skip as pressed key doesn't have an led position
     25         return;
     26     }
     27     for (uint8_t i_row = 0; i_row < MATRIX_ROWS; i_row++) {
     28         for (uint8_t i_col = 0; i_col < MATRIX_COLS; i_col++) {
     29             if (g_led_config.matrix_co[i_row][i_col] == NO_LED) { // skip as target key doesn't have an led position
     30                 continue;
     31             }
     32             if (i_row == row && i_col == col) {
     33                 g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP);
     34             } else {
     35 #            define LED_DISTANCE(led_a, led_b) sqrt16(((int32_t)(led_a.x - led_b.x) * (int32_t)(led_a.x - led_b.x)) + ((int32_t)(led_a.y - led_b.y) * (int32_t)(led_a.y - led_b.y)))
     36                 uint8_t distance = LED_DISTANCE(g_led_config.point[g_led_config.matrix_co[row][col]], g_led_config.point[g_led_config.matrix_co[i_row][i_col]]);
     37 #            undef LED_DISTANCE
     38                 if (distance <= RGB_MATRIX_TYPING_HEATMAP_SPREAD) {
     39                     uint8_t amount = qsub8(RGB_MATRIX_TYPING_HEATMAP_SPREAD, distance);
     40                     if (amount > RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT) {
     41                         amount = RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT;
     42                     }
     43                     g_rgb_frame_buffer[i_row][i_col] = qadd8(g_rgb_frame_buffer[i_row][i_col], amount);
     44                 }
     45             }
     46         }
     47     }
     48 #        endif
     49 }
     50 
     51 // A timer to track the last time we decremented all heatmap values.
     52 static uint16_t heatmap_decrease_timer;
     53 // Whether we should decrement the heatmap values during the next update.
     54 static bool decrease_heatmap_values;
     55 
     56 bool TYPING_HEATMAP(effect_params_t* params) {
     57     RGB_MATRIX_USE_LIMITS(led_min, led_max);
     58 
     59     if (params->init) {
     60         rgb_matrix_set_color_all(0, 0, 0);
     61         memset(g_rgb_frame_buffer, 0, sizeof g_rgb_frame_buffer);
     62     }
     63 
     64     // The heatmap animation might run in several iterations depending on
     65     // `RGB_MATRIX_LED_PROCESS_LIMIT`, therefore we only want to update the
     66     // timer when the animation starts.
     67     if (params->iter == 0) {
     68         decrease_heatmap_values = timer_elapsed(heatmap_decrease_timer) >= RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS;
     69 
     70         // Restart the timer if we are going to decrease the heatmap this frame.
     71         if (decrease_heatmap_values) {
     72             heatmap_decrease_timer = timer_read();
     73         }
     74     }
     75 
     76     // Render heatmap & decrease
     77     uint8_t count = 0;
     78     for (uint8_t row = 0; row < MATRIX_ROWS && count < RGB_MATRIX_LED_PROCESS_LIMIT; row++) {
     79         for (uint8_t col = 0; col < MATRIX_COLS && RGB_MATRIX_LED_PROCESS_LIMIT; col++) {
     80             if (g_led_config.matrix_co[row][col] >= led_min && g_led_config.matrix_co[row][col] < led_max) {
     81                 count++;
     82                 uint8_t val = g_rgb_frame_buffer[row][col];
     83                 if (!HAS_ANY_FLAGS(g_led_config.flags[g_led_config.matrix_co[row][col]], params->flags)) continue;
     84 
     85                 hsv_t hsv = {170 - qsub8(val, 85), rgb_matrix_config.hsv.s, scale8((qadd8(170, val) - 170) * 3, rgb_matrix_config.hsv.v)};
     86                 rgb_t rgb = rgb_matrix_hsv_to_rgb(hsv);
     87                 rgb_matrix_set_color(g_led_config.matrix_co[row][col], rgb.r, rgb.g, rgb.b);
     88 
     89                 if (decrease_heatmap_values) {
     90                     g_rgb_frame_buffer[row][col] = qsub8(val, 1);
     91                 }
     92             }
     93         }
     94     }
     95 
     96     return rgb_matrix_check_finished_leds(led_max);
     97 }
     98 
     99 #    endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
    100 #endif     // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP)