RGB Matrix Overhaul (#5372)

* RGB Matrix overhaul
Breakout of animations to separate files
Integration of optimized int based math lib
Overhaul of rgb_matrix.c and animations for performance

* Updating effect function api for future extensions

* Combined the keypresses || keyreleases define checks into a single define so I stop forgetting it where necessary

* Moving define RGB_MATRIX_KEYREACTIVE_ENABLED earlier in the include chain
This commit is contained in:
XScorpion2 2019-04-02 19:24:14 -05:00 committed by Drashna Jaelre
parent 68d8bb2b3f
commit c98247e3dd
37 changed files with 3879 additions and 1010 deletions

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,6 @@
#define DEBOUNCE 3
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
#define RGB_DISABLE_WHEN_USB_SUSPENDED false // turn off effects when suspended
#define RGB_MATRIX_SKIP_FRAMES 10
#define RGB_MATRIX_KEYPRESSES
#define DISABLE_RGB_MATRIX_SPLASH
#define DISABLE_RGB_MATRIX_MULTISPLASH

View File

@ -23,7 +23,6 @@
#define DEBOUNCE 3
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
#define RGB_DISABLE_WHEN_USB_SUSPENDED false // turn off effects when suspended
#define RGB_MATRIX_SKIP_FRAMES 10
#define RGB_MATRIX_KEYPRESSES
#define DISABLE_RGB_MATRIX_SPLASH
#define DISABLE_RGB_MATRIX_MULTISPLASH

View File

@ -109,7 +109,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DRIVER_1_LED_TOTAL 24
#define DRIVER_2_LED_TOTAL 24
#define DRIVER_LED_TOTAL DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL
#define RGB_MATRIX_SKIP_FRAMES 10
// #define RGBLIGHT_COLOR_LAYER_0 0x00, 0x00, 0xFF
/* #define RGBLIGHT_COLOR_LAYER_1 0x00, 0x00, 0xFF */

View File

@ -120,7 +120,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
#define RGB_DISABLE_WHEN_USB_SUSPENDED false // turn off effects when suspended
#define RGB_MATRIX_SKIP_FRAMES 0
#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 215
#define DRIVER_ADDR_1 0b1110100

View File

@ -13,7 +13,6 @@
// #define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (not recommened)
// #define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
#define RGB_DISABLE_WHEN_USB_SUSPENDED true// turn off effects when suspended
// #define RGB_MATRIX_SKIP_FRAMES 1 // number of frames to skip when displaying animations (0 is full effect) if not defined defaults to 1
// #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
// #define EECONFIG_RGB_MATRIX (uint32_t *)16
#endif

View File

@ -18,7 +18,6 @@
// #define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (not recommened)
// #define RGB_DISABLE_AFTER_TIMEOUT 0 // number of ticks to wait until disabling effects
#define RGB_DISABLE_WHEN_USB_SUSPENDED true// turn off effects when suspended
// #define RGB_MATRIX_SKIP_FRAMES 1 // number of frames to skip when displaying animations (0 is full effect) if not defined defaults to 1
// #define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255
#define EECONFIG_RGB_MATRIX (uint32_t *)15
#endif

20
lib/lib8tion/LICENSE Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 FastLED
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

242
lib/lib8tion/lib8tion.c Normal file
View File

@ -0,0 +1,242 @@
#define FASTLED_INTERNAL
#include <stdint.h>
#define RAND16_SEED 1337
uint16_t rand16seed = RAND16_SEED;
// memset8, memcpy8, memmove8:
// optimized avr replacements for the standard "C" library
// routines memset, memcpy, and memmove.
//
// There are two techniques that make these routines
// faster than the standard avr-libc routines.
// First, the loops are unrolled 2X, meaning that
// the average loop overhead is cut in half.
// And second, the compare-and-branch at the bottom
// of each loop decrements the low byte of the
// counter, and if the carry is clear, it branches
// back up immediately. Only if the low byte math
// causes carry do we bother to decrement the high
// byte and check that result for carry as well.
// Results for a 100-byte buffer are 20-40% faster
// than standard avr-libc, at a cost of a few extra
// bytes of code.
#if defined(__AVR__)
//__attribute__ ((noinline))
void * memset8 ( void * ptr, uint8_t val, uint16_t num )
{
asm volatile(
" movw r26, %[ptr] \n\t"
" sbrs %A[num], 0 \n\t"
" rjmp Lseteven_%= \n\t"
" rjmp Lsetodd_%= \n\t"
"Lsetloop_%=: \n\t"
" st X+, %[val] \n\t"
"Lsetodd_%=: \n\t"
" st X+, %[val] \n\t"
"Lseteven_%=: \n\t"
" subi %A[num], 2 \n\t"
" brcc Lsetloop_%= \n\t"
" sbci %B[num], 0 \n\t"
" brcc Lsetloop_%= \n\t"
: [num] "+r" (num)
: [ptr] "r" (ptr),
[val] "r" (val)
: "memory"
);
return ptr;
}
//__attribute__ ((noinline))
void * memcpy8 ( void * dst, const void* src, uint16_t num )
{
asm volatile(
" movw r30, %[src] \n\t"
" movw r26, %[dst] \n\t"
" sbrs %A[num], 0 \n\t"
" rjmp Lcpyeven_%= \n\t"
" rjmp Lcpyodd_%= \n\t"
"Lcpyloop_%=: \n\t"
" ld __tmp_reg__, Z+ \n\t"
" st X+, __tmp_reg__ \n\t"
"Lcpyodd_%=: \n\t"
" ld __tmp_reg__, Z+ \n\t"
" st X+, __tmp_reg__ \n\t"
"Lcpyeven_%=: \n\t"
" subi %A[num], 2 \n\t"
" brcc Lcpyloop_%= \n\t"
" sbci %B[num], 0 \n\t"
" brcc Lcpyloop_%= \n\t"
: [num] "+r" (num)
: [src] "r" (src),
[dst] "r" (dst)
: "memory"
);
return dst;
}
//__attribute__ ((noinline))
void * memmove8 ( void * dst, const void* src, uint16_t num )
{
if( src > dst) {
// if src > dst then we can use the forward-stepping memcpy8
return memcpy8( dst, src, num);
} else {
// if src < dst then we have to step backward:
dst = (char*)dst + num;
src = (char*)src + num;
asm volatile(
" movw r30, %[src] \n\t"
" movw r26, %[dst] \n\t"
" sbrs %A[num], 0 \n\t"
" rjmp Lmoveven_%= \n\t"
" rjmp Lmovodd_%= \n\t"
"Lmovloop_%=: \n\t"
" ld __tmp_reg__, -Z \n\t"
" st -X, __tmp_reg__ \n\t"
"Lmovodd_%=: \n\t"
" ld __tmp_reg__, -Z \n\t"
" st -X, __tmp_reg__ \n\t"
"Lmoveven_%=: \n\t"
" subi %A[num], 2 \n\t"
" brcc Lmovloop_%= \n\t"
" sbci %B[num], 0 \n\t"
" brcc Lmovloop_%= \n\t"
: [num] "+r" (num)
: [src] "r" (src),
[dst] "r" (dst)
: "memory"
);
return dst;
}
}
#endif /* AVR */
#if 0
// TEST / VERIFICATION CODE ONLY BELOW THIS POINT
#include <Arduino.h>
#include "lib8tion.h"
void test1abs( int8_t i)
{
Serial.print("abs("); Serial.print(i); Serial.print(") = ");
int8_t j = abs8(i);
Serial.print(j); Serial.println(" ");
}
void testabs()
{
delay(5000);
for( int8_t q = -128; q != 127; q++) {
test1abs(q);
}
for(;;){};
}
void testmul8()
{
delay(5000);
byte r, c;
Serial.println("mul8:");
for( r = 0; r <= 20; r += 1) {
Serial.print(r); Serial.print(" : ");
for( c = 0; c <= 20; c += 1) {
byte t;
t = mul8( r, c);
Serial.print(t); Serial.print(' ');
}
Serial.println(' ');
}
Serial.println("done.");
for(;;){};
}
void testscale8()
{
delay(5000);
byte r, c;
Serial.println("scale8:");
for( r = 0; r <= 240; r += 10) {
Serial.print(r); Serial.print(" : ");
for( c = 0; c <= 240; c += 10) {
byte t;
t = scale8( r, c);
Serial.print(t); Serial.print(' ');
}
Serial.println(' ');
}
Serial.println(' ');
Serial.println("scale8_video:");
for( r = 0; r <= 100; r += 4) {
Serial.print(r); Serial.print(" : ");
for( c = 0; c <= 100; c += 4) {
byte t;
t = scale8_video( r, c);
Serial.print(t); Serial.print(' ');
}
Serial.println(' ');
}
Serial.println("done.");
for(;;){};
}
void testqadd8()
{
delay(5000);
byte r, c;
for( r = 0; r <= 240; r += 10) {
Serial.print(r); Serial.print(" : ");
for( c = 0; c <= 240; c += 10) {
byte t;
t = qadd8( r, c);
Serial.print(t); Serial.print(' ');
}
Serial.println(' ');
}
Serial.println("done.");
for(;;){};
}
void testnscale8x3()
{
delay(5000);
byte r, g, b, sc;
for( byte z = 0; z < 10; z++) {
r = random8(); g = random8(); b = random8(); sc = random8();
Serial.print("nscale8x3_video( ");
Serial.print(r); Serial.print(", ");
Serial.print(g); Serial.print(", ");
Serial.print(b); Serial.print(", ");
Serial.print(sc); Serial.print(") = [ ");
nscale8x3_video( r, g, b, sc);
Serial.print(r); Serial.print(", ");
Serial.print(g); Serial.print(", ");
Serial.print(b); Serial.print("]");
Serial.println(' ');
}
Serial.println("done.");
for(;;){};
}
#endif

934
lib/lib8tion/lib8tion.h Normal file

File diff suppressed because it is too large Load Diff

552
lib/lib8tion/math8.h Normal file

File diff suppressed because it is too large Load Diff

94
lib/lib8tion/random8.h Normal file
View File

@ -0,0 +1,94 @@
#ifndef __INC_LIB8TION_RANDOM_H
#define __INC_LIB8TION_RANDOM_H
///@ingroup lib8tion
///@defgroup Random Fast random number generators
/// Fast 8- and 16- bit unsigned random numbers.
/// Significantly faster than Arduino random(), but
/// also somewhat less random. You can add entropy.
///@{
// X(n+1) = (2053 * X(n)) + 13849)
#define FASTLED_RAND16_2053 ((uint16_t)(2053))
#define FASTLED_RAND16_13849 ((uint16_t)(13849))
/// random number seed
extern uint16_t rand16seed;// = RAND16_SEED;
/// Generate an 8-bit random number
LIB8STATIC uint8_t random8(void)
{
rand16seed = (rand16seed * FASTLED_RAND16_2053) + FASTLED_RAND16_13849;
// return the sum of the high and low bytes, for better
// mixing and non-sequential correlation
return (uint8_t)(((uint8_t)(rand16seed & 0xFF)) +
((uint8_t)(rand16seed >> 8)));
}
/// Generate a 16 bit random number
LIB8STATIC uint16_t random16(void)
{
rand16seed = (rand16seed * FASTLED_RAND16_2053) + FASTLED_RAND16_13849;
return rand16seed;
}
/// Generate an 8-bit random number between 0 and lim
/// @param lim the upper bound for the result
LIB8STATIC uint8_t random8_max(uint8_t lim)
{
uint8_t r = random8();
r = (r*lim) >> 8;
return r;
}
/// Generate an 8-bit random number in the given range
/// @param min the lower bound for the random number
/// @param lim the upper bound for the random number
LIB8STATIC uint8_t random8_min_max(uint8_t min, uint8_t lim)
{
uint8_t delta = lim - min;
uint8_t r = random8_max(delta) + min;
return r;
}
/// Generate an 16-bit random number between 0 and lim
/// @param lim the upper bound for the result
LIB8STATIC uint16_t random16_max(uint16_t lim)
{
uint16_t r = random16();
uint32_t p = (uint32_t)lim * (uint32_t)r;
r = p >> 16;
return r;
}
/// Generate an 16-bit random number in the given range
/// @param min the lower bound for the random number
/// @param lim the upper bound for the random number
LIB8STATIC uint16_t random16_min_max( uint16_t min, uint16_t lim)
{
uint16_t delta = lim - min;
uint16_t r = random16_max(delta) + min;
return r;
}
/// Set the 16-bit seed used for the random number generator
LIB8STATIC void random16_set_seed(uint16_t seed)
{
rand16seed = seed;
}
/// Get the current seed value for the random number generator
LIB8STATIC uint16_t random16_get_seed(void)
{
return rand16seed;
}
/// Add entropy into the random number generator
LIB8STATIC void random16_add_entropy(uint16_t entropy)
{
rand16seed += entropy;
}
///@}
#endif

542
lib/lib8tion/scale8.h Normal file

File diff suppressed because it is too large Load Diff

259
lib/lib8tion/trig8.h Normal file
View File

@ -0,0 +1,259 @@
#ifndef __INC_LIB8TION_TRIG_H
#define __INC_LIB8TION_TRIG_H
///@ingroup lib8tion
///@defgroup Trig Fast trig functions
/// Fast 8 and 16-bit approximations of sin(x) and cos(x).
/// Don't use these approximations for calculating the
/// trajectory of a rocket to Mars, but they're great
/// for art projects and LED displays.
///
/// On Arduino/AVR, the 16-bit approximation is more than
/// 10X faster than floating point sin(x) and cos(x), while
/// the 8-bit approximation is more than 20X faster.
///@{
#if defined(__AVR__)
#define sin16 sin16_avr
#else
#define sin16 sin16_C
#endif
/// Fast 16-bit approximation of sin(x). This approximation never varies more than
/// 0.69% from the floating point value you'd get by doing
///
/// float s = sin(x) * 32767.0;
///
/// @param theta input angle from 0-65535
/// @returns sin of theta, value between -32767 to 32767.
LIB8STATIC int16_t sin16_avr( uint16_t theta )
{
static const uint8_t data[] =
{ 0, 0, 49, 0, 6393%256, 6393/256, 48, 0,
12539%256, 12539/256, 44, 0, 18204%256, 18204/256, 38, 0,
23170%256, 23170/256, 31, 0, 27245%256, 27245/256, 23, 0,
30273%256, 30273/256, 14, 0, 32137%256, 32137/256, 4 /*,0*/ };
uint16_t offset = (theta & 0x3FFF);
// AVR doesn't have a multi-bit shift instruction,
// so if we say "offset >>= 3", gcc makes a tiny loop.
// Inserting empty volatile statements between each
// bit shift forces gcc to unroll the loop.
offset >>= 1; // 0..8191
asm volatile("");
offset >>= 1; // 0..4095
asm volatile("");
offset >>= 1; // 0..2047
if( theta & 0x4000 ) offset = 2047 - offset;
uint8_t sectionX4;
sectionX4 = offset / 256;
sectionX4 *= 4;
uint8_t m;
union {
uint16_t b;
struct {
uint8_t blo;
uint8_t bhi;
};
} u;
//in effect u.b = blo + (256 * bhi);
u.blo = data[ sectionX4 ];
u.bhi = data[ sectionX4 + 1];
m = data[ sectionX4 + 2];
uint8_t secoffset8 = (uint8_t)(offset) / 2;
uint16_t mx = m * secoffset8;
int16_t y = mx + u.b;
if( theta & 0x8000 ) y = -y;
return y;
}
/// Fast 16-bit approximation of sin(x). This approximation never varies more than
/// 0.69% from the floating point value you'd get by doing
///
/// float s = sin(x) * 32767.0;
///
/// @param theta input angle from 0-65535
/// @returns sin of theta, value between -32767 to 32767.
LIB8STATIC int16_t sin16_C( uint16_t theta )
{
static const uint16_t base[] =
{ 0, 6393, 12539, 18204, 23170, 27245, 30273, 32137 };
static const uint8_t slope[] =
{ 49, 48, 44, 38, 31, 23, 14, 4 };
uint16_t offset = (theta & 0x3FFF) >> 3; // 0..2047
if( theta & 0x4000 ) offset = 2047 - offset;
uint8_t section = offset / 256; // 0..7
uint16_t b = base[section];
uint8_t m = slope[section];
uint8_t secoffset8 = (uint8_t)(offset) / 2;
uint16_t mx = m * secoffset8;
int16_t y = mx + b;
if( theta & 0x8000 ) y = -y;
return y;
}
/// Fast 16-bit approximation of cos(x). This approximation never varies more than
/// 0.69% from the floating point value you'd get by doing
///
/// float s = cos(x) * 32767.0;
///
/// @param theta input angle from 0-65535
/// @returns sin of theta, value between -32767 to 32767.
LIB8STATIC int16_t cos16( uint16_t theta)
{
return sin16( theta + 16384);
}
///////////////////////////////////////////////////////////////////////
// sin8 & cos8
// Fast 8-bit approximations of sin(x) & cos(x).
// Input angle is an unsigned int from 0-255.
// Output is an unsigned int from 0 to 255.
//
// This approximation can vary to to 2%
// from the floating point value you'd get by doing
// float s = (sin( x ) * 128.0) + 128;
//
// Don't use this approximation for calculating the
// "real" trigonometric calculations, but it's great
// for art projects and LED displays.
//
// On Arduino/AVR, this approximation is more than
// 20X faster than floating point sin(x) and cos(x)
#if defined(__AVR__) && !defined(LIB8_ATTINY)
#define sin8 sin8_avr
#else
#define sin8 sin8_C
#endif
const uint8_t b_m16_interleave[] = { 0, 49, 49, 41, 90, 27, 117, 10 };
/// Fast 8-bit approximation of sin(x). This approximation never varies more than
/// 2% from the floating point value you'd get by doing
///
/// float s = (sin(x) * 128.0) + 128;
///
/// @param theta input angle from 0-255
/// @returns sin of theta, value between 0 and 255
LIB8STATIC uint8_t sin8_avr( uint8_t theta)
{
uint8_t offset = theta;
asm volatile(
"sbrc %[theta],6 \n\t"
"com %[offset] \n\t"
: [theta] "+r" (theta), [offset] "+r" (offset)
);
offset &= 0x3F; // 0..63
uint8_t secoffset = offset & 0x0F; // 0..15
if( theta & 0x40) secoffset++;
uint8_t m16; uint8_t b;
uint8_t section = offset >> 4; // 0..3
uint8_t s2 = section * 2;
const uint8_t* p = b_m16_interleave;
p += s2;
b = *p;
p++;
m16 = *p;
uint8_t mx;
uint8_t xr1;
asm volatile(
"mul %[m16],%[secoffset] \n\t"
"mov %[mx],r0 \n\t"
"mov %[xr1],r1 \n\t"
"eor r1, r1 \n\t"
"swap %[mx] \n\t"
"andi %[mx],0x0F \n\t"
"swap %[xr1] \n\t"
"andi %[xr1], 0xF0 \n\t"
"or %[mx], %[xr1] \n\t"
: [mx] "=d" (mx), [xr1] "=d" (xr1)
: [m16] "d" (m16), [secoffset] "d" (secoffset)
);
int8_t y = mx + b;
if( theta & 0x80 ) y = -y;
y += 128;
return y;
}
/// Fast 8-bit approximation of sin(x). This approximation never varies more than
/// 2% from the floating point value you'd get by doing
///
/// float s = (sin(x) * 128.0) + 128;
///
/// @param theta input angle from 0-255
/// @returns sin of theta, value between 0 and 255
LIB8STATIC uint8_t sin8_C( uint8_t theta)
{
uint8_t offset = theta;
if( theta & 0x40 ) {
offset = (uint8_t)255 - offset;
}
offset &= 0x3F; // 0..63
uint8_t secoffset = offset & 0x0F; // 0..15
if( theta & 0x40) secoffset++;
uint8_t section = offset >> 4; // 0..3
uint8_t s2 = section * 2;
const uint8_t* p = b_m16_interleave;
p += s2;
uint8_t b = *p;
p++;
uint8_t m16 = *p;
uint8_t mx = (m16 * secoffset) >> 4;
int8_t y = mx + b;
if( theta & 0x80 ) y = -y;
y += 128;
return y;
}
/// Fast 8-bit approximation of cos(x). This approximation never varies more than
/// 2% from the floating point value you'd get by doing
///
/// float s = (cos(x) * 128.0) + 128;
///
/// @param theta input angle from 0-255
/// @returns sin of theta, value between 0 and 255
LIB8STATIC uint8_t cos8( uint8_t theta)
{
return sin8( theta + 64);
}
///@}
#endif

View File

@ -78,9 +78,11 @@ RGB hsv_to_rgb( HSV hsv )
break;
}
#ifdef USE_CIE1931_CURVE
rgb.r = pgm_read_byte( &CIE1931_CURVE[rgb.r] );
rgb.g = pgm_read_byte( &CIE1931_CURVE[rgb.g] );
rgb.b = pgm_read_byte( &CIE1931_CURVE[rgb.b] );
#endif
return rgb;
}

