]> git.donarmstrong.com Git - qmk_firmware.git/blob - users/drashna/rgb_stuff.c
Update KBD67 readme so that it mentions the KBD65 PCB (#5143)
[qmk_firmware.git] / users / drashna / rgb_stuff.c
1 #include "drashna.h"
2 #include "rgb_stuff.h"
3 #include "eeprom.h"
4
5 #if defined(RGBLIGHT_ENABLE)
6 extern rgblight_config_t rgblight_config;
7 bool has_initialized;
8 #elif defined(RGB_MATRIX_ENABLE)
9 extern rgb_config_t rgb_matrix_config;
10 #endif
11
12 #ifdef RGBLIGHT_ENABLE
13 void rgblight_sethsv_default_helper(uint8_t index) {
14   rgblight_sethsv_at(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, index);
15 }
16 #endif // RGBLIGHT_ENABLE
17
18 #ifdef INDICATOR_LIGHTS
19 void set_rgb_indicators(uint8_t this_mod, uint8_t this_led, uint8_t this_osm) {
20   if (userspace_config.rgb_layer_change && biton32(layer_state) == 0) {
21     if ( (this_mod | this_osm) & MOD_MASK_SHIFT || this_led & (1<<USB_LED_CAPS_LOCK) ) {
22       #ifdef SHFT_LED1
23         rgblight_sethsv_at(120, 255, 255, SHFT_LED1);
24       #endif // SHFT_LED1
25       #ifdef SHFT_LED2
26         rgblight_sethsv_at(120, 255, 255, SHFT_LED2);
27       #endif // SHFT_LED2
28     } else {
29       #ifdef SHFT_LED1
30         rgblight_sethsv_default_helper(SHFT_LED1);
31       #endif // SHFT_LED1
32       #ifdef SHFT_LED2
33         rgblight_sethsv_default_helper(SHFT_LED2);
34       #endif // SHFT_LED2
35     }
36     if ( (this_mod | this_osm) & MOD_MASK_CTRL) {
37       #ifdef CTRL_LED1
38         rgblight_sethsv_at(0, 255, 255, CTRL_LED1);
39       #endif // CTRL_LED1
40       #ifdef CTRL_LED2
41         rgblight_sethsv_at(0, 255, 255, CTRL_LED2);
42       #endif // CTRL_LED2
43     } else {
44       #ifdef CTRL_LED1
45         rgblight_sethsv_default_helper(CTRL_LED1);
46       #endif // CTRL_LED1
47       #ifdef CTRL_LED2
48         rgblight_sethsv_default_helper(CTRL_LED2);
49       #endif // CTRL_LED2
50     }
51     if ( (this_mod | this_osm) & MOD_MASK_GUI) {
52       #ifdef GUI_LED1
53         rgblight_sethsv_at(51, 255, 255, GUI_LED1);
54       #endif // GUI_LED1
55       #ifdef GUI_LED2
56         rgblight_sethsv_at(51, 255, 255, GUI_LED2);
57       #endif // GUI_LED2
58     } else {
59       #ifdef GUI_LED1
60         rgblight_sethsv_default_helper(GUI_LED1);
61       #endif // GUI_LED1
62       #ifdef GUI_LED2
63         rgblight_sethsv_default_helper(GUI_LED2);
64       #endif // GUI_LED2
65     }
66     if ( (this_mod | this_osm) & MOD_MASK_ALT) {
67       #ifdef ALT_LED1
68         rgblight_sethsv_at(240, 255, 255, ALT_LED1);
69       #endif // ALT_LED1
70       #ifdef GUI_LED2
71         rgblight_sethsv_at(240, 255, 255, ALT_LED2);
72       #endif // GUI_LED2
73     } else {
74       #ifdef GUI_LED1
75         rgblight_sethsv_default_helper(ALT_LED1);
76       #endif // GUI_LED1
77       #ifdef GUI_LED2
78         rgblight_sethsv_default_helper(ALT_LED2);
79       #endif // GUI_LED2
80     }
81   }
82 }
83
84 void matrix_scan_indicator(void) {
85   if (has_initialized) {
86     set_rgb_indicators(get_mods(), host_keyboard_leds(), get_oneshot_mods());
87   }
88 }
89 #endif //INDICATOR_LIGHTS
90
91 #ifdef RGBLIGHT_TWINKLE
92 static rgblight_fadeout lights[RGBLED_NUM];
93
94 __attribute__ ((weak))
95 bool rgblight_twinkle_is_led_used_keymap(uint8_t index) { return false; }
96
97 bool rgblight_twinkle_is_led_used(uint8_t index) {
98   switch (index) {
99 #ifdef INDICATOR_LIGHTS
100 #ifdef SHFT_LED1
101     case SHFT_LED1:
102       return true;
103 #endif //SHFT_LED1
104 #ifdef SHFT_LED2
105     case SHFT_LED2:
106       return true;
107 #endif //SHFT_LED2
108 #ifdef CTRL_LED1
109     case CTRL_LED1:
110       return true;
111 #endif //CTRL_LED1
112 #ifdef CTRL_LED2
113     case CTRL_LED2:
114       return true;
115 #endif //CTRL_LED2
116 #ifdef GUI_LED1
117     case GUI_LED1:
118       return true;
119 #endif //GUI_LED1
120 #ifdef GUI_LED2
121     case GUI_LED2:
122       return true;
123 #endif //GUI_LED2
124 #ifdef ALT_LED1
125     case ALT_LED1:
126       return true;
127 #endif //ALT_LED1
128 #ifdef ALT_LED2
129     case ALT_LED2:
130       return true;
131 #endif //ALT_LED2
132 #endif //INDICATOR_LIGHTS
133     default:
134     return rgblight_twinkle_is_led_used_keymap(index);
135   }
136 }
137
138 void scan_rgblight_fadeout(void) { // Don't effing change this function .... rgblight_sethsv is supppppper intensive
139   bool litup = false;
140   for (uint8_t light_index = 0 ; light_index < RGBLED_NUM ; ++light_index ) {
141     if (lights[light_index].enabled && timer_elapsed(lights[light_index].timer) > 10) {
142       rgblight_fadeout *light = &lights[light_index];
143       litup = true;
144
145       if (light->life) {
146         light->life -= 1;
147         if (biton32(layer_state) == 0) {
148           sethsv(light->hue + rand() % 0xF, 255, light->life, (LED_TYPE *)&led[light_index]);
149         }
150         light->timer = timer_read();
151       }
152       else {
153         if (light->enabled && biton32(layer_state) == 0) { rgblight_sethsv_default_helper(light_index); }
154         litup = light->enabled = false;
155       }
156     }
157   }
158   if (litup && biton32(layer_state) == 0) {
159     rgblight_set();
160   }
161 }
162
163 void start_rgb_light(void) {
164
165     uint8_t indices[RGBLED_NUM];
166     uint8_t indices_count = 0;
167     uint8_t min_life = 0xFF;
168     uint8_t min_life_index = -1;
169     for (uint8_t index = 0 ; index < RGBLED_NUM ; ++index ) {
170       if (rgblight_twinkle_is_led_used(index)) { continue; }
171       if (lights[index].enabled) {
172         if (min_life_index == -1 ||
173           lights[index].life < min_life)
174         {
175           min_life = lights[index].life;
176           min_life_index = index;
177         }
178         continue;
179       }
180
181       indices[indices_count] = index;
182       ++indices_count;
183     }
184
185     uint8_t light_index;
186     if (!indices_count) {
187         light_index = min_life_index;
188     }
189     else {
190       light_index = indices[rand() % indices_count];
191     }
192
193     rgblight_fadeout *light = &lights[light_index];
194     light->enabled = true;
195     light->timer = timer_read();
196     light->life = 0xC0 + rand() % 0x40;
197
198     light->hue = rgblight_config.hue + (rand() % 0xB4) - 0x54;
199
200     rgblight_sethsv_at(light->hue, 255, light->life, light_index);
201 }
202 #endif
203
204
205 bool process_record_user_rgb(uint16_t keycode, keyrecord_t *record) {
206   if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX)) {
207     keycode = keycode & 0xFF;
208   }
209   switch (keycode) {
210 #ifdef RGBLIGHT_TWINKLE
211     case KC_A ... KC_SLASH:
212     case KC_F1 ... KC_F12:
213     case KC_INSERT ... KC_UP:
214     case KC_KP_SLASH ... KC_KP_DOT:
215     case KC_F13 ... KC_F24:
216     case KC_AUDIO_MUTE ... KC_MEDIA_REWIND:
217       if (record->event.pressed) { start_rgb_light(); }
218       return true; break;
219 #endif // RGBLIGHT_TWINKLE
220   case KC_RGB_T:  // This allows me to use underglow as layer indication, or as normal
221 #if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE)
222     if (record->event.pressed) {
223       userspace_config.rgb_layer_change ^= 1;
224       xprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change);
225       eeconfig_update_user(userspace_config.raw);
226       if (userspace_config.rgb_layer_change) {
227         layer_state_set(layer_state); // This is needed to immediately set the layer color (looks better)
228       }
229     }
230 #endif // RGBLIGHT_ENABLE
231     return false; break;
232 #ifdef RGBLIGHT_ENABLE
233   case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // quantum_keycodes.h L400 for definitions
234     if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled
235       if (userspace_config.rgb_layer_change) {
236         userspace_config.rgb_layer_change = false;
237         xprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change);
238         eeconfig_update_user(userspace_config.raw);
239       }
240     }
241     return true; break;
242 #endif // RGBLIGHT_ENABLE
243   }
244     return true;
245 }
246
247
248
249 void keyboard_post_init_rgb(void) {
250 #ifdef RGBLIGHT_ENABLE
251         rgblight_enable_noeeprom();
252         layer_state_set_user(layer_state);
253   uint16_t old_hue = rgblight_config.hue;
254         rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT);
255         for (uint16_t i = 360; i > 0; i--) {
256                 rgblight_sethsv_noeeprom( ( i + old_hue) % 360, 255, 255);
257     wait_ms(10);
258         }
259         layer_state_set_user(layer_state);
260 #endif
261 }
262
263 void matrix_scan_rgb(void) {
264 #ifdef RGBLIGHT_TWINKLE
265   scan_rgblight_fadeout();
266 #endif // RGBLIGHT_ENABLE
267
268 #ifdef INDICATOR_LIGHTS
269   matrix_scan_indicator();
270 #endif
271
272 }
273
274
275 uint32_t layer_state_set_rgb(uint32_t state) {
276 #ifdef RGBLIGHT_ENABLE
277   if (userspace_config.rgb_layer_change) {
278     switch (biton32(state)) {
279     case _MACROS:
280       rgblight_sethsv_noeeprom_orange();
281       userspace_config.is_overwatch ? rgblight_effect_snake(RGBLIGHT_MODE_SNAKE + 2) : rgblight_effect_snake(RGBLIGHT_MODE_SNAKE + 3);
282       break;
283     case _MEDIA:
284       rgblight_sethsv_noeeprom_chartreuse();
285       rgblight_mode_noeeprom(RGBLIGHT_MODE_KNIGHT + 1);
286       break;
287     case _GAMEPAD:
288       rgblight_sethsv_noeeprom_orange();
289       rgblight_mode_noeeprom(RGBLIGHT_MODE_SNAKE + 2);
290       break;
291     case _DIABLO:
292       rgblight_sethsv_noeeprom_red();
293       rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3);
294       break;
295     case _RAISE:
296       rgblight_sethsv_noeeprom_yellow();
297       rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3);
298       break;
299     case _LOWER:
300       rgblight_sethsv_noeeprom_green();
301       rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3);
302       break;
303     case _ADJUST:
304       rgblight_sethsv_noeeprom_red();
305       rgblight_mode_noeeprom(RGBLIGHT_MODE_KNIGHT + 2);
306       break;
307     default: //  for any other layers, or the default layer
308       switch (biton32(default_layer_state)) {
309         case _COLEMAK:
310           rgblight_sethsv_noeeprom_magenta(); break;
311         case _DVORAK:
312           rgblight_sethsv_noeeprom_springgreen(); break;
313         case _WORKMAN:
314           rgblight_sethsv_noeeprom_goldenrod(); break;
315         case _NORMAN:
316           rgblight_sethsv_noeeprom_coral(); break;
317         case _MALTRON:
318           rgblight_sethsv_noeeprom_yellow(); break;
319         case _EUCALYN:
320           rgblight_sethsv_noeeprom_pink(); break;
321         case _CARPLAX:
322           rgblight_sethsv_noeeprom_blue(); break;
323         default:
324           rgblight_sethsv_noeeprom_cyan(); break;
325       }
326       biton32(state) == _MODS ? rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING) : rgblight_mode_noeeprom(RGBLIGHT_MODE_STATIC_LIGHT); // if _MODS layer is on, then breath to denote it
327       break;
328     }
329 //    layer_state_set_indicator(); // Runs every scan, so need to call this here .... since I can't get it working "right" anyhow
330   }
331 #endif // RGBLIGHT_ENABLE
332
333   return state;
334 }
335
336 #if 0
337 uint32_t default_layer_state_set_rgb(uint32_t state) {
338 #ifdef RGBLIGHT_ENABLE
339   if (userspace_config.rgb_layer_change) {
340     rgblight_config_t temp_rgblight_config = rgblight_config;
341     switch (biton32(state)) {
342       case _COLEMAK:
343         temp_rgblight_config.hue = 300;
344         temp_rgblight_config.val = 255;
345         temp_rgblight_config.sat = 255;
346         temp_rgblight_config.mode = 1;
347         break;
348       case _DVORAK:
349         temp_rgblight_config.hue = 150;
350         temp_rgblight_config.val = 255;
351         temp_rgblight_config.sat = 255;
352         temp_rgblight_config.mode = 1;
353       case _WORKMAN:
354         temp_rgblight_config.hue = 43;
355         temp_rgblight_config.val = 218;
356         temp_rgblight_config.sat = 218;
357         temp_rgblight_config.mode = 1;
358       default:
359         temp_rgblight_config.hue = 180;
360         temp_rgblight_config.val = 255;
361         temp_rgblight_config.sat = 255;
362         temp_rgblight_config.mode = 1;
363     }
364     if (temp_rgblight_config.raw != eeconfig_read_rgblight()) {
365       xprintf("rgblight set default layer hsv [EEPROM]: %u,%u,%u,%u\n", temp_rgblight_config.hue, temp_rgblight_config.sat, temp_rgblight_config.val, temp_rgblight_config.mode);
366       eeconfig_update_rgblight(temp_rgblight_config.raw);
367     }
368   }
369 #endif // RGBLIGHT_ENABLE
370   return state;
371 }
372 #endif