digital_rain_anim.h 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_DIGITAL_RAIN)
  2. RGB_MATRIX_EFFECT(DIGITAL_RAIN)
  3. #ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS
  4. #ifndef RGB_DIGITAL_RAIN_DROPS
  5. // lower the number for denser effect/wider keyboard
  6. #define RGB_DIGITAL_RAIN_DROPS 24
  7. #endif
  8. bool DIGITAL_RAIN(effect_params_t* params) {
  9. // algorithm ported from https://github.com/tremby/Kaleidoscope-LEDEffect-DigitalRain
  10. const uint8_t drop_ticks = 28;
  11. const uint8_t pure_green_intensity = 0xd0;
  12. const uint8_t max_brightness_boost = 0xc0;
  13. const uint8_t max_intensity = 0xff;
  14. static uint8_t drop = 0;
  15. if (params->init) {
  16. rgb_matrix_set_color_all(0, 0, 0);
  17. memset(rgb_frame_buffer, 0, sizeof(rgb_frame_buffer));
  18. drop = 0;
  19. }
  20. for (uint8_t col = 0; col < MATRIX_COLS; col++) {
  21. for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
  22. if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) {
  23. // top row, pixels have just fallen and we're
  24. // making a new rain drop in this column
  25. rgb_frame_buffer[row][col] = max_intensity;
  26. }
  27. else if (rgb_frame_buffer[row][col] > 0 && rgb_frame_buffer[row][col] < max_intensity) {
  28. // neither fully bright nor dark, decay it
  29. rgb_frame_buffer[row][col]--;
  30. }
  31. // set the pixel colour
  32. uint8_t led[LED_HITS_TO_REMEMBER];
  33. uint8_t led_count = rgb_matrix_map_row_column_to_led(row, col, led);
  34. // TODO: multiple leds are supported mapped to the same row/column
  35. if (led_count > 0) {
  36. if (rgb_frame_buffer[row][col] > pure_green_intensity) {
  37. const uint8_t boost = (uint8_t) ((uint16_t) max_brightness_boost * (rgb_frame_buffer[row][col] - pure_green_intensity) / (max_intensity - pure_green_intensity));
  38. rgb_matrix_set_color(led[0], boost, max_intensity, boost);
  39. }
  40. else {
  41. const uint8_t green = (uint8_t) ((uint16_t) max_intensity * rgb_frame_buffer[row][col] / pure_green_intensity);
  42. rgb_matrix_set_color(led[0], 0, green, 0);
  43. }
  44. }
  45. }
  46. }
  47. if (++drop > drop_ticks) {
  48. // reset drop timer
  49. drop = 0;
  50. for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) {
  51. for (uint8_t col = 0; col < MATRIX_COLS; col++) {
  52. // if ths is on the bottom row and bright allow decay
  53. if (row == MATRIX_ROWS - 1 && rgb_frame_buffer[row][col] == max_intensity) {
  54. rgb_frame_buffer[row][col]--;
  55. }
  56. // check if the pixel above is bright
  57. if (rgb_frame_buffer[row - 1][col] == max_intensity) {
  58. // allow old bright pixel to decay
  59. rgb_frame_buffer[row - 1][col]--;
  60. // make this pixel bright
  61. rgb_frame_buffer[row][col] = max_intensity;
  62. }
  63. }
  64. }
  65. }
  66. return false;
  67. }
  68. #endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
  69. #endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_DIGITAL_RAIN)