View File

@ -274,10 +274,10 @@ bool process_record_quantum(keyrecord_t *record) {
#ifdef HAPTIC_ENABLE
process_haptic(keycode, record) &&
#endif //HAPTIC_ENABLE
process_record_kb(keycode, record) &&
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYPRESSES)
#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_KEYREACTIVE_ENABLED)
process_rgb_matrix(keycode, record) &&
#endif
process_record_kb(keycode, record) &&
#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED)
process_midi(keycode, record) &&
#endif
@ -1049,12 +1049,6 @@ void matrix_init_quantum() {
matrix_init_kb();
}
uint8_t rgb_matrix_task_counter = 0;
#ifndef RGB_MATRIX_SKIP_FRAMES
#define RGB_MATRIX_SKIP_FRAMES 1
#endif
void matrix_scan_quantum() {
#if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE)
matrix_scan_music();
@ -1078,10 +1072,6 @@ void matrix_scan_quantum() {
#ifdef RGB_MATRIX_ENABLE
rgb_matrix_task();
if (rgb_matrix_task_counter == 0) {
rgb_matrix_update_pwm_buffers();
}
rgb_matrix_task_counter = ((rgb_matrix_task_counter + 1) % (RGB_MATRIX_SKIP_FRAMES + 1));
#endif
#ifdef ENCODER_ENABLE

File diff suppressed because it is too large Load Diff

View File

@ -21,32 +21,33 @@
#include <stdint.h>
#include <stdbool.h>
#include "rgb_matrix_types.h"
#include "color.h"
#include "quantum.h"
#ifdef IS31FL3731
#include "is31fl3731.h"
#include "is31fl3731.h"
#elif defined (IS31FL3733)
#include "is31fl3733.h"
#include "is31fl3733.h"
#endif
typedef struct Point {
uint8_t x;
uint8_t y;
} __attribute__((packed)) Point;
#ifndef RGB_MATRIX_LED_FLUSH_LIMIT
#define RGB_MATRIX_LED_FLUSH_LIMIT 16
#endif
typedef struct rgb_led {
union {
uint8_t raw;
struct {
uint8_t row:4; // 16 max
uint8_t col:4; // 16 max
};
} matrix_co;
Point point;
uint8_t modifier:1;
} __attribute__((packed)) rgb_led;
#ifndef RGB_MATRIX_LED_PROCESS_LIMIT
#define RGB_MATRIX_LED_PROCESS_LIMIT (DRIVER_LED_TOTAL + 4) / 5
#endif
#if defined(RGB_MATRIX_LED_PROCESS_LIMIT) && RGB_MATRIX_LED_PROCESS_LIMIT > 0 && RGB_MATRIX_LED_PROCESS_LIMIT < DRIVER_LED_TOTAL
#define RGB_MATRIX_USE_LIMITS(min, max) uint8_t min = RGB_MATRIX_LED_PROCESS_LIMIT * params->iter; \
uint8_t max = min + RGB_MATRIX_LED_PROCESS_LIMIT; \
if (max > DRIVER_LED_TOTAL) \
max = DRIVER_LED_TOTAL;
#else
#define RGB_MATRIX_USE_LIMITS(min, max) uint8_t min = 0; \
uint8_t max = DRIVER_LED_TOTAL;
#endif
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
@ -56,79 +57,73 @@ typedef struct
uint8_t index;
} rgb_indicator;
typedef union {
uint32_t raw;
struct {
bool enable :1;
uint8_t mode :6;
uint16_t hue :9;
uint8_t sat :8;
uint8_t val :8;
uint8_t speed :8;//EECONFIG needs to be increased to support this
};
} rgb_config_t;
enum rgb_matrix_effects {
RGB_MATRIX_NONE = 0,
RGB_MATRIX_SOLID_COLOR = 1,
#ifndef DISABLE_RGB_MATRIX_ALPHAS_MODS
RGB_MATRIX_ALPHAS_MODS,
#endif
#ifndef DISABLE_RGB_MATRIX_DUAL_BEACON
RGB_MATRIX_DUAL_BEACON,
#endif
RGB_MATRIX_ALPHAS_MODS,
#endif // DISABLE_RGB_MATRIX_ALPHAS_MODS
#ifndef DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
RGB_MATRIX_GRADIENT_UP_DOWN,
#endif
#ifndef DISABLE_RGB_MATRIX_RAINDROPS
RGB_MATRIX_RAINDROPS,
#endif
RGB_MATRIX_GRADIENT_UP_DOWN,
#endif // DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
#ifndef DISABLE_RGB_MATRIX_BREATHING
RGB_MATRIX_BREATHING,
#endif // DISABLE_RGB_MATRIX_BREATHING
#ifndef DISABLE_RGB_MATRIX_CYCLE_ALL
RGB_MATRIX_CYCLE_ALL,
#endif
RGB_MATRIX_CYCLE_ALL,
#endif // DISABLE_RGB_MATRIX_CYCLE_ALL
#ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
RGB_MATRIX_CYCLE_LEFT_RIGHT,
#endif
RGB_MATRIX_CYCLE_LEFT_RIGHT,
#endif // DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
#ifndef DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
RGB_MATRIX_CYCLE_UP_DOWN,
#endif
#ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON
RGB_MATRIX_RAINBOW_BEACON,
#endif
#ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
RGB_MATRIX_RAINBOW_PINWHEELS,
#endif
RGB_MATRIX_CYCLE_UP_DOWN,
#endif // DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
#ifndef DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
RGB_MATRIX_RAINBOW_MOVING_CHEVRON,
#endif
RGB_MATRIX_RAINBOW_MOVING_CHEVRON,
#endif // DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
#ifndef DISABLE_RGB_MATRIX_DUAL_BEACON
RGB_MATRIX_DUAL_BEACON,
#endif // DISABLE_RGB_MATRIX_DUAL_BEACON
#ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON
RGB_MATRIX_RAINBOW_BEACON,
#endif // DISABLE_RGB_MATRIX_RAINBOW_BEACON
#ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
RGB_MATRIX_RAINBOW_PINWHEELS,
#endif // DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
#ifndef DISABLE_RGB_MATRIX_RAINDROPS
RGB_MATRIX_RAINDROPS,
#endif // DISABLE_RGB_MATRIX_RAINDROPS
#ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
RGB_MATRIX_JELLYBEAN_RAINDROPS,
#endif
RGB_MATRIX_JELLYBEAN_RAINDROPS,
#endif // DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN
RGB_MATRIX_DIGITAL_RAIN,
#endif
#ifdef RGB_MATRIX_KEYPRESSES
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE
RGB_MATRIX_SOLID_REACTIVE,
#endif
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
RGB_MATRIX_SOLID_REACTIVE_SIMPLE,
#endif
#ifndef DISABLE_RGB_MATRIX_SPLASH
RGB_MATRIX_SPLASH,
#endif
#ifndef DISABLE_RGB_MATRIX_MULTISPLASH
RGB_MATRIX_MULTISPLASH,
#endif
#ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH
RGB_MATRIX_SOLID_SPLASH,
#endif
#ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
RGB_MATRIX_SOLID_MULTISPLASH,
#endif
#endif
RGB_MATRIX_EFFECT_MAX
RGB_MATRIX_DIGITAL_RAIN,
#endif // DISABLE_RGB_MATRIX_DIGITAL_RAIN
#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
RGB_MATRIX_SOLID_REACTIVE_SIMPLE,
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE
#ifndef DISABLE_RGB_MATRIX_SOLID_REACTIVE
RGB_MATRIX_SOLID_REACTIVE,
#endif // DISABLE_RGB_MATRIX_SOLID_REACTIVE
#ifndef DISABLE_RGB_MATRIX_SPLASH
RGB_MATRIX_SPLASH,
#endif // DISABLE_RGB_MATRIX_SPLASH
#ifndef DISABLE_RGB_MATRIX_MULTISPLASH
RGB_MATRIX_MULTISPLASH,
#endif // DISABLE_RGB_MATRIX_MULTISPLASH
#ifndef DISABLE_RGB_MATRIX_SOLID_SPLASH
RGB_MATRIX_SOLID_SPLASH,
#endif // DISABLE_RGB_MATRIX_SOLID_SPLASH
#ifndef DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
RGB_MATRIX_SOLID_MULTISPLASH,
#endif // DISABLE_RGB_MATRIX_SOLID_MULTISPLASH
#endif // RGB_MATRIX_KEYREACTIVE_ENABLED
RGB_MATRIX_EFFECT_MAX
};
uint8_t rgb_matrix_map_row_column_to_led( uint8_t row, uint8_t column, uint8_t *led_i);
void rgb_matrix_set_color( int index, uint8_t red, uint8_t green, uint8_t blue );
void rgb_matrix_set_color_all( uint8_t red, uint8_t green, uint8_t blue );
@ -162,8 +157,6 @@ void rgb_matrix_decrease(void);
// void backlight_get_key_color( uint8_t led, HSV *hsv );
// void backlight_set_key_color( uint8_t row, uint8_t column, HSV hsv );
uint32_t rgb_matrix_get_tick(void);
void rgb_matrix_toggle(void);
void rgb_matrix_enable(void);
void rgb_matrix_enable_noeeprom(void);
@ -212,7 +205,6 @@ uint8_t rgb_matrix_get_mode(void);
typedef struct {
/* Perform any initialisation required for the other driver functions to work. */
void (*init)(void);
/* Set the colour of a single LED in the buffer. */
void (*set_color)(int index, uint8_t r, uint8_t g, uint8_t b);
/* Set the colour of all LEDS on the keyboard in the buffer. */

View File

@ -0,0 +1,26 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_ALPHAS_MODS
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
// alphas = color1, mods = color2
bool rgb_matrix_alphas_mods(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, rgb_matrix_config.val };
RGB rgb1 = hsv_to_rgb(hsv);
hsv.h += rgb_matrix_config.speed;
RGB rgb2 = hsv_to_rgb(hsv);
for (uint8_t i = led_min; i < led_max; i++) {
if (g_rgb_leds[i].modifier) {
rgb_matrix_set_color(i, rgb2.r, rgb2.g, rgb2.b);
} else {
rgb_matrix_set_color(i, rgb1.r, rgb1.g, rgb1.b);
}
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_ALPHAS_MODS

View File

@ -0,0 +1,19 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_BREATHING
extern rgb_config_t rgb_matrix_config;
bool rgb_matrix_breathing(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 8);
uint8_t val = scale8(abs8(sin8(time) - 128) * 2, rgb_matrix_config.val);
HSV hsv = { rgb_matrix_config.hue, rgb_matrix_config.sat, val };
RGB rgb = hsv_to_rgb(hsv);
for (uint8_t i = led_min; i < led_max; i++) {
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_BREATHING

View File

@ -0,0 +1,21 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_CYCLE_ALL
extern rgb_counters_t g_rgb_counters;
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
bool rgb_matrix_cycle_all(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
for (uint8_t i = led_min; i < led_max; i++) {
hsv.h = time;
RGB rgb = hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_CYCLE_ALL

View File

@ -0,0 +1,22 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT
extern rgb_counters_t g_rgb_counters;
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
bool rgb_matrix_cycle_left_right(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
for (uint8_t i = led_min; i < led_max; i++) {
point_t point = g_rgb_leds[i].point;
hsv.h = point.x - time;
RGB rgb = hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT

View File

@ -0,0 +1,22 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_CYCLE_UP_DOWN
extern rgb_counters_t g_rgb_counters;
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
bool rgb_matrix_cycle_up_down(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
for (uint8_t i = led_min; i < led_max; i++) {
point_t point = g_rgb_leds[i].point;
hsv.h = point.y - time;
RGB rgb = hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_CYCLE_UP_DOWN

View File

@ -0,0 +1,74 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_DIGITAL_RAIN
#ifndef RGB_DIGITAL_RAIN_DROPS
// lower the number for denser effect/wider keyboard
#define RGB_DIGITAL_RAIN_DROPS 24
#endif
bool rgb_matrix_digital_rain(effect_params_t* params) {
// algorithm ported from https://github.com/tremby/Kaleidoscope-LEDEffect-DigitalRain
const uint8_t drop_ticks = 28;
const uint8_t pure_green_intensity = 0xd0;
const uint8_t max_brightness_boost = 0xc0;
const uint8_t max_intensity = 0xff;
static uint8_t map[MATRIX_COLS][MATRIX_ROWS] = {{0}};
static uint8_t drop = 0;
if (params->init) {
rgb_matrix_set_color_all(0, 0, 0);
memset(map, 0, sizeof map);
drop = 0;
}
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) {
// top row, pixels have just fallen and we're
// making a new rain drop in this column
map[col][row] = max_intensity;
}
else if (map[col][row] > 0 && map[col][row] < max_intensity) {
// neither fully bright nor dark, decay it
map[col][row]--;
}
// set the pixel colour
uint8_t led[LED_HITS_TO_REMEMBER];
uint8_t led_count = rgb_matrix_map_row_column_to_led(row, col, led);
// TODO: multiple leds are supported mapped to the same row/column
if (led_count > 0) {
if (map[col][row] > pure_green_intensity) {
const uint8_t boost = (uint8_t) ((uint16_t) max_brightness_boost * (map[col][row] - pure_green_intensity) / (max_intensity - pure_green_intensity));
rgb_matrix_set_color(led[0], boost, max_intensity, boost);
}
else {
const uint8_t green = (uint8_t) ((uint16_t) max_intensity * map[col][row] / pure_green_intensity);
rgb_matrix_set_color(led[0], 0, green, 0);
}
}
}
}
if (++drop > drop_ticks) {
// reset drop timer
drop = 0;
for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) {
for (uint8_t col = 0; col < MATRIX_COLS; col++) {
// if ths is on the bottom row and bright allow decay
if (row == MATRIX_ROWS - 1 && map[col][row] == max_intensity) {
map[col][row]--;
}
// check if the pixel above is bright
if (map[col][row - 1] == max_intensity) {
// allow old bright pixel to decay
map[col][row - 1]--;
// make this pixel bright
map[col][row] = max_intensity;
}
}
}
}
return false;
}
#endif // DISABLE_RGB_MATRIX_DIGITAL_RAIN

View File

@ -0,0 +1,24 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_DUAL_BEACON
extern rgb_counters_t g_rgb_counters;
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
bool rgb_matrix_dual_beacon(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
int8_t cos_value = cos8(time) - 128;
int8_t sin_value = sin8(time) - 128;
for (uint8_t i = led_min; i < led_max; i++) {
point_t point = g_rgb_leds[i].point;
hsv.h = ((point.y - 32) * cos_value + (point.x - 112) * sin_value) / 128 + rgb_matrix_config.hue;
RGB rgb = hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_DUAL_BEACON

View File

@ -0,0 +1,22 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
bool rgb_matrix_gradient_up_down(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
uint8_t scale = scale8(64, rgb_matrix_config.speed);
for (uint8_t i = led_min; i < led_max; i++) {
point_t point = g_rgb_leds[i].point;
// The y range will be 0..64, map this to 0..4
// Relies on hue being 8-bit and wrapping
hsv.h = rgb_matrix_config.hue + scale * (point.y >> 4);
RGB rgb = hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_GRADIENT_UP_DOWN

View File

@ -0,0 +1,30 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS
extern rgb_counters_t g_rgb_counters;
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
static void jellybean_raindrops_set_color(int i) {
HSV hsv = { rand() & 0xFF , rand() & 0xFF, rgb_matrix_config.val };
RGB rgb = hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
bool rgb_matrix_jellybean_raindrops(effect_params_t* params) {
if (!params->init) {
// Change one LED every tick, make sure speed is not 0
if (scale16by8(g_rgb_counters.tick, qadd8(rgb_matrix_config.speed, 16)) % 5 == 0) {
jellybean_raindrops_set_color(rand() % DRIVER_LED_TOTAL);
}
return false;
}
RGB_MATRIX_USE_LIMITS(led_min, led_max);
for (int i = led_min; i < led_max; i++) {
jellybean_raindrops_set_color(i);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS

View File

@ -0,0 +1,24 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_RAINBOW_BEACON
extern rgb_counters_t g_rgb_counters;
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
bool rgb_matrix_rainbow_beacon(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
int16_t cos_value = 2 * (cos8(time) - 128);
int16_t sin_value = 2 * (sin8(time) - 128);
for (uint8_t i = led_min; i < led_max; i++) {
point_t point = g_rgb_leds[i].point;
hsv.h = ((point.y - 32) * cos_value + (point.x - 112) * sin_value) / 128 + rgb_matrix_config.hue;
RGB rgb = hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_RAINBOW_BEACON

View File

@ -0,0 +1,22 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON
extern rgb_counters_t g_rgb_counters;
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
bool rgb_matrix_rainbow_moving_chevron(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
uint8_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
for (uint8_t i = led_min; i < led_max; i++) {
point_t point = g_rgb_leds[i].point;
hsv.h = abs8(point.y - 32) + (point.x - time) + rgb_matrix_config.hue;
RGB rgb = hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON

View File

@ -0,0 +1,24 @@
#pragma once
#ifndef DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS
extern rgb_counters_t g_rgb_counters;
extern const rgb_led g_rgb_leds[DRIVER_LED_TOTAL];
extern rgb_config_t rgb_matrix_config;
bool rgb_matrix_rainbow_pinwheels(effect_params_t* params) {
RGB_MATRIX_USE_LIMITS(led_min, led_max);
HSV hsv = { 0, rgb_matrix_config.sat, rgb_matrix_config.val };
uint16_t time = scale16by8(g_rgb_counters.tick, rgb_matrix_config.speed / 4);
int16_t cos_value = 3 * (cos8(time) - 128);
int16_t sin_value = 3 * (sin8(time) - 128);
for (uint8_t i = led_min; i < led_max; i++) {
point_t point = g_rgb_leds[i].point;
hsv.h = ((point.y - 32) * cos_value + (56 - abs8(point.x - 112)) * sin_value) / 128 + rgb_matrix_config.hue;
RGB rgb = hsv_to_rgb(hsv);
rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b);
}
return led_max < DRIVER_LED_TOTAL;
}
#endif // DISABLE_RGB_MATRIX_RAINBOW_PINWHEELS

Some files were not shown because too many files have changed in this diff Show More