mirror of
https://github.com/Keychron/qmk_firmware.git
synced 2024-12-28 20:18:49 +06:00
7f413e9f01
Co-authored-by: Drashna Jaelre <drashna@live.com> Co-authored-by: Less/Rikki <86894501+lesshonor@users.noreply.github.com> Co-authored-by: Ryan <fauxpark@gmail.com>
243 lines
9.1 KiB
C
243 lines
9.1 KiB
C
/* Copyright 2023 ziptyze
|
|
*
|
|
* 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 "quantum.h"
|
|
#include <ctype.h>
|
|
#include <stdio.h>
|
|
|
|
#if defined(RGB_MATRIX_EFFECT)
|
|
# undef RGB_MATRIX_EFFECT
|
|
#endif // defined(RGB_MATRIX_EFFECT)
|
|
|
|
#define RGB_MATRIX_EFFECT(x) RGB_MATRIX_EFFECT_##x,
|
|
enum {
|
|
RGB_MATRIX_EFFECT_NONE,
|
|
#include "rgb_matrix_effects.inc"
|
|
#undef RGB_MATRIX_EFFECT
|
|
#ifdef RGB_MATRIX_CUSTOM_KB
|
|
# include "rgb_matrix_kb.inc"
|
|
#endif
|
|
#ifdef RGB_MATRIX_CUSTOM_USER
|
|
# include "rgb_matrix_user.inc"
|
|
#endif
|
|
};
|
|
|
|
#define RGB_MATRIX_EFFECT(x) \
|
|
case RGB_MATRIX_EFFECT_##x: \
|
|
return #x;
|
|
const char* rgb_matrix_name(uint8_t effect) {
|
|
switch (effect) {
|
|
case RGB_MATRIX_EFFECT_NONE:
|
|
return "NONE";
|
|
#include "rgb_matrix_effects.inc"
|
|
#undef RGB_MATRIX_EFFECT
|
|
#ifdef RGB_MATRIX_CUSTOM_KB
|
|
# include "rgb_matrix_kb.inc"
|
|
#endif
|
|
#ifdef RGB_MATRIX_CUSTOM_USER
|
|
# include "rgb_matrix_user.inc"
|
|
#endif
|
|
default:
|
|
return "UNKNOWN";
|
|
}
|
|
}
|
|
|
|
#ifdef OLED_ENABLE
|
|
|
|
static uint32_t oled_logo_timer = 0;
|
|
static bool clear_logo = true;
|
|
static const char PROGMEM my_logo[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x1f, 0xff, 0xff, 0xff, 0x1f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
|
|
0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
|
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0,
|
|
0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x0f, 0x0f, 0x0f, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xfb,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xff,
|
|
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
};
|
|
|
|
#endif
|
|
|
|
#ifdef OLED_ENABLE
|
|
|
|
void init_timer(void){
|
|
oled_logo_timer = timer_read32();
|
|
};
|
|
|
|
void user_oled_magic(void) {
|
|
// Host Keyboard Layer Status
|
|
oled_write_P(PSTR("Layer: "), false);
|
|
|
|
switch (get_highest_layer(layer_state)) {
|
|
case 0:
|
|
oled_write_P(PSTR("One\n"), false);
|
|
break;
|
|
case 1:
|
|
oled_write_P(PSTR("Two\n"), false);
|
|
break;
|
|
case 2:
|
|
oled_write_P(PSTR("Three\n"), false);
|
|
break;
|
|
case 3:
|
|
oled_write_P(PSTR("Four\n"), false);
|
|
break;
|
|
case 4:
|
|
oled_write_P(PSTR("Five\n"), false);
|
|
break;
|
|
case 5:
|
|
oled_write_P(PSTR("Six\n"), false);
|
|
break;
|
|
case 6:
|
|
oled_write_P(PSTR("Seven\n"), false);
|
|
break;
|
|
case 7:
|
|
oled_write_P(PSTR("Eight\n"), false);
|
|
break;
|
|
case 8:
|
|
oled_write_P(PSTR("Nine\n"), false);
|
|
break;
|
|
case 9:
|
|
oled_write_P(PSTR("Ten\n"), false);
|
|
break;
|
|
default:
|
|
// Or use the write_ln shortcut over adding '\n' to the end of your string
|
|
oled_write_ln_P(PSTR("Undefined"), false);
|
|
}
|
|
|
|
// Host Keyboard LED Status
|
|
led_t led_state = host_keyboard_led_state();
|
|
oled_write_P(led_state.caps_lock ? PSTR("Cap(x) ") : PSTR("Cap( ) "), false);
|
|
oled_write_P(led_state.num_lock ? PSTR("Num(x) ") : PSTR("Num( ) "), false);
|
|
oled_write_P(led_state.scroll_lock ? PSTR("Scrl(x)") : PSTR("Scrl( )"), false);
|
|
|
|
char *mode_name = strdup(rgb_matrix_name(rgb_matrix_get_mode()));
|
|
if (mode_name != NULL) {
|
|
int len = strlen(mode_name);
|
|
bool capitalize_next = true;
|
|
for (int i = 0; i < len; i++) {
|
|
if (i == 21 && mode_name[i] == '_') {
|
|
continue; // Skip the underscore if it's the 22nd character
|
|
}
|
|
if (mode_name[i] == '_') {
|
|
mode_name[i] = ' ';
|
|
capitalize_next = true;
|
|
} else if (capitalize_next) {
|
|
mode_name[i] = mode_name[i] >= 'a' && mode_name[i] <= 'z' ? mode_name[i] - 'a' + 'A' : mode_name[i];
|
|
capitalize_next = false;
|
|
} else {
|
|
mode_name[i] = mode_name[i] >= 'A' && mode_name[i] <= 'Z' ? mode_name[i] - 'A' + 'a' : mode_name[i];
|
|
}
|
|
}
|
|
|
|
// Add line break and spaces if necessary
|
|
if (len < 19) {
|
|
strcat(mode_name, "\n");
|
|
for (int i = 0; i < 21; i++) {
|
|
strcat(mode_name, " ");
|
|
}
|
|
} else {
|
|
// Find the most recent ' ' before the 21st character and replace it with a line break
|
|
int break_pos = -1;
|
|
for (int i = 18; i >= 0; i--) {
|
|
if (mode_name[i] == ' ') {
|
|
break_pos = i;
|
|
break;
|
|
}
|
|
}
|
|
if (break_pos >= 0) {
|
|
mode_name[break_pos] = '\n';
|
|
for (int i = 0; i < (21 - (len - break_pos - 1)); i++) {
|
|
strcat(mode_name, " ");
|
|
}
|
|
} else {
|
|
// No '_' found, just add spaces
|
|
for (int i = 0; i < (21 - len); i++) {
|
|
strcat(mode_name, " ");
|
|
}
|
|
}
|
|
}
|
|
|
|
oled_write_P(PSTR(mode_name), false);
|
|
free(mode_name);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
void render_logo(void) {
|
|
oled_write_raw_P(my_logo, sizeof(my_logo));
|
|
}
|
|
|
|
void clear_screen(void) {
|
|
if (clear_logo){
|
|
for (uint8_t i = 0; i < OLED_DISPLAY_HEIGHT; ++i) {
|
|
for (uint8_t j = 0; j < OLED_DISPLAY_WIDTH; ++j) {
|
|
oled_write_raw_byte(0x0, i*OLED_DISPLAY_WIDTH + j);
|
|
}
|
|
}
|
|
clear_logo = false;
|
|
}
|
|
}
|
|
|
|
oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
|
|
return OLED_ROTATION_180;
|
|
}
|
|
|
|
void keyboard_post_init_kb(void) {
|
|
init_timer();
|
|
|
|
keyboard_post_init_user();
|
|
}
|
|
|
|
# define SHOW_LOGO 5000
|
|
bool oled_task_kb(void) {
|
|
if (!oled_task_user()) { return false; }
|
|
if ((timer_elapsed32(oled_logo_timer) < SHOW_LOGO)){
|
|
render_logo();
|
|
}else{
|
|
clear_screen();
|
|
user_oled_magic();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
#endif
|