qmk_firmware

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

led_matrix_module.inc (2475B)


      1 // Copyright 2024-2025 Google LLC
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     https://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 LED_MATRIX_EFFECT(FLOW)
     16 
     17 #ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS
     18 
     19 // "Flow" animated effect. Draws moving wave patterns mimicking the appearance
     20 // of flowing liquid. For interesting variety of patterns, space coordinates are
     21 // slowly rotated and a function of several sine waves is evaluated.
     22 static bool FLOW(effect_params_t* params) {
     23     LED_MATRIX_USE_LIMITS(led_min, led_max);
     24 
     25     static uint16_t wrap_correction = 0;
     26     static uint8_t  last_high_byte  = 0;
     27     const uint8_t   time_scale      = 1 + led_matrix_eeconfig.speed / 8;
     28     const uint8_t   high_byte       = (uint8_t)(g_led_timer >> 16);
     29     if (last_high_byte != high_byte) {
     30         last_high_byte = high_byte;
     31         wrap_correction += ((uint16_t)time_scale) << 8;
     32     }
     33     const uint16_t time = scale16by8(g_led_timer, time_scale) + wrap_correction;
     34 
     35     // Compute rotation coefficients with 7 fractional bits.
     36     const int8_t  rot_c = cos8(time / 4) - 128;
     37     const int8_t  rot_s = sin8(time / 4) - 128;
     38     const uint8_t omega = 32 + sin8(time) / 4;
     39 
     40     for (uint8_t i = led_min; i < led_max; ++i) {
     41         LED_MATRIX_TEST_LED_FLAGS();
     42         const uint8_t x = g_led_config.point[i].x;
     43         const uint8_t y = g_led_config.point[i].y;
     44 
     45         // Rotate (x, y) by the 2x2 rotation matrix described by rot_c, rot_s.
     46         const uint8_t x1 = (uint8_t)((((int16_t)rot_c) * ((int16_t)x)) / 128) - (uint8_t)((((int16_t)rot_s) * ((int16_t)y)) / 128);
     47         const uint8_t y1 = (uint8_t)((((int16_t)rot_s) * ((int16_t)x)) / 128) + (uint8_t)((((int16_t)rot_c) * ((int16_t)y)) / 128);
     48 
     49         uint8_t value = scale8(sin8(x1 - 2 * time), omega) + y1 + time / 4;
     50         value         = (value <= 127) ? value : (255 - value);
     51 
     52         led_matrix_set_value(i, scale8(led_matrix_eeconfig.val, value));
     53     }
     54 
     55     return led_matrix_check_finished_leds(led_max);
     56 }
     57 
     58 #endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS