You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
3.2 KiB

  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. } else if (rgb_frame_buffer[row][col] > 0 && rgb_frame_buffer[row][col] < max_intensity) {
  27. // neither fully bright nor dark, decay it
  28. rgb_frame_buffer[row][col]--;
  29. }
  30. // set the pixel colour
  31. uint8_t led[LED_HITS_TO_REMEMBER];
  32. uint8_t led_count = rgb_matrix_map_row_column_to_led(row, col, led);
  33. // TODO: multiple leds are supported mapped to the same row/column
  34. if (led_count > 0) {
  35. if (rgb_frame_buffer[row][col] > pure_green_intensity) {
  36. const uint8_t boost = (uint8_t)((uint16_t)max_brightness_boost * (rgb_frame_buffer[row][col] - pure_green_intensity) / (max_intensity - pure_green_intensity));
  37. rgb_matrix_set_color(led[0], boost, max_intensity, boost);
  38. } else {
  39. const uint8_t green = (uint8_t)((uint16_t)max_intensity * rgb_frame_buffer[row][col] / pure_green_intensity);
  40. rgb_matrix_set_color(led[0], 0, green, 0);
  41. }
  42. }
  43. }
  44. }
  45. if (++drop > drop_ticks) {
  46. // reset drop timer
  47. drop = 0;
  48. for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) {
  49. for (uint8_t col = 0; col < MATRIX_COLS; col++) {
  50. // if ths is on the bottom row and bright allow decay
  51. if (row == MATRIX_ROWS - 1 && rgb_frame_buffer[row][col] == max_intensity) {
  52. rgb_frame_buffer[row][col]--;
  53. }
  54. // check if the pixel above is bright
  55. if (rgb_frame_buffer[row - 1][col] == max_intensity) {
  56. // allow old bright pixel to decay
  57. rgb_frame_buffer[row - 1][col]--;
  58. // make this pixel bright
  59. rgb_frame_buffer[row][col] = max_intensity;
  60. }
  61. }
  62. }
  63. }
  64. return false;
  65. }
  66. # endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS
  67. #endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(DISABLE_RGB_MATRIX_DIGITAL_RAIN)