* Tidy up LCD_ENABLE/visualizer references * Fix up my (333fred) ergodox keymap with new LCD driver Co-authored-by: Fredric Silberberg <fred@silberberg.xyz>pull/14899/head
@ -1,123 +0,0 @@ | |||
/* Copyright 2017 Fred Sundvik | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ | |||
#define KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ | |||
// Currently we are assuming that both the backlight and LCD are enabled | |||
// But it's entirely possible to write a custom visualizer that use only | |||
// one of them | |||
#ifndef LCD_BACKLIGHT_ENABLE | |||
#error This visualizer needs that LCD backlight is enabled | |||
#endif | |||
#ifndef LCD_ENABLE | |||
#error This visualizer needs that LCD is enabled | |||
#endif | |||
#include "visualizer.h" | |||
#include "visualizer_keyframes.h" | |||
#include "lcd_keyframes.h" | |||
#include "lcd_backlight_keyframes.h" | |||
#include "system/serial_link.h" | |||
#include "led.h" | |||
#include "default_animations.h" | |||
static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); | |||
static const uint32_t initial_color = LCD_COLOR(0, 0, 0); | |||
static bool initial_update = true; | |||
// Feel free to modify the animations below, or even add new ones if needed | |||
static keyframe_animation_t lcd_layer_display = { | |||
.num_frames = 1, | |||
.loop = false, | |||
.frame_lengths = {gfxMillisecondsToTicks(0)}, | |||
.frame_functions = {lcd_keyframe_display_layer_and_led_states} | |||
}; | |||
// The color animation animates the LCD color when you change layers | |||
static keyframe_animation_t color_animation = { | |||
.num_frames = 2, | |||
.loop = false, | |||
// Note that there's a 200 ms no-operation frame, | |||
// this prevents the color from changing when activating the layer | |||
// momentarily | |||
.frame_lengths = {gfxMillisecondsToTicks(1), gfxMillisecondsToTicks(5)}, | |||
.frame_functions = {keyframe_no_operation, lcd_backlight_keyframe_animate_color}, | |||
}; | |||
void initialize_user_visualizer(visualizer_state_t* state) { | |||
// The brightness will be dynamically adjustable in the future | |||
// But for now, change it here. | |||
lcd_backlight_brightness(130); | |||
state->current_lcd_color = initial_color; | |||
state->target_lcd_color = logo_background_color; | |||
initial_update = true; | |||
start_keyframe_animation(&default_startup_animation); | |||
} | |||
// This function should be implemented by the keymap visualizer | |||
// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing | |||
// that the simple_visualizer assumes that you are updating | |||
// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is | |||
// stopped. This can be done by either double buffering it or by using constant strings | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state); | |||
void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { | |||
// Add more tests, change the colors and layer texts here | |||
// Usually you want to check the high bits (higher layers first) | |||
// because that's the order layers are processed for keypresses | |||
// You can for check for example: | |||
// state->status.layer | |||
// state->status.default_layer | |||
// state->status.leds (see led.h for available statuses) | |||
uint32_t prev_color = state->target_lcd_color; | |||
const char* prev_layer_text = state->layer_text; | |||
get_visualizer_layer_and_color(state); | |||
if (initial_update || prev_color != state->target_lcd_color) { | |||
start_keyframe_animation(&color_animation); | |||
} | |||
if (initial_update || prev_layer_text != state->layer_text) { | |||
start_keyframe_animation(&lcd_layer_display); | |||
} | |||
// You can also stop existing animations, and start your custom ones here | |||
// remember that you should normally have only one animation for the LCD | |||
// and one for the background. But you can also combine them if you want. | |||
} | |||
void user_visualizer_suspend(visualizer_state_t* state) { | |||
state->layer_text = "Suspending..."; | |||
uint8_t hue = LCD_HUE(state->current_lcd_color); | |||
uint8_t sat = LCD_SAT(state->current_lcd_color); | |||
state->target_lcd_color = LCD_COLOR(hue, sat, 0); | |||
start_keyframe_animation(&default_suspend_animation); | |||
} | |||
void user_visualizer_resume(visualizer_state_t* state) { | |||
state->current_lcd_color = initial_color; | |||
state->target_lcd_color = logo_background_color; | |||
initial_update = true; | |||
start_keyframe_animation(&default_startup_animation); | |||
} | |||
#endif /* KEYBOARDS_ERGODOX_INFINITY_SIMPLE_VISUALIZER_H_ */ |
@ -1,79 +0,0 @@ | |||
/* | |||
Copyright 2017 Fred Sundvik | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "./simple_visualizer.h" | |||
#include "util.h" | |||
#include "layers.h" | |||
// This function should be implemented by the keymap visualizer | |||
// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing | |||
// that the simple_visualizer assumes that you are updating | |||
// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is | |||
// stopped. This can be done by either double buffering it or by using constant strings | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state) { | |||
switch(biton32(default_layer_state)) { | |||
case _QWERTY: | |||
state->layer_text = "QWERTY"; | |||
state->target_lcd_color = LCD_COLOR(0, 255, 128); | |||
break; | |||
case _WORKMAN: | |||
state->layer_text = "Workman"; | |||
state->target_lcd_color = LCD_COLOR(80, 255, 128); | |||
break; | |||
case _DVORAK: | |||
state->layer_text = "Dvorak"; | |||
state->target_lcd_color = LCD_COLOR(194, 255, 128); | |||
break; | |||
case _COLEMAK: | |||
state->layer_text = "Colemak"; | |||
state->target_lcd_color = LCD_COLOR(18, 255, 128); | |||
break; | |||
} | |||
switch(biton32(state->status.layer)) { | |||
case _LOWER: | |||
state->layer_text = "Lower"; | |||
state->target_lcd_color = LCD_COLOR(141, 255, 255); | |||
break; | |||
case _RAISE: | |||
state->layer_text = "Raise"; | |||
state->target_lcd_color = LCD_COLOR(18, 255, 255); | |||
break; | |||
case _ADJUST: | |||
state->layer_text = "Adjust"; | |||
state->target_lcd_color = LCD_COLOR(194, 255, 255); | |||
break; | |||
case _NUM: | |||
state->layer_text = "Numpad"; | |||
state->target_lcd_color = LCD_COLOR(80, 255, 255); | |||
break; | |||
case _MOUSE: | |||
state->layer_text = "Mouse"; | |||
state->target_lcd_color = LCD_COLOR(300, 255, 255); | |||
break; | |||
case _GAME: | |||
state->layer_text = "Game"; | |||
state->target_lcd_color = LCD_COLOR(300, 255, 255); | |||
break; | |||
case _QWERTY: case _WORKMAN: case _DVORAK: case _COLEMAK: | |||
break; | |||
default: | |||
state->layer_text = "NONE"; | |||
state->target_lcd_color = LCD_COLOR(0, 255, 255); | |||
break; | |||
} | |||
} |
@ -1,35 +0,0 @@ | |||
/* Copyright 2017 Fred Sundvik | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef VISUALIZER_H_ | |||
#define VISUALIZER_H_ | |||
#include "visualizer.h" | |||
#include "led.h" | |||
void ergodox_led_lower_on (void); | |||
void ergodox_led_raise_on (void); | |||
void ergodox_led_adjust_on (void); | |||
void ergodox_led_lower_off (void); | |||
void ergodox_led_raise_off (void); | |||
void ergodox_led_adjust_off (void); | |||
void ergodox_led_lower_set (uint8_t n); | |||
void ergodox_led_raise_set (uint8_t n); | |||
void ergodox_led_adjust_set (uint8_t n); | |||
#endif /* VISUALIZER_H_ */ |
@ -1,384 +0,0 @@ | |||
/* | |||
Copyright 2017 Fred Sundvik | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "visualizer.h" | |||
#include "gfx.h" | |||
#include "math.h" | |||
#include "default_animations.h" | |||
#include "led_backlight_keyframes.h" | |||
#define NUM_ROWS LED_HEIGHT | |||
#define NUM_COLS LED_WIDTH | |||
#define ONESIDESCAN 10 | |||
#define BOTHSIDESCAN 20 | |||
#define FULL_ON LUMA2COLOR(255) | |||
#define THREE_QUARTER LUMA2COLOR(200) | |||
#define HALF_ON LUMA2COLOR(150) | |||
#define ONE_QUARTER LUMA2COLOR(50) | |||
#define CROSSFADE_TIME 500 | |||
#define GRADIENT_TIME 3000 | |||
bool led_backlight_keyframe_one_period_sweep(keyframe_animation_t* animation, visualizer_state_t* state); | |||
bool led_backlight_keyframe_half_period_sweep_to_on(keyframe_animation_t* animation, visualizer_state_t* state); | |||
bool led_backlight_keyframe_half_period_sweep_to_off(keyframe_animation_t* animation, visualizer_state_t* state); | |||
keyframe_animation_t Fade_in_all_leds = { | |||
.num_frames = 1, | |||
.loop = false, | |||
.frame_lengths = { | |||
CROSSFADE_TIME, | |||
}, | |||
.frame_functions = { | |||
led_backlight_keyframe_fade_in_all, | |||
}, | |||
}; | |||
keyframe_animation_t decreasing_gradient = { | |||
.num_frames = 8, | |||
.loop = true, | |||
.frame_lengths = { | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) | |||
0, // mirror leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) | |||
0, // normal leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) | |||
0, // mirror leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) | |||
0, // normal leds | |||
}, | |||
.frame_functions = { | |||
led_backlight_keyframe_one_period_sweep, | |||
led_backlight_keyframe_mirror_orientation, | |||
keyframe_no_operation, | |||
keyframe_no_operation, | |||
keyframe_no_operation, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_one_period_sweep, | |||
led_backlight_keyframe_normal_orientation, | |||
}, | |||
}; | |||
static uint8_t off_on_off_gradient(float t, float index, float num) { | |||
const float two_pi = M_PI * 2.0f; | |||
float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; | |||
float x = t * two_pi + normalized_index-M_PI; | |||
if((1*M_PI) < x && x < (3*M_PI)) | |||
{ | |||
float v = 0.5 * (cosf(x) + 1.0f); | |||
return (uint8_t)(255.0f * v); | |||
} | |||
else | |||
{ | |||
return 0; | |||
} | |||
} | |||
static uint8_t off_on_gradient(float t, float index, float num) { | |||
const float two_pi = M_PI * 2.0f; | |||
float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; | |||
float x = t * two_pi + normalized_index-M_PI; | |||
float v; | |||
if((1*M_PI) < x && x < (2*M_PI)) | |||
{ | |||
v = 0.5 * (cosf(x) + 1.0f); | |||
} | |||
else if(x >= (2*M_PI)) | |||
{ | |||
v = 1; | |||
} | |||
else | |||
{ | |||
v = 0; | |||
} | |||
return (uint8_t)(255.0f * v); | |||
} | |||
static uint8_t on_off_gradient(float t, float index, float num) { | |||
const float two_pi = M_PI * 2.0f; | |||
float normalized_index = (1.0f - index / (num - 1.0f)) * two_pi; | |||
float x = t * two_pi + normalized_index-M_PI; | |||
float v; | |||
if((2*M_PI) < x && x < (3*M_PI)) | |||
{ | |||
v = 0.5 * (cosf(x) + 1.0f); | |||
} | |||
else if(x >= (3*M_PI)) | |||
{ | |||
v = 0; | |||
} | |||
else | |||
{ | |||
v = 1; | |||
} | |||
return (uint8_t)(255.0f * v); | |||
} | |||
bool led_backlight_keyframe_one_period_sweep(keyframe_animation_t* animation, visualizer_state_t* state) { | |||
(void)state; | |||
float frame_length = animation->frame_lengths[animation->current_frame]; | |||
float current_pos = frame_length - animation->time_left_in_frame; | |||
float t = current_pos / frame_length; | |||
for (int i=0; i< NUM_COLS; i++) { | |||
uint8_t color = off_on_off_gradient(t*2, i, NUM_COLS); | |||
gdispGDrawLine(LED_DISPLAY, i, 0, i, NUM_ROWS - 1, LUMA2COLOR(color)); | |||
} | |||
return true; | |||
} | |||
bool led_backlight_keyframe_half_period_sweep_to_on(keyframe_animation_t* animation, visualizer_state_t* state) { | |||
(void)state; | |||
float frame_length = animation->frame_lengths[animation->current_frame]; | |||
float current_pos = frame_length - animation->time_left_in_frame; | |||
float t = current_pos / frame_length; | |||
for (int i=0; i< NUM_COLS; i++) { | |||
uint8_t color = off_on_gradient(t*2, i, NUM_COLS); | |||
gdispGDrawLine(LED_DISPLAY, i, 0, i, NUM_ROWS - 1, LUMA2COLOR(color)); | |||
} | |||
return true; | |||
} | |||
bool led_backlight_keyframe_half_period_sweep_to_off(keyframe_animation_t* animation, visualizer_state_t* state) { | |||
(void)state; | |||
float frame_length = animation->frame_lengths[animation->current_frame]; | |||
float current_pos = frame_length - animation->time_left_in_frame; | |||
float t = current_pos / frame_length; | |||
for (int i=0; i< NUM_COLS; i++) { | |||
uint8_t color = on_off_gradient(t*2, i, NUM_COLS); | |||
gdispGDrawLine(LED_DISPLAY, i, 0, i, NUM_ROWS - 1, LUMA2COLOR(color)); | |||
} | |||
return true; | |||
} | |||
/* | |||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-------+ | |||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | phase | | |||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-------+ | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | | |||
| 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | | |||
| 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | | |||
| 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | | |||
| 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 4 | | |||
| 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 5 | | |||
| 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 6 | | |||
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 7 | | |||
| 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 8 | | |||
| 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 0 | 9 | | |||
| 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 0 | 10 | | |||
| 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 0 | 11 | | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 0 | 12 | | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 | 13 | | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 14 | | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 5 | 15 | | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 4 | 16 | | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 3 | 17 | | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 2 | 18 | | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 19 | | |||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 20 | | |||
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+-------+ | |||
*/ | |||
#ifdef MASTER_IS_ON_RIGHT /*right side*/ | |||
keyframe_animation_t sweep_on_sweep_off_left_and_right = { | |||
.num_frames = 12, | |||
.loop = true, | |||
.frame_lengths = { | |||
0, | |||
1, | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left on | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // right on | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left off | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // right off | |||
0, // mirror leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // right on | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left on | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // right off | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left off | |||
0, // normal leds | |||
}, | |||
.frame_functions = { | |||
led_backlight_keyframe_mirror_orientation, | |||
led_backlight_keyframe_fade_out_all, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_half_period_sweep_to_on, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_half_period_sweep_to_off, | |||
led_backlight_keyframe_normal_orientation, | |||
led_backlight_keyframe_half_period_sweep_to_on, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_half_period_sweep_to_off, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_mirror_orientation, | |||
}, | |||
}; | |||
keyframe_animation_t both_sides_fade_across = { | |||
.num_frames = 10, | |||
.loop = true, | |||
.frame_lengths = { | |||
0, | |||
1, | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) | |||
0, // mirror leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) | |||
0, // normal leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) | |||
0, // mirror leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) | |||
0, // normal leds | |||
}, | |||
.frame_functions = { | |||
led_backlight_keyframe_mirror_orientation, | |||
led_backlight_keyframe_fade_out_all, | |||
keyframe_no_operation, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_one_period_sweep, | |||
led_backlight_keyframe_normal_orientation, | |||
led_backlight_keyframe_one_period_sweep, | |||
led_backlight_keyframe_mirror_orientation, | |||
keyframe_no_operation, | |||
keyframe_no_operation, | |||
}, | |||
}; | |||
#else /*left side*/ | |||
keyframe_animation_t sweep_on_sweep_off_left_and_right = { | |||
.num_frames = 10, | |||
.loop = true, | |||
.frame_lengths = { | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left on | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // right on | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left off | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // right off | |||
0, // mirror leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // right on | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left on | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // right off | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left off | |||
0, // normal leds | |||
}, | |||
.frame_functions = { | |||
led_backlight_keyframe_half_period_sweep_to_on, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_half_period_sweep_to_off, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_mirror_orientation, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_half_period_sweep_to_on, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_half_period_sweep_to_off, | |||
led_backlight_keyframe_normal_orientation, | |||
}, | |||
}; | |||
keyframe_animation_t both_sides_fade_across = { | |||
.num_frames = 8, | |||
.loop = true, | |||
.frame_lengths = { | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) | |||
0, // mirror leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) | |||
0, // normal leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left to rigt (outside in) | |||
0, // mirror leds | |||
gfxMillisecondsToTicks(GRADIENT_TIME), // left_to_right (mirrored, so inside out) | |||
0, // normal leds | |||
}, | |||
.frame_functions = { | |||
led_backlight_keyframe_one_period_sweep, | |||
led_backlight_keyframe_mirror_orientation, | |||
keyframe_no_operation, | |||
keyframe_no_operation, | |||
keyframe_no_operation, | |||
keyframe_no_operation, | |||
led_backlight_keyframe_one_period_sweep, | |||
led_backlight_keyframe_normal_orientation, | |||
}, | |||
}; | |||
#endif | |||
#define RED 0 | |||
#define ORANGE 21 | |||
#define YELLOW 42 | |||
#define SPRING_GREEN 64 | |||
#define GREEN 85 | |||
#define TURQUOISE 107 | |||
#define CYAN 127 | |||
#define OCEAN 149 | |||
#define BLUE 170 | |||
#define VIOLET 192 | |||
#define MAGENTA 212 | |||
#define RASPBERRY 234 | |||
// This function should be implemented by the keymap visualizer | |||
// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing | |||
// that the simple_visualizer assumes that you are updating | |||
// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is | |||
// stopped. This can be done by either double buffering it or by using constant strings | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state) { | |||
uint8_t saturation = 255; | |||
/* if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { | |||
saturation = 255; | |||
} */ | |||
if (state->status.layer & 0x400) { | |||
state->target_lcd_color = LCD_COLOR(OCEAN, saturation, 0xFF); | |||
state->layer_text = "STENOGRAPHY"; | |||
} | |||
else if (state->status.layer & 0x200) { | |||
state->target_lcd_color = LCD_COLOR(GREEN, saturation, 0xFF); | |||
state->layer_text = "FUNCTION"; | |||
} | |||
else if (state->status.layer & 0x100) { | |||
state->target_lcd_color = LCD_COLOR(MAGENTA, saturation, 0xFF); | |||
state->layer_text = "Shortcuts Layer"; | |||
stop_keyframe_animation(&sweep_on_sweep_off_left_and_right); | |||
start_keyframe_animation(&led_test_animation); | |||
} | |||
else if (state->status.layer & 0x80) { | |||
state->target_lcd_color = LCD_COLOR(VIOLET, saturation, 0xFF); | |||
state->layer_text = "Plover"; | |||
} | |||
else if (state->status.layer & 0x40) { | |||
state->target_lcd_color = LCD_COLOR(RASPBERRY, saturation, 0xFF); | |||
state->layer_text = "Mirrored Symbols"; | |||
} | |||
else if (state->status.layer & 0x20) { | |||
state->target_lcd_color = LCD_COLOR(RED, saturation, 0xFF); | |||
state->layer_text = "Symbols"; | |||
} | |||
else if (state->status.layer & 0x8) { | |||
state->target_lcd_color = LCD_COLOR(OCEAN, saturation, 0xFF); | |||
state->layer_text = "Mirrored Dvorak"; | |||
} | |||
else if (state->status.layer & 0x4) { | |||
state->target_lcd_color = LCD_COLOR(BLUE, saturation, 0xFF); | |||
state->layer_text = "Dvorak"; | |||
stop_keyframe_animation(&led_test_animation); | |||
start_keyframe_animation(&sweep_on_sweep_off_left_and_right); | |||
} | |||
else if (state->status.layer & 0x2) { | |||
state->target_lcd_color = LCD_COLOR(ORANGE, saturation, 0xFF); | |||
state->layer_text = "Mirrored Qwerty"; | |||
} | |||
else { | |||
state->target_lcd_color = LCD_COLOR(YELLOW, saturation, 0xFF); | |||
state->layer_text = "Qwerty"; | |||
stop_keyframe_animation(&led_test_animation); | |||
start_keyframe_animation(&Fade_in_all_leds); | |||
} | |||
} |
@ -1,125 +0,0 @@ | |||
/* Copyright 2017 Fred Sundvik | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef VISUALIZER_H_ | |||
#define VISUALIZER_H_ | |||
// Currently we are assuming that both the backlight and LCD are enabled | |||
// But it's entirely possible to write a custom visualizer that use only | |||
// one of them | |||
#ifndef LCD_BACKLIGHT_ENABLE | |||
#error This visualizer needs that LCD backlight is enabled | |||
#endif | |||
#ifndef LCD_ENABLE | |||
#error This visualizer needs that LCD is enabled | |||
#endif | |||
#include "visualizer.h" | |||
#include "visualizer_keyframes.h" | |||
#include "lcd_keyframes.h" | |||
#include "lcd_backlight_keyframes.h" | |||
#include "system/serial_link.h" | |||
#include "led.h" | |||
#include "default_animations.h" | |||
static const uint32_t logo_background_color = LCD_COLOR(0x00, 0x00, 0xFF); | |||
static const uint32_t initial_color = LCD_COLOR(0, 0, 0); | |||
static bool initial_update = true; | |||
// Feel free to modify the animations below, or even add new ones if needed | |||
extern keyframe_animation_t KITT_Scanner_animation; | |||
static keyframe_animation_t lcd_layer_display = { | |||
.num_frames = 1, | |||
.loop = false, | |||
.frame_lengths = {gfxMillisecondsToTicks(0)}, | |||
.frame_functions = {lcd_keyframe_display_layer_and_led_states} | |||
}; | |||
// The color animation animates the LCD color when you change layers | |||
static keyframe_animation_t color_animation = { | |||
.num_frames = 2, | |||
.loop = false, | |||
// Note that there's a 200 ms no-operation frame, | |||
// this prevents the color from changing when activating the layer | |||
// momentarily | |||
.frame_lengths = {gfxMillisecondsToTicks(200), gfxMillisecondsToTicks(500)}, | |||
.frame_functions = {keyframe_no_operation, lcd_backlight_keyframe_animate_color}, | |||
}; | |||
void initialize_user_visualizer(visualizer_state_t* state) { | |||
// The brightness will be dynamically adjustable in the future | |||
// But for now, change it here. | |||
lcd_backlight_brightness(130); | |||
state->current_lcd_color = initial_color; | |||
state->target_lcd_color = logo_background_color; | |||
initial_update = true; | |||
start_keyframe_animation(&default_startup_animation); | |||
} | |||
// This function should be implemented by the keymap visualizer | |||
// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing | |||
// that the simple_visualizer assumes that you are updating | |||
// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is | |||
// stopped. This can be done by either double buffering it or by using constant strings | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state); | |||
void update_user_visualizer_state(visualizer_state_t* state, visualizer_keyboard_status_t* prev_status) { | |||
// Add more tests, change the colors and layer texts here | |||
// Usually you want to check the high bits (higher layers first) | |||
// because that's the order layers are processed for keypresses | |||
// You can for check for example: | |||
// state->status.layer | |||
// state->status.default_layer | |||
// state->status.leds (see led.h for available statuses) | |||
uint32_t prev_color = state->target_lcd_color; | |||
const char* prev_layer_text = state->layer_text; | |||
get_visualizer_layer_and_color(state); | |||
if (initial_update || prev_color != state->target_lcd_color) { | |||
start_keyframe_animation(&color_animation); | |||
} | |||
if (initial_update || prev_layer_text != state->layer_text) { | |||
start_keyframe_animation(&lcd_layer_display); | |||
} | |||
// You can also stop existing animations, and start your custom ones here | |||
// remember that you should normally have only one animation for the LCD | |||
// and one for the background. But you can also combine them if you want. | |||
} | |||
void user_visualizer_suspend(visualizer_state_t* state) { | |||
state->layer_text = "Suspending..."; | |||
uint8_t hue = LCD_HUE(state->current_lcd_color); | |||
uint8_t sat = LCD_SAT(state->current_lcd_color); | |||
state->target_lcd_color = LCD_COLOR(hue, sat, 0); | |||
start_keyframe_animation(&default_suspend_animation); | |||
} | |||
void user_visualizer_resume(visualizer_state_t* state) { | |||
state->current_lcd_color = initial_color; | |||
state->target_lcd_color = logo_background_color; | |||
initial_update = true; | |||
start_keyframe_animation(&default_startup_animation); | |||
} | |||
#endif /* VISUALIZER_H_ */ |
@ -1,5 +1,2 @@ | |||
LCD_BACKLIGHT_ENABLE = yes | |||
LCD_ENABLE = yes | |||
BACKLIGHT_ENABLE = yes | |||
KEY_LOCK_ENABLE = yes | |||
CONSOLE_ENABLE = no |
@ -1,39 +0,0 @@ | |||
/* | |||
Note: this is a modified copy of ../default/visualizer.c, originally licensed GPL. | |||
*/ | |||
#include "simple_visualizer.h" | |||
// This function should be implemented by the keymap visualizer | |||
// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing | |||
// that the simple_visualizer assumes that you are updating | |||
// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is | |||
// stopped. This can be done by either double buffering it or by using constant strings | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state) { | |||
uint8_t saturation = 60; | |||
if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { | |||
saturation = 255; | |||
} | |||
if (state->status.layer & 0x80) { | |||
state->target_lcd_color = LCD_COLOR(0, 255, 60); | |||
state->layer_text = "Game Arrow"; | |||
} else if (state->status.layer & 0x40) { | |||
state->target_lcd_color = LCD_COLOR(0, 255, 60); | |||
state->layer_text = "Game"; | |||
} else if (state->status.layer & 0x20) { | |||
state->target_lcd_color = LCD_COLOR(140, 100, 60); | |||
state->layer_text = "Movement"; | |||
} else if (state->status.layer & 0x10) { | |||
state->target_lcd_color = LCD_COLOR(0, saturation, 0xFF); | |||
state->layer_text = "Media"; | |||
} else if (state->status.layer & 0x8) { | |||
state->target_lcd_color = LCD_COLOR(168, saturation, 0xFF); | |||
state->layer_text = "Symbol"; | |||
} else if (state->status.layer & 0x2 || state->status.layer & 0x4) { | |||
state->target_lcd_color = LCD_COLOR(216, 90, 0xFF); | |||
state->layer_text = "Code"; | |||
} else { | |||
state->target_lcd_color = LCD_COLOR(84, saturation, 0xFF); | |||
state->layer_text = "Default"; | |||
} | |||
} |
@ -1,34 +0,0 @@ | |||
/* | |||
Note: this is a modified copy of ../default/visualizer.c, originally licensed GPL. | |||
*/ | |||
#include "simple_visualizer.h" | |||
// This function should be implemented by the keymap visualizer | |||
// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing | |||
// that the simple_visualizer assumes that you are updating | |||
// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is | |||
// stopped. This can be done by either double buffering it or by using constant strings | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state) { | |||
if (state->status.layer & 0x20) { | |||
state->target_lcd_color = LCD_COLOR(127, 0xFF, 0xFF); | |||
state->layer_text = "Mouse"; | |||
} else if (state->status.layer & 0x10) { | |||
state->target_lcd_color = LCD_COLOR(85, 0xFF, 0xFF); | |||
state->layer_text = "Symbol"; | |||
} else if (state->status.layer & 0x8) { | |||
state->target_lcd_color = LCD_COLOR(64, 0xFF, 0xFF); | |||
state->layer_text = "Brackets"; | |||
} else if (state->status.layer & 0x4) { | |||
state->target_lcd_color = LCD_COLOR(42, 0xFF, 0xFF); | |||
state->layer_text = "Diak"; | |||
} else if (state->status.layer & 0x2) { | |||
state->target_lcd_color = LCD_COLOR(21, 0xFF, 0xFF); | |||
state->layer_text = "Terminal"; | |||
} else { | |||
state->target_lcd_color = LCD_COLOR(192, 0xFF, 0xFF); | |||
state->layer_text = "Vim"; | |||
} | |||
} | |||
@ -1,49 +0,0 @@ | |||
/* | |||
Copyright 2017 Fred Sundvik | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
// Currently we are assuming that both the backlight and LCD are enabled | |||
// But it's entirely possible to write a custom visualizer that use only | |||
// one of them | |||
#ifndef LCD_BACKLIGHT_ENABLE | |||
#error This visualizer needs that LCD backlight is enabled | |||
#endif | |||
#ifndef LCD_ENABLE | |||
#error This visualizer needs that LCD is enabled | |||
#endif | |||
#include "simple_visualizer.h" | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state) { | |||
uint8_t saturation = 60; | |||
if (state->status.leds & (1u << USB_LED_CAPS_LOCK)) { | |||
saturation = 255; | |||
} | |||
if (state->status.layer & 0x4) { | |||
state->target_lcd_color = LCD_COLOR(0, saturation, 0xFF); | |||
state->layer_text = "Media"; | |||
} | |||
else if (state->status.layer & 0x2) { | |||
state->target_lcd_color = LCD_COLOR(168, saturation, 0xFF); | |||
state->layer_text = "Symbols"; | |||
} | |||
else { | |||
state->target_lcd_color = LCD_COLOR(84, saturation, 0xFF); | |||
state->layer_text = "Base"; | |||
} | |||
} |
@ -1,62 +0,0 @@ | |||
/* | |||
Copyright 2017 Fred Sundvik | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "simple_visualizer.h" | |||
// This function should be implemented by the keymap visualizer | |||
// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing | |||
// that the simple_visualizer assumes that you are updating | |||
// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is | |||
// stopped. This can be done by either double buffering it or by using constant strings | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state) { | |||
if (state->status.layer & 0x20) { | |||
//GREEN | |||
state->target_lcd_color = LCD_COLOR(85, 255, 128); | |||
state->layer_text = "Gaming"; | |||
} | |||
else if (state->status.layer & 0x10) { | |||
//ORANGE | |||
state->target_lcd_color = LCD_COLOR(28, 255, 230); | |||
state->layer_text = "Numpad & Mouse"; | |||
} | |||
else if (state->status.layer & 0x8) { | |||
//YELLOW | |||
state->target_lcd_color = LCD_COLOR(38, 255, 230); | |||
state->layer_text = "Symbols"; | |||
} | |||
else if (state->status.layer & 0x4) { | |||
//RED | |||
state->target_lcd_color = LCD_COLOR(0, 255, 95); | |||
if (state->status.layer & 0x2){ | |||
state->layer_text = "Qwerty - Fn"; | |||
}else{ | |||
state->layer_text = "Colemak - Fn"; | |||
} | |||
} | |||
else if (state->status.layer & 0x2) { | |||
//BLUE | |||
state->target_lcd_color = LCD_COLOR(149, 255, 192); | |||
state->layer_text = "Qwerty"; | |||
} | |||
else { | |||
//PURPLE | |||
state->target_lcd_color = LCD_COLOR(200, 255, 192); | |||
state->layer_text = "Colemak"; | |||
} | |||
} | |||
@ -1,77 +0,0 @@ | |||
/* | |||
Copyright 2017 Fred Sundvik | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "./simple_visualizer.h" | |||
#include "util.h" | |||
#include "drashna.h" | |||
#include "rgblight_list.h" | |||
#define LCD_COLOR_wrapper(...) LCD_COLOR(__VA_ARGS__) | |||
// This function should be implemented by the keymap visualizer | |||
// Don't change anything else than state->target_lcd_color and state->layer_text as that's the only thing | |||
// that the simple_visualizer assumes that you are updating | |||
// Also make sure that the buffer passed to state->layer_text remains valid until the previous animation is | |||
// stopped. This can be done by either double buffering it or by using constant strings | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state) { | |||
switch(get_highest_layer(state->status.layer|default_layer_state)) { | |||
case _LOWER: | |||
state->layer_text = "Lower"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_GREEN); | |||
break; | |||
case _RAISE: | |||
state->layer_text = "Raise"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_YELLOW); | |||
break; | |||
case _ADJUST: | |||
state->layer_text = "Adjust"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_RED); | |||
break; | |||
case _MACROS: | |||
state->layer_text = "Macros"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_ORANGE); | |||
break; | |||
case _MEDIA: | |||
state->layer_text = "Media"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_CHARTREUSE); | |||
break; | |||
case _GAMEPAD: | |||
state->layer_text = "Game"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_ORANGE); | |||
break; | |||
case _QWERTY: | |||
state->layer_text = "QWERTY"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_CYAN); | |||
break; | |||
case _WORKMAN: | |||
state->layer_text = "Workman"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_GOLDENROD); | |||
break; | |||
case _DVORAK: | |||
state->layer_text = "Dvorak"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_SPRINGGREEN); | |||
break; | |||
case _COLEMAK: | |||
state->layer_text = "Colemak"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_MAGENTA); | |||
break; break; | |||
default: | |||
state->layer_text = "NONE"; | |||
state->target_lcd_color = LCD_COLOR_wrapper(HSV_RED); | |||
break; | |||
} | |||
} |
@ -1,47 +0,0 @@ | |||
#include "layers.h" | |||
#include "simple_visualizer.h" | |||
#include "util.h" | |||
static void get_visualizer_layer_and_color(visualizer_state_t *state) { | |||
uint8_t layer = biton32(state->status.layer); | |||
// Go from highest to lowest layer to get the right text/color combination. | |||
switch (layer) { | |||
// #AEB2F4 / hsv(65.71%, 28.69%, 95.69%) | |||
case FKEYS: | |||
// #F4AEDC / hsv(89.05%, 28.69%, 95.69%) | |||
state->layer_text = "FUNCTION KEYS"; | |||
state->target_lcd_color = LCD_COLOR(228, 73, 245); | |||
break; | |||
case US_1: | |||
// #F4B993 / hsv(6.53%, 39.75%, 95.69%) | |||
state->layer_text = "QWERTY"; | |||
state->target_lcd_color = LCD_COLOR(17, 102, 245); | |||
break; | |||
case NEO_6: | |||
// #F4E393 / hsv(13.75%, 39.75%, 95.69%) | |||
state->layer_text = "NEO: 6"; | |||
state->target_lcd_color = LCD_COLOR(35, 102, 245); | |||
break; | |||
case NEO_5: | |||
// #C6F493 / hsv(24.57%, 39.75%, 95.69%) | |||
state->layer_text = "NEO: 5"; | |||
state->target_lcd_color = LCD_COLOR(63, 102, 245); | |||
break; | |||
case NEO_4: | |||
// #8EEBC9 / hsv(43.91%, 39.57%, 92.16%) | |||
state->layer_text = "NEO: 4"; | |||
state->target_lcd_color = LCD_COLOR(112, 101, 189); | |||
break; | |||
case NEO_3: | |||
// #93D2F4 / hsv(55.84%, 39.75%, 95.69%) | |||
state->layer_text = "NEO: 3"; | |||
state->target_lcd_color = LCD_COLOR(143, 102, 245); | |||
break; | |||
default: | |||
// #EEEEEE / hsv(0%, 0%, 93%) | |||
state->layer_text = "NEO: 1"; | |||
state->target_lcd_color = LCD_COLOR(0, 0, 255); | |||
break; | |||
} | |||
} |
@ -1,21 +0,0 @@ | |||
/* Copyright 2020 Joseph Wasson | |||
* | |||
* This program is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation, either version 2 of the License, or | |||
* (at your option) any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU General Public License | |||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#include "talljoe.h" | |||
static void get_visualizer_layer_and_color(visualizer_state_t* state) { | |||
state->status_text = layer_names[biton32(state->status.layer)]; | |||
} |