1
0
Fork 0

[Keymap] Drashna Keymap updates for 0.21.0 (#21073)

This commit is contained in:
Drashna Jael're 2023-05-31 11:44:06 -07:00 committed by GitHub
parent 1411c79aef
commit 3a3e5abac9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
71 changed files with 1609 additions and 2215 deletions

View file

@ -28,7 +28,7 @@ void bootmagic_lite(void) {
if (!is_keyboard_left()) {
row = BOOTMAGIC_LITE_ROW_RIGHT;
col = BOOTMAGIC_LITE_COLUMN_RIGHT;
#if defined(BOOTMAGIC_LITE_EEPROM_ROW) && defined(BOOTMAGIC_LITE_EEPROM_COLUMN) && defined(BOOTMAGIC_LITE_EEPROM_ROW_RIGHT) && defined(BOOTMAGIC_LITE_EEPROM_COLUMN_RIGHT)
# if defined(BOOTMAGIC_LITE_EEPROM_ROW) && defined(BOOTMAGIC_LITE_EEPROM_COLUMN) && defined(BOOTMAGIC_LITE_EEPROM_ROW_RIGHT) && defined(BOOTMAGIC_LITE_EEPROM_COLUMN_RIGHT)
row_e = BOOTMAGIC_LITE_EEPROM_ROW_RIGHT;
col_e = BOOTMAGIC_LITE_EEPROM_COLUMN_RIGHT;
# endif

View file

@ -3,6 +3,9 @@
#include "drashna.h"
#ifdef CUSTOM_DYNAMIC_MACROS_ENABLE
# include "keyrecords/dynamic_macros.h"
#endif
#ifdef I2C_SCANNER_ENABLE
void housekeeping_task_i2c_scanner(void);
void keyboard_post_init_i2c(void);
@ -10,7 +13,10 @@ void keyboard_post_init_i2c(void);
__attribute__((weak)) void keyboard_pre_init_keymap(void) {}
void keyboard_pre_init_user(void) {
userspace_config.raw = eeconfig_read_user();
eeconfig_read_user_config(&userspace_config.raw);
if (!userspace_config.check) {
eeconfig_init_user();
}
keyboard_pre_init_keymap();
}
// Add reconfigurable functions here, for keymap customization
@ -24,58 +30,8 @@ void keyboard_pre_init_user(void) {
void keyboard_post_init_qp(void);
#endif
#ifdef OS_DETECTION_ENABLE
os_variant_t os_type;
uint32_t startup_exec(uint32_t trigger_time, void *cb_arg) {
/* do something */
if (is_keyboard_master()) {
os_type = detected_host_os();
if (os_type) {
bool is_mac = (os_type == OS_MACOS) || (os_type == OS_IOS);
keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = is_mac;
# ifdef UNICODE_COMMON_ENABLE
uint8_t mode = is_mac ? UNICODE_MODE_MACOS : UNICODE_MODE_WINCOMPOSE;
if (mode != get_unicode_input_mode()) {
set_unicode_input_mode(mode);
}
# endif
switch (os_type) {
case OS_UNSURE:
xprintf("unknown OS Detected\n");
break;
case OS_LINUX:
xprintf("Linux Detected\n");
break;
case OS_WINDOWS:
xprintf("Windows Detected\n");
break;
# if 0
case OS_WINDOWS_UNSURE:
xprintf("Windows? Detected\n");
break;
# endif
case OS_MACOS:
xprintf("MacOS Detected\n");
break;
case OS_IOS:
xprintf("iOS Detected\n");
break;
# if 0
case OS_PS5:
xprintf("PlayStation 5 Detected\n");
break;
case OS_HANDHELD:
xprintf("Nintend Switch/Quest 2 Detected\n");
break;
# endif
}
}
}
return os_type ? 0 : 500;
}
#if defined(OS_DETECTION_ENABLE) && defined(DEFERRED_EXEC_ENABLE)
uint32_t startup_exec(uint32_t trigger_time, void *cb_arg);
#endif
__attribute__((weak)) void keyboard_post_init_keymap(void) {}
@ -103,8 +59,10 @@ void keyboard_post_init_user(void) {
DDRB &= ~(1 << 0);
PORTB &= ~(1 << 0);
#endif
#ifdef OS_DETECTION_ENABLE
#ifdef CUSTOM_DYNAMIC_MACROS_ENABLE
dynamic_macro_init();
#endif
#if defined(OS_DETECTION_ENABLE) && defined(DEFERRED_EXEC_ENABLE)
defer_exec(100, startup_exec, NULL);
#endif
@ -153,9 +111,6 @@ void suspend_power_down_user(void) {
__attribute__((weak)) void suspend_wakeup_init_keymap(void) {}
void suspend_wakeup_init_user(void) {
#ifdef OLED_ENABLE
oled_timer_reset();
#endif
suspend_wakeup_init_keymap();
}
@ -217,6 +172,11 @@ layer_state_t layer_state_set_user(layer_state_t state) {
__attribute__((weak)) layer_state_t default_layer_state_set_keymap(layer_state_t state) {
return state;
}
#if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
static float default_layer_songs[][MAX_LAYER][2] = DEFAULT_LAYER_SONGS;
#endif
layer_state_t default_layer_state_set_user(layer_state_t state) {
if (!is_keyboard_master()) {
return state;
@ -226,6 +186,21 @@ layer_state_t default_layer_state_set_user(layer_state_t state) {
#if defined(CUSTOM_RGBLIGHT)
state = default_layer_state_set_rgb_light(state);
#endif
static bool has_init_been_ran = false;
// We don't want to run this the first time it's called, since it's read from eeeprom and called
// as part of the startup process. But after that, it's okay.
if (has_init_been_ran) {
#if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS)
if (get_highest_layer(state) < MAX_LAYER) {
PLAY_SONG(default_layer_songs[get_highest_layer(state)]);
}
#endif
eeconfig_update_default_layer(state);
} else {
has_init_been_ran = true;
}
return state;
}
@ -238,11 +213,23 @@ __attribute__((weak)) void eeconfig_init_keymap(void) {}
void eeconfig_init_user(void) {
userspace_config.raw = 0;
userspace_config.rgb_layer_change = true;
userspace_config.autocorrection = true;
eeconfig_update_user(userspace_config.raw);
userspace_config.check = true;
#if defined(OLED_ENABLE)
userspace_config.oled_brightness = OLED_BRIGHTNESS;
#else
userspace_config.oled_brightness = 255;
#endif
eeconfig_update_user_config(&userspace_config.raw);
eeconfig_init_keymap();
}
void eeconfig_init_user_datablock(void) {
#if (EECONFIG_USER_DATA_SIZE) > 4
uint8_t eeconfig_empty_temp[(EECONFIG_USER_DATA_SIZE)-4] = {0};
eeconfig_update_user_data(eeconfig_empty_temp);
#endif
}
#ifdef SPLIT_KEYBOARD
__attribute__((weak)) void matrix_slave_scan_keymap(void) {}
void matrix_slave_scan_user(void) {

View file

@ -3,9 +3,6 @@
#pragma once
// Use custom magic number so that when switching branches, EEPROM always gets reset
#define EECONFIG_MAGIC_NUMBER (uint16_t)0x1339
#ifdef IS_COMMAND
# undef IS_COMMAND
#endif
@ -43,7 +40,6 @@
# define WPM_ESTIMATED_WORD_SIZE 5
#endif
#define UNICODE_SELECTED_MODES UNICODE_MODE_WINCOMPOSE, UNICODE_MODE_MACOS
#ifndef ONESHOT_TAP_TOGGLE
@ -98,7 +94,22 @@
# define C15 PAL_LINE(GPIOC, 15)
#endif
#define ENABLE_COMPILE_KEYCODE
#define BOTH_SHIFTS_TURNS_ON_CAPS_WORD
/* --- PRINTF_BYTE_TO_BINARY macro's --- */
#define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c"
#define PRINTF_BYTE_TO_BINARY_INT8(i) (((i)&0x80ll) ? '1' : '0'), (((i)&0x40ll) ? '1' : '0'), (((i)&0x20ll) ? '1' : '0'), (((i)&0x10ll) ? '1' : '0'), (((i)&0x08ll) ? '1' : '0'), (((i)&0x04ll) ? '1' : '0'), (((i)&0x02ll) ? '1' : '0'), (((i)&0x01ll) ? '1' : '0')
#define PRINTF_BINARY_PATTERN_INT16 PRINTF_BINARY_PATTERN_INT8 " " PRINTF_BINARY_PATTERN_INT8
#define PRINTF_BYTE_TO_BINARY_INT16(i) PRINTF_BYTE_TO_BINARY_INT8((i) >> 8), PRINTF_BYTE_TO_BINARY_INT8(i)
#define PRINTF_BINARY_PATTERN_INT32 PRINTF_BINARY_PATTERN_INT16 " " PRINTF_BINARY_PATTERN_INT16
#define PRINTF_BYTE_TO_BINARY_INT32(i) PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i)
#define PRINTF_BINARY_PATTERN_INT64 PRINTF_BINARY_PATTERN_INT32 " " PRINTF_BINARY_PATTERN_INT32
#define PRINTF_BYTE_TO_BINARY_INT64(i) PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i)
/* --- end macros --- */
#ifndef EECONFIG_USER_DATA_SIZE
# define EECONFIG_USER_DATA_SIZE 8
#endif

View file

@ -2,6 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "drashna.h"
#include <stdio.h>
#include <ctype.h>
userspace_config_t userspace_config;
@ -139,7 +141,7 @@ float autocorrect_song[][2] = SONG(PLOVER_GOODBYE_SOUND);
# endif
# endif
bool apply_autocorrect(uint8_t backspaces, const char* str) {
bool apply_autocorrect(uint8_t backspaces, const char *str) {
if (layer_state_is(_GAMEPAD)) {
return false;
}
@ -188,7 +190,7 @@ void oneshot_locked_mods_changed_user(uint8_t mods) {
# endif
#endif
void format_layer_bitmap_string(char* buffer, layer_state_t state, layer_state_t default_state) {
void format_layer_bitmap_string(char *buffer, layer_state_t state, layer_state_t default_state) {
for (int i = 0; i < 16; i++) {
if (i == 0 || i == 4 || i == 8 || i == 12) {
*buffer = ' ';
@ -207,3 +209,111 @@ void format_layer_bitmap_string(char* buffer, layer_state_t state, layer_state_t
}
*buffer = 0;
}
#if defined(OS_DETECTION_ENABLE) && defined(DEFERRED_EXEC_ENABLE)
os_variant_t os_type;
uint32_t startup_exec(uint32_t trigger_time, void *cb_arg) {
if (is_keyboard_master()) {
os_type = detected_host_os();
if (os_type) {
bool is_mac = (os_type == OS_MACOS) || (os_type == OS_IOS);
if (keymap_config.swap_lctl_lgui != is_mac) {
keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = is_mac;
eeconfig_update_keymap(keymap_config.raw);
}
# ifdef UNICODE_COMMON_ENABLE
set_unicode_input_mode_soft(keymap_config.swap_lctl_lgui ? UNICODE_MODE_MACOS : UNICODE_MODE_WINCOMPOSE);
# endif
switch (os_type) {
case OS_UNSURE:
xprintf("unknown OS Detected\n");
break;
case OS_LINUX:
xprintf("Linux Detected\n");
break;
case OS_WINDOWS:
xprintf("Windows Detected\n");
break;
# if 0
case OS_WINDOWS_UNSURE:
xprintf("Windows? Detected\n");
break;
# endif
case OS_MACOS:
xprintf("MacOS Detected\n");
break;
case OS_IOS:
xprintf("iOS Detected\n");
break;
# if 0
case OS_PS5:
xprintf("PlayStation 5 Detected\n");
break;
case OS_HANDHELD:
xprintf("Nintend Switch/Quest 2 Detected\n");
break;
# endif
}
}
}
return os_type ? 0 : 500;
}
#endif
static host_driver_t *host_driver = 0;
static bool host_driver_disabled = false;
void set_keyboard_lock(bool status) {
if (!status && !host_get_driver()) {
host_set_driver(host_driver);
} else if (status && host_get_driver()) {
host_driver = host_get_driver();
clear_keyboard();
host_set_driver(0);
} else if (status) {
clear_keyboard();
}
host_driver_disabled = status;
}
void toggle_keyboard_lock(void) {
set_keyboard_lock(!host_driver_disabled);
}
bool get_keyboard_lock(void) {
return host_driver_disabled;
}
const char *get_layer_name_string(layer_state_t state, bool alt_name) {
switch (get_highest_layer(state)) {
case _QWERTY:
return alt_name ? "Num Pad" : "QWERTY";
case _COLEMAK:
return "Colemak";
case _COLEMAK_DH:
return "Colemak-DH";
case _DVORAK:
return "Dvorak";
case _GAMEPAD:
return "Gamepad";
case _DIABLO:
return "Diablo";
case _DIABLOII:
return "Diablo II";
case _MOUSE:
return alt_name ? "Macros" : "Mouse";
case _MEDIA:
return "Media";
case _LOWER:
return "Lower";
case _RAISE:
return "Raise";
case _ADJUST:
return "Adjust";
default:
return "Unknown";
}
}

View file

@ -4,7 +4,7 @@
#pragma once
#include QMK_KEYBOARD_H
#include "eeprom.h"
#include "eeconfig_users.h"
#include "keyrecords/wrappers.h"
#include "keyrecords/process_records.h"
#include "callbacks.h"
@ -30,6 +30,9 @@
#ifdef OS_DETECTION_ENABLE
# include "os_detection.h"
#endif
#ifdef UNICODE_COMMON_ENABLE
# include "keyrecords/unicode.h"
#endif
/* Define layer names */
enum userspace_layers {
@ -88,14 +91,25 @@ void format_layer_bitmap_string(char* buffer, layer_state_t state, layer_state_t
typedef union {
uint32_t raw;
struct {
bool rgb_layer_change :1;
bool is_overwatch :1;
bool nuke_switch :1;
bool swapped_numbers :1;
bool rgb_matrix_idle_anim :1;
bool autocorrection :1;
bool rgb_layer_change :1;
bool is_overwatch :1;
bool nuke_switch :1;
bool swapped_numbers :1;
bool rgb_matrix_idle_anim :1;
bool mouse_jiggler :1;
uint8_t align_reserved :2;
uint8_t oled_brightness :8;
uint32_t reserved :15;
bool check :1;
};
} userspace_config_t;
// clang-format on
_Static_assert(sizeof(userspace_config_t) == sizeof(uint32_t), "Userspace EECONFIG out of spec.");
extern userspace_config_t userspace_config;
void set_keyboard_lock(bool enable);
bool get_keyboard_lock(void);
void toggle_keyboard_lock(void);
const char* get_layer_name_string(layer_state_t state, bool alt_name);

View file

@ -0,0 +1,53 @@
// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "eeconfig_users.h"
#include "eeprom.h"
#include "eeconfig.h"
#include <string.h>
#if (TOTAL_EEPROM_BYTE_COUNT - 1) < EECONFIG_SIZE && !defined(KEYBOARD_input_club_ergodox_infinity)
# error "More eeprom configured than is available."
#endif
#if (EECONFIG_USER_DATA_SIZE) != 0 && (EECONFIG_USER_DATA_SIZE) < 4
# error "Not enough EEPROM configured for user config."
#endif
#if (EECONFIG_USER_DATA_SIZE) == 0
# define EECONFIG_USER_TEMP EECONFIG_USER
#else
# define EECONFIG_USER_TEMP (uint32_t *)(EECONFIG_USER_DATABLOCK)
#endif
void eeconfig_read_user_config(uint32_t *data) {
#if (EECONFIG_USER_DATA_SIZE) > 0
if (!eeconfig_is_user_datablock_valid()) {
memset(data, 0, 4);
} else
#endif
eeprom_read_block(data, EECONFIG_USER_TEMP, 4);
}
void eeconfig_update_user_config(const uint32_t *data) {
eeprom_update_block(data, EECONFIG_USER_TEMP, 4);
#if (EECONFIG_USER_DATA_SIZE) > 0
eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
#endif
}
void eeconfig_read_user_data(void *data) {
#if (EECONFIG_USER_DATA_SIZE) > 4
if (eeconfig_is_user_datablock_valid()) {
eeprom_read_block(data, EECONFIG_USER_DATABLOCK + 4, (EECONFIG_USER_DATA_SIZE)-4);
} else {
memset(data, 0, (EECONFIG_USER_DATA_SIZE));
}
#endif
}
void eeconfig_update_user_data(const void *data) {
#if (EECONFIG_USER_DATA_SIZE) > 4
eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION));
eeprom_update_block(data, EECONFIG_USER_DATABLOCK + 4, (EECONFIG_USER_DATA_SIZE)-4);
#endif
}

View file

@ -0,0 +1,12 @@
// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <stdint.h>
void eeconfig_read_user_config(uint32_t *data);
void eeconfig_update_user_config(const uint32_t *data);
void eeconfig_read_user_data(void *data);
void eeconfig_update_user_data(const void *data);

View file

@ -0,0 +1,283 @@
// Copyright 2016 Jack Humbert
// Copyright 2019 Wojciech Siewierski < wojciech dot siewierski at onet dot pl >
// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "keyrecords/dynamic_macros.h"
#include "keyrecords/process_records.h"
#include "wait.h"
#include "debug.h"
#include "eeprom.h"
#include "eeconfig.h"
#include <string.h>
static uint8_t macro_id = 255;
static uint8_t recording_state = STATE_NOT_RECORDING;
#if EECONFIG_USER_DATA_SIZE < 4
# error "EECONFIG_USER_DATA_SIZE not set. Don't step on others eeprom."
#endif
#ifndef DYNAMIC_MACRO_EEPROM_BLOCK0_ADDR
# define DYNAMIC_MACRO_EEPROM_BLOCK0_ADDR (uint8_t*)(EECONFIG_USER_DATABLOCK + 4)
#endif
dynamic_macro_t dynamic_macros[DYNAMIC_MACRO_COUNT];
_Static_assert((sizeof(dynamic_macros)) <= (EECONFIG_USER_DATA_SIZE - 4), "User Data Size must be large enough to host all macros");
__attribute__((weak)) void dynamic_macro_record_start_user(void) {}
__attribute__((weak)) void dynamic_macro_play_user(uint8_t macro_id) {}
__attribute__((weak)) void dynamic_macro_record_key_user(uint8_t macro_id, keyrecord_t* record) {}
__attribute__((weak)) void dynamic_macro_record_end_user(uint8_t macro_id) {}
/**
* @brief Gets the current macro ID
*
* @return uint8_t
*/
uint8_t dynamic_macro_get_current_id(void) {
return macro_id;
}
/**
* @brief Gets the current recording state
*
* @return uint8_t
*/
uint8_t dynamic_macro_get_recording_state(void) {
return recording_state;
}
/**
* Start recording of the dynamic macro.
*
* @param macro_id[in] The id of macro to be recorded
*/
bool dynamic_macro_record_start(uint8_t macro_id) {
if (macro_id >= (uint8_t)(DYNAMIC_MACRO_COUNT)) {
return false;
}
dprintf("dynamic macro recording: started for slot %d\n", macro_id);
dynamic_macro_record_start_user();
clear_keyboard();
layer_clear();
dynamic_macros[macro_id].length = 0;
return true;
}
/**
* Play the dynamic macro.
*
* @param macro_id[in] The id of macro to be played
*/
void dynamic_macro_play(uint8_t macro_id) {
if (macro_id >= (uint8_t)(DYNAMIC_MACRO_COUNT)) {
return;
}
dprintf("dynamic macro: slot %d playback, length %d\n", macro_id, dynamic_macros[macro_id].length);
layer_state_t saved_layer_state = layer_state;
clear_keyboard();
layer_clear();
for (uint8_t i = 0; i < dynamic_macros[macro_id].length; ++i) {
process_record(&dynamic_macros[macro_id].events[i]);
}
clear_keyboard();
layer_state_set(saved_layer_state);
dynamic_macro_play_user(macro_id);
}
/**
* Record a single key in a dynamic macro.
*
* @param macro_id[in] The start of the used macro buffer.
* @param record[in] The current keypress.
*/
void dynamic_macro_record_key(uint8_t macro_id, keyrecord_t* record) {
dynamic_macro_t* macro = &dynamic_macros[macro_id];
uint8_t length = macro->length;
/* If we've just started recording, ignore all the key releases. */
if (!record->event.pressed && length == 0) {
dprintln("dynamic macro: ignoring a leading key-up event");
return;
}
if (length < DYNAMIC_MACRO_SIZE) {
macro->events[length] = *record;
macro->length = ++length;
} else {
dynamic_macro_record_key_user(macro_id, record);
}
dprintf("dynamic macro: slot %d length: %d/%d\n", macro_id, length, DYNAMIC_MACRO_SIZE);
}
/**
* End recording of the dynamic macro. Essentially just update the
* pointer to the end of the macro.
*/
void dynamic_macro_record_end(uint8_t macro_id) {
if (macro_id >= (uint8_t)(DYNAMIC_MACRO_COUNT)) {
return;
}
dynamic_macro_record_end_user(macro_id);
dynamic_macro_t* macro = &dynamic_macros[macro_id];
uint8_t length = macro->length;
keyrecord_t* events_begin = &(macro->events[0]);
keyrecord_t* events_pointer = &(macro->events[length - 1]);
dprintf("dynamic_macro: macro length before trimming: %d\n", macro->length);
while (events_pointer != events_begin && (events_pointer)->event.pressed) {
dprintln("dynamic macro: trimming a trailing key-down event");
--(macro->length);
--events_pointer;
}
macro->checksum = dynamic_macro_calc_crc(macro);
dynamic_macro_save_eeprom(macro_id);
dprintf("dynamic macro: slot %d saved, length: %d\n", macro_id, length);
}
bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t* record) {
if (STATE_NOT_RECORDING == recording_state) {
/* Program key pressed to request programming mode */
if (keycode == DYN_MACRO_PROG && record->event.pressed) {
// dynamic_macro_led_blink();
recording_state = STATE_RECORD_KEY_PRESSED;
dprintf("dynamic macro: programming key pressed, waiting for macro slot selection. %d\n", recording_state);
return false;
}
/* Macro key pressed to request macro playback */
if (IS_DYN_KEYCODE(keycode) && record->event.pressed) {
dynamic_macro_play(keycode - DYN_MACRO_KEY00);
return false;
}
/* Non-dynamic macro key, process it elsewhere. */
return true;
} else if (STATE_RECORD_KEY_PRESSED == recording_state) {
/* Program key pressed again before a macro selector key, cancel macro recording.
Blink leds to indicate cancelation. */
if (keycode == DYN_MACRO_PROG && record->event.pressed) {
// dynamic_macro_led_blink();
recording_state = STATE_NOT_RECORDING;
dprintf("dynamic macro: programming key pressed, programming mode canceled. %d\n", recording_state);
return false;
} else if (IS_DYN_KEYCODE(keycode) && record->event.pressed) {
macro_id = keycode - DYN_MACRO_KEY00;
if (dynamic_macro_record_start(macro_id)) {
/* Macro slot selected, enter recording state. */
recording_state = STATE_CURRENTLY_RECORDING;
} else {
recording_state = STATE_NOT_RECORDING;
}
return false;
}
/* Ignore any non-macro key press while in RECORD_KEY_PRESSED state. */
return false;
} else if (STATE_CURRENTLY_RECORDING == recording_state) {
/* Program key pressed to request end of macro recording. */
if (keycode == DYN_MACRO_PROG && record->event.pressed) {
dynamic_macro_record_end(macro_id);
recording_state = STATE_NOT_RECORDING;
return false;
}
/* Don't record other macro key presses. */
else if (IS_DYN_KEYCODE(keycode) && record->event.pressed) {
dprintln("dynamic macro: playback key ignored in programming mode.");
return false;
}
/* Non-macro keypress that should be recorded */
else {
dynamic_macro_record_key(macro_id, record);
/* Don't output recorded keypress. */
return false;
}
}
return true;
}
static inline uint16_t crc16_update(uint16_t crc, uint8_t a) {
crc ^= a;
for (uint8_t i = 0; i < 8; ++i) {
if (crc & 1)
crc = (crc >> 1) ^ 0xA001;
else
crc = (crc >> 1);
}
return crc;
}
uint16_t dynamic_macro_calc_crc(dynamic_macro_t* macro) {
uint16_t crc = 0;
uint8_t* data = (uint8_t*)macro;
for (uint16_t i = 0; i < DYNAMIC_MACRO_CRC_LENGTH; ++i) {
crc = crc16_update(crc, *(data++));
}
return crc;
}
inline void* dynamic_macro_eeprom_macro_addr(uint8_t macro_id) {
return DYNAMIC_MACRO_EEPROM_BLOCK0_ADDR + sizeof(dynamic_macro_t) * macro_id;
}
void dynamic_macro_load_eeprom_all(void) {
for (uint8_t i = 0; i < DYNAMIC_MACRO_COUNT; ++i) {
dynamic_macro_load_eeprom(i);
}
}
void dynamic_macro_load_eeprom(uint8_t macro_id) {
dynamic_macro_t* dst = &dynamic_macros[macro_id];
eeprom_read_block(dst, dynamic_macro_eeprom_macro_addr(macro_id), sizeof(dynamic_macro_t));
/* Validate checksum, ifchecksum is NOT valid for macro, set its length to 0 to prevent its use. */
if (dynamic_macro_calc_crc(dst) != dst->checksum) {
dprintf("dynamic macro: slot %d not loaded, checksum mismatch\n", macro_id);
dst->length = 0;
return;
}
dprintf("dynamic macro: slot %d loaded from eeprom, checksum okay\n", macro_id);
}
void dynamic_macro_save_eeprom(uint8_t macro_id) {
dynamic_macro_t* src = &dynamic_macros[macro_id];
eeprom_update_block(src, dynamic_macro_eeprom_macro_addr(macro_id), sizeof(dynamic_macro_t));
dprintf("dynamic macro: slot %d saved to eeprom\n", macro_id);
}
void dynamic_macro_init(void) {
/* zero out macro blocks */
memset(&dynamic_macros, 0, DYNAMIC_MACRO_COUNT * sizeof(dynamic_macro_t));
dynamic_macro_load_eeprom_all();
}

View file

@ -0,0 +1,50 @@
// Copyright 2016 Jack Humbert
// Copyright 2019 Wojciech Siewierski < wojciech dot siewierski at onet dot pl >
// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "action.h"
#include "action_layer.h"
#ifndef DYNAMIC_MACRO_COUNT
# define DYNAMIC_MACRO_COUNT 8
#endif
#ifndef DYNAMIC_MACRO_SIZE
# define DYNAMIC_MACRO_SIZE 64
#endif
enum dynamic_macro_recording_state {
STATE_NOT_RECORDING,
STATE_RECORD_KEY_PRESSED,
STATE_CURRENTLY_RECORDING,
};
typedef struct {
keyrecord_t events[DYNAMIC_MACRO_SIZE];
uint8_t length;
uint16_t checksum;
} dynamic_macro_t;
void dynamic_macro_init(void);
bool dynamic_macro_record_start(uint8_t macro_id);
void dynamic_macro_play(uint8_t macro_id);
void dynamic_macro_record_key(uint8_t macro_id, keyrecord_t* record);
void dynamic_macro_record_end(uint8_t macro_id);
bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t* record);
void dynamic_macro_record_start_user(void);
void dynamic_macro_play_user(uint8_t macro_id);
void dynamic_macro_record_key_user(uint8_t macro_id, keyrecord_t* record);
void dynamic_macro_record_end_user(uint8_t macro_id);
#define DYNAMIC_MACRO_CRC_LENGTH (sizeof(dynamic_macro_t) - sizeof(uint16_t))
#define IS_DYN_KEYCODE(keycode) (keycode >= DYN_MACRO_KEY00 && keycode <= DYN_MACRO_KEY15)
uint16_t dynamic_macro_calc_crc(dynamic_macro_t* macro);
void dynamic_macro_load_eeprom_all(void);
void dynamic_macro_load_eeprom(uint8_t macro_id);
void dynamic_macro_save_eeprom(uint8_t macro_id);
bool dynamic_macro_header_correct(void);

View file

@ -6,9 +6,11 @@
#ifdef OS_DETECTION_ENABLE
# include "os_detection.h"
#endif
#ifdef CUSTOM_DYNAMIC_MACROS_ENABLE
# include "keyrecords/dynamic_macros.h"
#endif
uint16_t copy_paste_timer;
bool host_driver_disabled = false;
// Defines actions tor my global custom keycodes. Defined in drashna.h file
// Then runs the _keymap's record handier if not processed here
@ -55,30 +57,15 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
#endif
#if defined(CUSTOM_POINTING_DEVICE)
&& process_record_pointing(keycode, record)
#endif
#ifdef CUSTOM_DYNAMIC_MACROS_ENABLE
&& process_record_dynamic_macro(keycode, record)
#endif
&& true)) {
return false;
}
switch (keycode) {
case FIRST_DEFAULT_LAYER_KEYCODE ... LAST_DEFAULT_LAYER_KEYCODE:
if (record->event.pressed) {
uint8_t mods = mod_config(get_mods() | get_oneshot_mods());
if (!mods) {
set_single_persistent_default_layer(keycode - FIRST_DEFAULT_LAYER_KEYCODE);
#if LAST_DEFAULT_LAYER_KEYCODE > (FIRST_DEFAULT_LAYER_KEYCODE + 3)
} else if (mods & MOD_MASK_SHIFT) {
set_single_persistent_default_layer(keycode - FIRST_DEFAULT_LAYER_KEYCODE + 4);
# if LAST_DEFAULT_LAYER_KEYCODE > (FIRST_DEFAULT_LAYER_KEYCODE + 7)
} else if (mods & MOD_MASK_CTRL) {
set_single_persistent_default_layer(keycode - FIRST_DEFAULT_LAYER_KEYCODE + 8);
# endif
#endif
}
}
break;
case VRSN: // Prints firmware version
if (record->event.pressed) {
send_string_with_delay_P(PSTR(QMK_KEYBOARD "/" QMK_KEYMAP " @ " QMK_VERSION ", Built on: " QMK_BUILDDATE), TAP_CODE_DELAY);
@ -111,7 +98,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
userspace_config.rgb_layer_change ^= 1;
dprintf("rgblight layer change [EEPROM]: %u\n", userspace_config.rgb_layer_change);
eeconfig_update_user(userspace_config.raw);
eeconfig_update_user_config(&userspace_config.raw);
if (userspace_config.rgb_layer_change) {
# if defined(CUSTOM_RGB_MATRIX)
rgb_matrix_set_flags(LED_FLAG_UNDERGLOW | LED_FLAG_KEYLIGHT | LED_FLAG_INDICATOR);
@ -168,38 +155,16 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
}
# endif
if (is_eeprom_updated) {
eeconfig_update_user(userspace_config.raw);
eeconfig_update_user_config(&userspace_config.raw);
}
}
break;
#endif
case KEYLOCK: {
static host_driver_t *host_driver = 0;
case KEYLOCK:
if (record->event.pressed) {
if (host_get_driver()) {
host_driver = host_get_driver();
clear_keyboard();
host_set_driver(0);
host_driver_disabled = true;
} else {
host_set_driver(host_driver);
host_driver_disabled = false;
}
toggle_keyboard_lock();
}
break;
}
case OLED_LOCK: {
#if defined(OLED_ENABLE) && defined(CUSTOM_OLED_DRIVER)
extern bool is_oled_locked;
if (record->event.pressed) {
is_oled_locked = !is_oled_locked;
if (is_oled_locked) {
oled_on();
}
}
#endif
} break;
#if defined(OS_DETECTION_ENABLE) && defined(OS_DETECTION_DEBUG_ENABLE)
case STORE_SETUPS:
if (record->event.pressed) {
@ -218,5 +183,18 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
__attribute__((weak)) void post_process_record_keymap(uint16_t keycode, keyrecord_t *record) {}
void post_process_record_user(uint16_t keycode, keyrecord_t *record) {
#if defined(OS_DETECTION_ENABLE) && defined(UNICODE_COMMON_ENABLE)
switch (keycode) {
case QK_MAGIC_SWAP_LCTL_LGUI:
case QK_MAGIC_SWAP_RCTL_RGUI:
case QK_MAGIC_SWAP_CTL_GUI:
case QK_MAGIC_UNSWAP_LCTL_LGUI:
case QK_MAGIC_UNSWAP_RCTL_RGUI:
case QK_MAGIC_UNSWAP_CTL_GUI:
case QK_MAGIC_TOGGLE_CTL_GUI:
set_unicode_input_mode_soft(keymap_config.swap_lctl_lgui ? UNICODE_MODE_MACOS : UNICODE_MODE_WINCOMPOSE);
break;
}
#endif
post_process_record_keymap(keycode, record);
}

View file

@ -5,27 +5,21 @@
#include "drashna.h"
enum userspace_custom_keycodes {
VRSN = QK_USER, // Prints QMK Firmware and board info
KC_QWERTY, // Sets default layer to QWERTY
FIRST_DEFAULT_LAYER_KEYCODE = KC_QWERTY, // Sets default layer to QWERTY
KC_COLEMAK_DH, // Sets default layer to COLEMAK
KC_COLEMAK, // Sets default layer to COLEMAK
KC_DVORAK, // Sets default layer to DVORAK
LAST_DEFAULT_LAYER_KEYCODE = KC_DVORAK, // Sets default layer to WORKMAN
KC_DIABLO_CLEAR, // Clears all Diablo Timers
KC_RGB_T, // Toggles RGB Layer Indication mode
RGB_IDL, // RGB Idling animations
KC_SECRET_1, // test1
KC_SECRET_2, // test2
KC_SECRET_3, // test3
KC_SECRET_4, // test4
KC_SECRET_5, // test5
KC_CCCV, // Hold to copy, tap to paste
KC_NUKE, // NUCLEAR LAUNCH DETECTED!!!
UC_FLIP, // (ಠ痊ಠ)┻━┻
UC_TABL, // ┬─┬ノ( º _ ºノ)
UC_SHRG, // ¯\_(ツ)_/¯
UC_DISA, // ಠ_ಠ
VRSN = QK_USER, // Prints QMK Firmware and board info
KC_DIABLO_CLEAR, // Clears all Diablo Timers
KC_RGB_T, // Toggles RGB Layer Indication mode
RGB_IDL, // RGB Idling animations
KC_SECRET_1, // test1
KC_SECRET_2, // test2
KC_SECRET_3, // test3
KC_SECRET_4, // test4
KC_SECRET_5, // test5
KC_CCCV, // Hold to copy, tap to paste
KC_NUKE, // NUCLEAR LAUNCH DETECTED!!!
UC_FLIP, // (ಠ痊ಠ)┻━┻
UC_TABL, // ┬─┬ノ( º _ ºノ)
UC_SHRG, // ¯\_(ツ)_/¯
UC_DISA, // ಠ_ಠ
UC_IRNY,
UC_CLUE,
KEYLOCK, // Locks keyboard by unmounting driver
@ -40,11 +34,33 @@ enum userspace_custom_keycodes {
KC_COMIC,
KC_ACCEL,
OLED_LOCK,
OLED_BRIGHTNESS_INC,
OLED_BRIGHTNESS_DEC,
STORE_SETUPS,
PRINT_SETUPS,
USER_SAFE_RANGE, // use "NEWPLACEHOLDER for keymap specific codes
PD_JIGGLER,
DYN_MACRO_PROG,
DYN_MACRO_KEY00,
DYN_MACRO_KEY01,
DYN_MACRO_KEY02,
DYN_MACRO_KEY03,
DYN_MACRO_KEY04,
DYN_MACRO_KEY05,
DYN_MACRO_KEY06,
DYN_MACRO_KEY07,
DYN_MACRO_KEY08,
DYN_MACRO_KEY09,
DYN_MACRO_KEY10,
DYN_MACRO_KEY11,
DYN_MACRO_KEY12,
DYN_MACRO_KEY13,
DYN_MACRO_KEY14,
DYN_MACRO_KEY15,
USER_SAFE_RANGE,
};
bool process_record_secrets(uint16_t keycode, keyrecord_t *record);
@ -69,27 +85,15 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record);
#define KC_SEC4 KC_SECRET_4
#define KC_SEC5 KC_SECRET_5
#define KC_QWERTY DF(_QWERTY)
#define KC_COLEMAK_DH DF(_COLEMAK_DH)
#define KC_COLEMAK DF(_COLEMAK)
#define KC_DVORAK DF(_DVORAK)
#define QWERTY KC_QWERTY
#define DVORAK KC_DVORAK
#define COLEMAK KC_COLEMAK
#define COLEMAKDH KC_COLEMAK_DH
#define DEFLYR1 FIRST_DEFAULT_LAYER_KEYCODE
#define DEFLYR2 (FIRST_DEFAULT_LAYER_KEYCODE + 1)
#define DEFLYR3 (FIRST_DEFAULT_LAYER_KEYCODE + 2)
#define DEFLYR4 (FIRST_DEFAULT_LAYER_KEYCODE + 3)
#if LAST_DEFAULT_LAYER_KEYCODE > (FIRST_DEFAULT_LAYER_KEYCODE + 3)
# define DEFLYR5 (FIRST_DEFAULT_LAYER_KEYCODE + 4)
# define DEFLYR6 (FIRST_DEFAULT_LAYER_KEYCODE + 5)
# define DEFLYR7 (FIRST_DEFAULT_LAYER_KEYCODE + 6)
# define DEFLYR8 (FIRST_DEFAULT_LAYER_KEYCODE + 7)
# if LAST_DEFAULT_LAYER_KEYCODE > (FIRST_DEFAULT_LAYER_KEYCODE + 7)
# define DEFLYR9 (FIRST_DEFAULT_LAYER_KEYCODE + 8)
# define DEFLYR10 (FIRST_DEFAULT_LAYER_KEYCODE + 9)
# define DEFLYR11 (FIRST_DEFAULT_LAYER_KEYCODE + 10)
# define DEFLYR12 (FIRST_DEFAULT_LAYER_KEYCODE + 11)
# endif
#endif
#define CLMKDH KC_COLEMAK_DH
#ifdef SWAP_HANDS_ENABLE
# define KC_C1R3 SH_T(KC_TAB)
@ -140,3 +144,7 @@ We use custom codes here, so we can substitute the right stuff
# define KC_D3_3 KC_3
# define KC_D3_4 KC_4
#endif // TAP_DANCE_ENABLE
#define OL_LOCK OLED_LOCK
#define OL_BINC OLED_BRIGHTNESS_INC
#define OL_BDEC OLED_BRIGHTNESS_DEC

View file

@ -5,9 +5,14 @@
#ifdef TAPPING_TERM_PER_KEY
__attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case BK_LWER:
return TAPPING_TERM + 25;
case QK_MOD_TAP ... QK_MOD_TAP_MAX:
if (QK_MOD_TAP_GET_MODS(keycode) & MOD_LGUI) {
return 300;
}
default:
return TAPPING_TERM;
}

View file

@ -434,3 +434,13 @@ bool process_record_unicode(uint16_t keycode, keyrecord_t *record) {
void keyboard_post_init_unicode(void) {
unicode_input_mode_init();
}
/**
* @brief Set the unicode input mode without extra functionality
*
* @param input_mode
*/
void set_unicode_input_mode_soft(uint8_t input_mode) {
unicode_config.input_mode = input_mode;
unicode_input_mode_set_kb(input_mode);
}

View file

@ -18,3 +18,4 @@ enum unicode_typing_modes {
extern uint8_t unicode_typing_mode;
extern const PROGMEM char unicode_mode_str[UNCODES_MODE_END][13];
void set_unicode_input_mode_soft(uint8_t input_mode);

View file

@ -260,7 +260,7 @@ NOTE: These are all the same length. If you do a search/replace
#define _________________ADJUST_L3_________________ RGB_RMOD,RGB_HUD,RGB_SAD, RGB_VAD, KC_RGB_T
#define _________________ADJUST_R1_________________ KC_SEC1, KC_SEC2, KC_SEC3, KC_SEC4, KC_SEC5
#define _________________ADJUST_R2_________________ CG_SWAP, DEFLYR1, DEFLYR2, DEFLYR3, DEFLYR4
#define _________________ADJUST_R2_________________ CG_SWAP, QWERTY, CLMKDH, COLEMAK, DVORAK
#define _________________ADJUST_R3_________________ MG_NKRO, KC_MUTE, KC_VOLD, KC_VOLU, KC_MNXT
// clang-format on

View file

@ -3,14 +3,7 @@
// additional fonts from
// https://github.com/datacute/TinyOLED-Fonts
#if __has_include("oled_font.h")
# include "oled_font.h"
#else
// additional fonts from
// https://github.com/datacute/TinyOLED-Fonts
# include "progmem.h"
#include "progmem.h"
// clang-format off
static const unsigned char font[] PROGMEM = {
@ -895,7 +888,7 @@ static const unsigned char font[] PROGMEM = {
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
0x18, 0x24, 0x24, 0x1C, 0x78, 0x00,
0x18, 0xA4, 0xA4, 0x9C, 0x78, 0x00,
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
@ -904,8 +897,8 @@ static const unsigned char font[] PROGMEM = {
0x7C, 0x04, 0x78, 0x04, 0x78, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x78, 0x00,
0x38, 0x44, 0x44, 0x44, 0x38, 0x00,
0x7C, 0x18, 0x24, 0x24, 0x18, 0x00,
0x18, 0x24, 0x24, 0x18, 0x7C, 0x00,
0xFC, 0x18, 0x24, 0x24, 0x18, 0x00,
0x18, 0x24, 0x24, 0x18, 0xFC, 0x00,
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
@ -923,129 +916,6 @@ static const unsigned char font[] PROGMEM = {
# endif
// top Logo section
# if defined(OLED_LOGO_GMK_BAD)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0xC0, 0xE0, 0xF0, 0xF0, 0x70,
0x38, 0x38, 0x38, 0x78, 0x70, 0xF0,
0xE0, 0xE0, 0x80, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xF0, 0xF8,
0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00,
0x80, 0xE0, 0xF8, 0xF8, 0xF8, 0xF8,
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0xF8, 0xF8, 0xF8, 0x38, 0x00,
0x80, 0xE0, 0xF0, 0xF8, 0x78, 0x38,
0x08, 0x08, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x80, 0xF8, 0xF8, 0xF8, 0x38, 0x38,
0x38, 0xF8, 0xF0, 0xF0, 0xE0, 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, 0x80, 0xFC, 0xFC,
0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_HUE_MANITEE)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0,
0x90, 0x70, 0xE8, 0xA8, 0xE4, 0xC4,
0xC4, 0xA0, 0xE4, 0xB0, 0xDC, 0xE4,
0xFC, 0xFC, 0xFC, 0xFC, 0x3C, 0x3C,
0xFC, 0xF8, 0xF0, 0xF0, 0xE0, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8,
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,
0xF8, 0xF8, 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,
# elif defined(OLED_LOGO_CORNE)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0,
0xF0, 0xF8, 0xF8, 0x18, 0x00, 0xC0,
0xF0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x80,
0x00, 0x00, 0x00, 0xE0, 0xE0, 0xC0,
0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0x00,
0x00, 0xE0, 0xE0, 0xC0, 0xC0, 0xE0,
0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x80,
0x00, 0x00, 0x00, 0x00, 0x80, 0xC0,
0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
0xE0, 0xE0, 0xC0, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_LOOSE)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8,
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x00,
0xFC, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE,
0x02, 0xF9, 0x01, 0x01, 0x05, 0x09,
0x11, 0x22, 0x06, 0xFE, 0xFE, 0xFE,
0xFE, 0xFE, 0xFE, 0xFE, 0x46, 0x46,
0x44, 0x44, 0x45, 0x44, 0x29, 0x28,
0x2A, 0x28, 0x11, 0x13, 0x05, 0x07,
0x05, 0x07, 0x05, 0x07, 0x05, 0x07,
0xE5, 0xE7, 0xE5, 0x07, 0x05, 0x07,
0x05, 0x07, 0x05, 0x07, 0x05, 0x07,
0x85, 0xC7, 0xE5, 0xE7, 0xE5, 0xE7,
0xE5, 0xE7, 0xE5, 0xC7, 0x85, 0x07,
0x85, 0xC7, 0xE5, 0xE7, 0xE5, 0xE7,
0xE5, 0xE7, 0xE5, 0xC7, 0x85, 0x07,
0x85, 0xC7, 0xE5, 0xE7, 0xE5, 0xE7,
0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0x07,
0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xE7,
0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_SKEEB)
0xC0, 0x20, 0x10, 0x08, 0x04, 0x02,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x03, 0x07, 0x0F, 0x1F,
0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01,
0xFF, 0xFF, 0x01, 0x01, 0xFF, 0xFF,
0x01, 0x01, 0xFF, 0xFF, 0x19, 0x19,
0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x01, 0x01, 0xFF, 0xFF, 0x81, 0x81,
0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x19, 0x19, 0xFF, 0xFF, 0xF9, 0xF9,
0xF9, 0xF9, 0x01, 0x01, 0xF9, 0xF9,
0xF9, 0xF9, 0xFF, 0xFF, 0x99, 0x99,
0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0xF9, 0xF9, 0xFF, 0xFF, 0x19, 0x19,
0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
0x67, 0x67, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F,
0x1F, 0x0F, 0x07, 0x03, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x02, 0x04, 0x08, 0x10, 0x20, 0xC0,
# else
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x40, 0x40, 0x40, 0xF0, 0xF8, 0xF8,
0xFF, 0x38, 0xFF, 0xF8, 0xF8, 0x3F,
0xF8, 0xF8, 0xFF, 0x38, 0xFF, 0xF8,
0xF8, 0xF0, 0x40, 0x40, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00,
0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00,
0x80, 0xC0, 0xC0, 0x00, 0xC0, 0xC0,
0x00, 0x00, 0x80, 0xC0, 0xC0, 0x00,
0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0,
0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -1055,7 +925,18 @@ static const unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#endif
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, 0x00, 0x00, 0x00,
// First icon section
0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xEC,
@ -1071,139 +952,27 @@ static const unsigned char font[] PROGMEM = {
0x14, 0x36, 0x00, 0x36, 0x77, 0x77,
// middle logo section
# if defined(OLED_LOGO_GMK_BAD)
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C,
0xFF, 0xFF, 0xFF, 0xC1, 0x80, 0x00,
0x00, 0x38, 0x38, 0xB8, 0xB8, 0xF9,
0xF9, 0xF8, 0x38, 0x00, 0x00, 0x00,
0x00, 0xC0, 0xF8, 0xFF, 0xFF, 0x1F,
0x01, 0x3F, 0xFF, 0xFF, 0xF0, 0xFE,
0x7F, 0x0F, 0x03, 0xFF, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x80,
0xFF, 0xFF, 0xFF, 0x3F, 0x1E, 0x7F,
0xFF, 0xFF, 0xF3, 0xC1, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0xFF, 0xFF, 0xFF, 0x3F, 0x1C, 0x1C,
0x9C, 0xFF, 0xFF, 0xF3, 0xE1, 0x00,
0x00, 0x00, 0x00, 0xF0, 0xFC, 0xFE,
0xFF, 0x0F, 0x07, 0x07, 0x8E, 0xFF,
0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00,
0x00, 0xF0, 0xFC, 0xFE, 0xFF, 0x8F,
0x07, 0x07, 0x8E, 0xFF, 0xFF, 0xFF,
0x3F, 0x00, 0x00, 0x00, 0x00, 0x80,
0xC0, 0x80, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_HUE_MANITEE)
0x00, 0x00, 0x00, 0x00, 0x00, 0xF0,
0xFC, 0xF6, 0xF7, 0xEF, 0xFF, 0x87,
0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F,
0x1F, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF,
0xFF, 0x07, 0x1F, 0x1F, 0x19, 0x15,
0xF7, 0x16, 0x1A, 0x1B, 0x16, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0C, 0x0C, 0x33, 0x33,
0x33, 0x33, 0x33, 0x33, 0xC0, 0xC0,
0x00, 0x00, 0x03, 0x03, 0xFF, 0xFF,
0x03, 0x03, 0x00, 0x00, 0xC0, 0xC0,
0x00, 0x00, 0x00, 0xFC, 0xFC, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0xFC,
0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0x30, 0x30, 0xCC, 0xCC,
0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_CORNE)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF8, 0xFC, 0xFE,
0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x1F, 0x07, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x81, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x81,
0xC3, 0xC3, 0xC3, 0x00, 0x00, 0xFF,
0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x81, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00,
0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF,
0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
0x9D, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C,
0x1C, 0x9D, 0xDF, 0xDF, 0xDF, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_LOOSE)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xE3, 0xC1, 0xC1, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0xFF, 0x00, 0x00, 0x80, 0x00,
0x1C, 0x3E, 0x7F, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0x22, 0x22,
0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
0x22, 0x22, 0x22, 0x14, 0x14, 0x14,
0x14, 0x14, 0x08, 0x08, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xBE,
0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xBD,
0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0x00,
0x8F, 0x9F, 0x9C, 0x9C, 0x9C, 0x9C,
0x9C, 0x9C, 0x9C, 0xFC, 0xF8, 0x00,
0xFF, 0xFF, 0xFF, 0x9C, 0x9C, 0x9C,
0x9C, 0x9C, 0x9C, 0x80, 0x80, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_SKEEB)
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x03, 0x07,
0x0F, 0x0F, 0x0F, 0x0F, 0x08, 0x08,
0x0F, 0x0F, 0x0E, 0x0E, 0x0F, 0x0F,
0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x08, 0x08, 0x0F, 0x0F, 0x09, 0x09,
0x09, 0x09, 0xF9, 0xF9, 0x09, 0x09,
0x08, 0x08, 0x0F, 0x0F, 0x0F, 0x0F,
0x0F, 0x0F, 0x08, 0x08, 0x0F, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x09, 0x09,
0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
0x09, 0x09, 0x0F, 0x0F, 0x08, 0x08,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F,
0x08, 0x08, 0x0F, 0x0F, 0x0F, 0x0F,
0x07, 0x03, 0x01, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
# else
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x49, 0x49, 0x49, 0xFF, 0xFF, 0xFF,
0xFF, 0xE0, 0xDF, 0xBF, 0xBF, 0x00,
0xBF, 0xBF, 0xDF, 0xE0, 0xFF, 0xFF,
0xFF, 0xFF, 0x49, 0x49, 0x49, 0x00,
0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F,
0x60, 0x60, 0xE0, 0xBF, 0x1F, 0x00,
0x7F, 0x7F, 0x07, 0x1E, 0x38, 0x1E,
0x07, 0x7F, 0x7F, 0x00, 0x7F, 0x7F,
0x0E, 0x1F, 0x3B, 0x71, 0x60, 0x00,
0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F,
0x0C, 0x0C, 0x0C, 0x00, 0x7E, 0x7E,
0x00, 0x7F, 0x7E, 0x03, 0x03, 0x00,
0x7F, 0x7E, 0x03, 0x03, 0x7E, 0x7E,
0x03, 0x03, 0x7F, 0x7E, 0x00, 0x0F,
0x3E, 0x70, 0x3C, 0x06, 0x3C, 0x70,
0x3E, 0x0F, 0x00, 0x32, 0x7B, 0x49,
0x49, 0x3F, 0x7E, 0x00, 0x7F, 0x7E,
0x03, 0x03, 0x00, 0x1E, 0x3F, 0x69,
0x69, 0x6F, 0x26, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# endif
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,
// second icon section
0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F,
@ -1219,124 +988,6 @@ static const unsigned char font[] PROGMEM = {
0xF0, 0xFC, 0xF2, 0x92, 0xFC, 0xF0,
// bottom logo section
# if defined(OLED_LOGO_GMK_BAD)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x03, 0x03, 0x03, 0x07,
0x07, 0x07, 0x07, 0x03, 0x03, 0x03,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x06, 0x07, 0x07, 0x07, 0x01, 0x00,
0x00, 0x00, 0x07, 0x07, 0x07, 0x01,
0x00, 0x00, 0x00, 0x07, 0x07, 0x07,
0x07, 0x00, 0x00, 0x00, 0x00, 0x07,
0x07, 0x07, 0x07, 0x00, 0x00, 0x00,
0x00, 0x03, 0x07, 0x07, 0x07, 0x06,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x03, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x03, 0x07,
0x07, 0x07, 0x07, 0x03, 0x07, 0x07,
0x07, 0x07, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x07, 0x07, 0x07,
0x07, 0x03, 0x07, 0x07, 0x07, 0x07,
0x00, 0x00, 0x00, 0x00, 0x01, 0x07,
0x07, 0x07, 0x01, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_HUE_MANITEE)
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x03, 0x07, 0x07, 0x07, 0x07, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x07, 0x07,
0x03, 0x00, 0x00, 0x02, 0x04, 0x00,
0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0x03, 0x03, 0x03,
0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x03, 0x03, 0x03, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
0x03, 0x03, 0x03, 0x03, 0x03, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_CORNE)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F,
0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x1F,
0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x3F,
0x3F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F,
0x7F, 0x7C, 0x78, 0x78, 0x38, 0x1C,
0x0F, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x03, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x03, 0x01, 0x00, 0x00, 0x00, 0x00,
0x01, 0x03, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x07, 0x07, 0x03, 0x01,
0x00, 0x00, 0x00, 0x07, 0x07, 0x07,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x07, 0x07, 0x07, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x07, 0x07,
0x07, 0x00, 0x00, 0x00, 0x01, 0x03,
0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
0x07, 0x07, 0x03, 0x01, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_LOOSE)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x03, 0x07, 0x0F,
0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00,
0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
0x20, 0x47, 0x48, 0x50, 0x40, 0x41,
0x42, 0x24, 0x30, 0x3F, 0x3F, 0x3F,
0x3F, 0x3F, 0x3F, 0x3F, 0x31, 0x31,
0x11, 0x51, 0x11, 0x11, 0x4A, 0x0A,
0x2A, 0x0A, 0x44, 0x64, 0x50, 0x70,
0x50, 0x70, 0x50, 0x70, 0x50, 0x70,
0x53, 0x73, 0x53, 0x73, 0x53, 0x73,
0x53, 0x73, 0x53, 0x73, 0x53, 0x70,
0x50, 0x71, 0x53, 0x73, 0x53, 0x73,
0x53, 0x73, 0x53, 0x71, 0x50, 0x70,
0x50, 0x71, 0x53, 0x73, 0x53, 0x73,
0x53, 0x73, 0x53, 0x71, 0x50, 0x70,
0x53, 0x73, 0x53, 0x73, 0x53, 0x73,
0x53, 0x73, 0x53, 0x73, 0x51, 0x70,
0x53, 0x73, 0x53, 0x73, 0x53, 0x73,
0x53, 0x73, 0x53, 0x73, 0x53, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# elif defined(OLED_LOGO_SKEEB)
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0x08, 0x08, 0x08, 0x08, 0x08,
0x08, 0x08, 0x08, 0x08, 0x08, 0xFF,
0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08,
0x03, 0x04, 0x08, 0x10, 0x20, 0x40,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x40, 0x20, 0x10, 0x08, 0x04, 0x03,
0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8,
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8,
0xF8, 0xF8, 0xF0, 0xE0, 0xC0, 0x80,
0x01, 0x02, 0xFC, 0xF8, 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,
#else
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 0x01, 0x01, 0x07, 0x0F, 0x0F,
0x7F, 0x0F, 0x7F, 0x0F, 0x0F, 0x7E,
0x0F, 0x0F, 0x7F, 0x0F, 0x7F, 0x0F,
0x0F, 0x07, 0x01, 0x01, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -1351,7 +1002,13 @@ static const unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
#endif
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,
// third icon section
0x1F, 0x05, 0x00, 0x02, 0x1F, 0x00,
@ -1391,14 +1048,13 @@ static const unsigned char font[] PROGMEM = {
0x6A, 0x60, 0x40, 0x00, 0x00, 0x00,
0x00, 0x04, 0x42, 0x69, 0x65, 0x65,
0x65, 0x69, 0x42, 0x04, 0x00, 0x00,
0x06, 0x0F, 0x09, 0x0F, 0x06, 0x00,
0x00, 0x00, 0x1C, 0x14, 0x1C, 0x08,
0x18, 0x08, 0x18, 0x00, 0x00, 0x00,
0x00, 0x70, 0xC8, 0xEE, 0xF9, 0x70,
0x1F, 0x05, 0x00, 0x10, 0x77, 0x40,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x06, 0x09, 0x59, 0x01, 0x02,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
// clang-format on
#endif

View file

@ -0,0 +1,207 @@
// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) <drashna@live.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// clang-format off
static const char PROGMEM code_to_name[256] = {
// 0 1 2 3 4 5 6 7 8 9 A B c D E F
' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', // 0x
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', // 1x
'3', '4', '5', '6', '7', '8', '9', '0', 20, 19, 27, 26, 22, '-', '=', '[', // 2x
']','\\', '#', ';','\'', '`', ',', '.', '/', 128,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA, // 3x
0xDB,0xDC,0xDD,0xDE,0XDF,0xFB, 'P', 'S', 19, ' ', 17, 30, 16, 16, 31, 26, // 4x
27, 25, 24, 'N', '/', '*', '-', '+', 23, '1', '2', '3', '4', '5', '6', '7', // 5x
'8', '9', '0', '.','\\', 'A', 0, '=', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 6x
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 7x
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 8x
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 9x
' ', ' ', ' ', ' ', ' ', 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // Ax
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // Bx
' ',0x9E,0x9E, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',0x9D,0x9D,0x9D,0x9D, // Cx
0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D, // Dx
'C', 'S', 'A', 'G', 'C', 'S', 'A', 'G', ' ', ' ', ' ', ' ', ' ', 24, 26, 24, // Ex
25, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 24, 25, 27, 26, ' ', ' ', ' ' // Fx
};
static const char PROGMEM gmk_bad_logo[384] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF0, 0x70, 0x38, 0x38, 0x38, 0x78, 0x70, 0xF0, 0xE0, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0x00, 0x00, 0x00, 0x80, 0xE0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF8, 0xF8, 0xF8, 0x38, 0x00, 0x80, 0xE0, 0xF0, 0xF8, 0x78, 0x38, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xF8, 0xF8, 0xF8, 0x38, 0x38, 0x38, 0xF8, 0xF0, 0xF0, 0xE0, 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, 0x80, 0xFC, 0xFC, 0xFC, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0xFF, 0xFF, 0xFF, 0xC1, 0x80, 0x00, 0x00, 0x38, 0x38, 0xB8, 0xB8, 0xF9, 0xF9, 0xF8, 0x38, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xF8, 0xFF, 0xFF, 0x1F, 0x01, 0x3F, 0xFF, 0xFF, 0xF0, 0xFE, 0x7F, 0x0F, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x1E, 0x7F, 0xFF, 0xFF, 0xF3, 0xC1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xFF, 0xFF, 0xFF, 0x3F, 0x1C, 0x1C, 0x9C, 0xFF, 0xFF, 0xF3, 0xE1, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFC, 0xFE, 0xFF, 0x0F, 0x07, 0x07, 0x8E, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFC, 0xFE, 0xFF, 0x8F, 0x07, 0x07, 0x8E, 0xFF, 0xFF, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x07, 0x07, 0x07, 0x01, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x01, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x07, 0x07, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x07, 0x07, 0x07, 0x03, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x07, 0x07, 0x07, 0x03, 0x07, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x07, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const char PROGMEM hue_manitee_logo[384] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0x90, 0x70, 0xE8, 0xA8, 0xE4, 0xC4, 0xC4, 0xA0, 0xE4, 0xB0, 0xDC, 0xE4, 0xFC, 0xFC, 0xFC, 0xFC, 0x3C, 0x3C, 0xFC, 0xF8, 0xF0, 0xF0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xF8, 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, 0xF8, 0xF8, 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, 0xF0, 0xFC, 0xF6, 0xF7, 0xEF, 0xFF, 0x87, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x1F, 0x1F, 0x19, 0x15, 0xF7, 0x16, 0x1A, 0x1B, 0x16, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xC0, 0xC0, 0x00, 0x00, 0x03, 0x03, 0xFF, 0xFF, 0x03, 0x03, 0x00, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xFC, 0xFC, 0x00, 0x00, 0x00, 0xFC, 0xFC, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x30, 0x30, 0xCC, 0xCC, 0x03, 0x03, 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, 0x01, 0x03, 0x07, 0x07, 0x07, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x07, 0x03, 0x00, 0x00, 0x02, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const char PROGMEM corne_logo[384] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0x18, 0x00, 0xC0, 0xF0, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0x00, 0x00, 0xE0, 0xE0, 0xC0, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xC0, 0x80, 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, 0xF8, 0xFC, 0xFE, 0xFF, 0xE0, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xC3, 0xC3, 0xC3, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x9D, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x9D, 0xDF, 0xDF, 0xDF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x1F, 0x1F, 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x3F, 0x3F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7C, 0x78, 0x78, 0x38, 0x1C, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const char PROGMEM loose_logo[384] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0x00, 0xFC, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x02, 0xF9, 0x01, 0x01, 0x05, 0x09, 0x11, 0x22, 0x06, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0x46, 0x46, 0x44, 0x44, 0x45, 0x44, 0x29, 0x28, 0x2A, 0x28, 0x11, 0x13, 0x05, 0x07, 0x05, 0x07, 0x05, 0x07, 0x05, 0x07, 0xE5, 0xE7, 0xE5, 0x07, 0x05, 0x07, 0x05, 0x07, 0x05, 0x07, 0x05, 0x07, 0x85, 0xC7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xC7, 0x85, 0x07, 0x85, 0xC7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xC7, 0x85, 0x07, 0x85, 0xC7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0x07, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0xE7, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE3, 0xC1, 0xC1, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x80, 0x00, 0x1C, 0x3E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x14, 0x14, 0x14, 0x14, 0x14, 0x08, 0x08, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0xBE, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x81, 0xBD, 0x81, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x8F, 0x9F, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0xFC, 0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x9C, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x1F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x20, 0x47, 0x48, 0x50, 0x40, 0x41, 0x42, 0x24, 0x30, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x31, 0x31, 0x11, 0x51, 0x11, 0x11, 0x4A, 0x0A, 0x2A, 0x0A, 0x44, 0x64, 0x50, 0x70, 0x50, 0x70, 0x50, 0x70, 0x50, 0x70, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x70, 0x50, 0x71, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x71, 0x50, 0x70, 0x50, 0x71, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x71, 0x50, 0x70, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x51, 0x70, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x73, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const char PROGMEM skeeb_logo[384] = {
0xC0, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0xFF, 0xFF, 0x01, 0x01, 0xFF, 0xFF, 0x01, 0x01, 0xFF, 0xFF, 0x19, 0x19, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x01, 0x01, 0xFF, 0xFF, 0x81, 0x81, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x19, 0x19, 0xFF, 0xFF, 0xF9, 0xF9, 0xF9, 0xF9, 0x01, 0x01, 0xF9, 0xF9, 0xF9, 0xF9, 0xFF, 0xFF, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xF9, 0xF9, 0xFF, 0xFF, 0x19, 0x19, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x67, 0x67, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0xC0, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x08, 0x08, 0x0F, 0x0F, 0x0E, 0x0E, 0x0F, 0x0F, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x08, 0x08, 0x0F, 0x0F, 0x09, 0x09, 0x09, 0x09, 0xF9, 0xF9, 0x09, 0x09, 0x08, 0x08, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x08, 0x08, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0F, 0x0F, 0x08, 0x08, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x08, 0x08, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xFF, 0x08, 0x08, 0x0F, 0x0F, 0x08, 0x08, 0x03, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x03, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x01, 0x02, 0xFC, 0xF8, 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, 0x00, 0x00
};
static const char PROGMEM qmk_logo[384] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0xF0, 0xF8, 0xF8, 0xFF, 0x38, 0xFF, 0xF8, 0xF8, 0x3F, 0xF8, 0xF8, 0xFF, 0x38, 0xFF, 0xF8, 0xF8, 0xF0, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0xC0, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 0x00, 0x00, 0x80, 0xC0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x00, 0xC0, 0xC0, 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, 0x49, 0x49, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xDF, 0xBF, 0xBF, 0x00, 0xBF, 0xBF, 0xDF, 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x3F, 0x60, 0x60, 0xE0, 0xBF, 0x1F, 0x00, 0x7F, 0x7F, 0x07, 0x1E, 0x38, 0x1E, 0x07, 0x7F, 0x7F, 0x00, 0x7F, 0x7F, 0x0E, 0x1F, 0x3B, 0x71, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x7F, 0x0C, 0x0C, 0x0C, 0x00, 0x7E, 0x7E, 0x00, 0x7F, 0x7E, 0x03, 0x03, 0x00, 0x7F, 0x7E, 0x03, 0x03, 0x7E, 0x7E, 0x03, 0x03, 0x7F, 0x7E, 0x00, 0x0F, 0x3E, 0x70, 0x3C, 0x06, 0x3C, 0x70, 0x3E, 0x0F, 0x00, 0x32, 0x7B, 0x49, 0x49, 0x3F, 0x7E, 0x00, 0x7F, 0x7E, 0x03, 0x03, 0x00, 0x1E, 0x3F, 0x69, 0x69, 0x6F, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x07, 0x0F, 0x0F, 0x7F, 0x0F, 0x7F, 0x0F, 0x0F, 0x7E, 0x0F, 0x0F, 0x7F, 0x0F, 0x7F, 0x0F, 0x0F, 0x07, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
static const char PROGMEM qmk_large_logo[1024] = {
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, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x3f, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x3f, 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, 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, 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, 0x00, 0x03, 0x83, 0x83, 0x83, 0x83, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83, 0x83, 0x83, 0x83, 0x03, 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, 0x81, 0x83, 0x83, 0x83, 0x83, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 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, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x83, 0x83, 0x83, 0x83, 0x81, 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, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x1f, 0x3f, 0x7f, 0x7e, 0xf8, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf8, 0x7e, 0x7f, 0x3f, 0x1f, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 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, 0xc0, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc0, 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, 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, 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, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xfc, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 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
};
static const char PROGMEM header_image[128] = { 0x00, 0xC0, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0xC0 };
static const char PROGMEM row_2_image[128] = { 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF };
static const char PROGMEM display_border[3] = {0x0, 0xFF, 0x0};
static const char PROGMEM footer_image[128] = { 0x00, 0x03, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x03 };
static const char PROGMEM mouse_logo[3][2][16] = {
{ // mouse icon
{ 0x00, 0x00, 0x00, 0xFC, 0x02, 0x02, 0x02, 0x3A, 0x02, 0x02, 0x02, 0xFC, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x3F, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x60, 0x3F, 0x00, 0x00, 0x00 }
},
{ // crosshair icon
{0x80, 0xF0, 0x88, 0xE4, 0x92, 0x8A, 0xCA, 0x7F, 0xCA, 0x8A, 0x92, 0xE4, 0x88, 0xF0, 0x80, 0x00 },
{0x00, 0x07, 0x08, 0x13, 0x24, 0x28, 0x29, 0x7F, 0x29, 0x28, 0x24, 0x13, 0x08, 0x07, 0x00, 0x00 }
},
{ // dragscroll icon
{0x00, 0x00, 0x70, 0x88, 0x9C, 0x02, 0x0F, 0x01, 0x0F, 0x02, 0x8C, 0x44, 0x38, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x0F, 0x1C, 0x3C, 0x7C, 0x3C, 0x1C, 0x0F, 0x06, 0x02, 0x00, 0x00, 0x00}
}
};
// Images credit j-inc(/James Incandenza) and pixelbenny.
// Credit to obosob for initial animation approach.
// heavily modified by drashna because he's a glutton for punishment
#define OLED_ANIM_SIZE 36
#define OLED_ANIM_ROWS 4
#define OLED_ANIM_MAX_FRAMES 3
static const char PROGMEM animation[4][OLED_ANIM_MAX_FRAMES][OLED_ANIM_ROWS][OLED_ANIM_SIZE] = {
{ // sleep frames
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xa8, 0x48, 0xa8, 0x18, 0x08, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x80, 0x44, 0x84, 0x06, 0x05, 0x04, 0x80, 0x40, 0x20, 0x10, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x18, 0x04, 0x04, 0x02, 0x7a, 0x86, 0x01, 0x80, 0x80, 0x01, 0x03, 0x05, 0x07, 0x01, 0x00, 0x00, 0x80, 0x83, 0x45, 0xfa, 0x3c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x33, 0x24, 0x28, 0x28, 0x29, 0x29, 0x29, 0x3a, 0x18, 0x1c, 0x39, 0x24, 0x24, 0x3a, 0x2d, 0x26, 0x31, 0x1f, 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, 0x22, 0x22, 0x3a, 0x2a, 0x26, 0x22, 0x80, 0xc0, 0x80, 0x00, 0x24, 0x34, 0x2c, 0xe4, 0x60, 0x10, 0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x38, 0x04, 0x02, 0x02, 0x01, 0x79, 0x87, 0x01, 0x80, 0x81, 0x83, 0x05, 0x05, 0x03, 0x01, 0x00, 0x00, 0x80, 0x43, 0x05, 0xfa, 0x3c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x33, 0x24, 0x28, 0x28, 0x28, 0x29, 0x29, 0x3a, 0x18, 0x1c, 0x39, 0x24, 0x24, 0x3a, 0x2d, 0x26, 0x31, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00 }
}
},
{ // wake frames
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x08, 0x10, 0x60, 0x80, 0x00, 0x80, 0x60, 0x10, 0x08, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x40, 0x40, 0x5c, 0x00, 0x01, 0x41, 0x01, 0x00, 0x5c, 0x40, 0x40, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x80, 0xe1, 0x12, 0x0a, 0x06, 0x00, 0x80, 0x00, 0x06, 0x0a, 0x12, 0xe1, 0x80, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x11, 0x10, 0x10, 0x14, 0x14, 0x1f, 0x1c, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00 }
},
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x08, 0x10, 0x60, 0x80, 0x00, 0x80, 0x60, 0x10, 0x08, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x90, 0x12, 0x0a, 0x02, 0xf4, 0x09, 0x0d, 0xf1, 0x04, 0x02, 0x0a, 0x12, 0x90, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x80, 0xe1, 0x12, 0x0a, 0x06, 0x01, 0x81, 0x00, 0x06, 0x0a, 0x12, 0xe1, 0x80, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x11, 0x10, 0x10, 0x14, 0x14, 0x1f, 0x1c, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00 }
}
},
{ // kaki frames
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x40, 0x80, 0x80, 0x80, 0x00, 0xfc, 0x84, 0x08, 0x08, 0x10, 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1e, 0x60, 0x80, 0x00, 0x00, 0x91, 0xa1, 0x80, 0x00, 0x00, 0x22, 0x84, 0x40, 0x50, 0x48, 0xc1, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x41, 0x82, 0xe2, 0x12, 0x0a, 0x06, 0x00, 0x80, 0x88, 0x4f, 0x02, 0x22, 0xe2, 0x9f, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x14, 0x10, 0x10, 0x10, 0x10, 0x10, 0x14, 0x14, 0x1f, 0x1a, 0x0a, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x06, 0x1a, 0x22, 0xc2, 0x04, 0x04, 0x04, 0x07, 0x00, 0xc0, 0x20, 0x10, 0x80, 0x80, 0x01, 0x01, 0x02, 0xfc, 0xfe, 0x02, 0x3c, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0d, 0x8d, 0x55, 0x50, 0x94, 0xf0, 0x10, 0x09, 0x08, 0x00, 0x80, 0x00, 0x06, 0x09, 0x1b, 0xee, 0x00, 0x00, 0x00, 0x00, 0x81, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x19, 0x18, 0x1c, 0x14, 0x16, 0x15, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00 }
},
{
{ 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x01, 0x02, 0x04, 0x04, 0x03, 0x80, 0x40, 0x40, 0x20, 0x00, 0x01, 0x02, 0x8c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0d, 0x8d, 0x55, 0x50, 0x94, 0xf0, 0x10, 0x0a, 0x0e, 0x1d, 0x95, 0x24, 0x24, 0x27, 0x13, 0xe1, 0x01, 0x01, 0x01, 0x01, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x19, 0x18, 0x1c, 0x14, 0x14, 0x17, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00 }
}
},
{ // rtogi frames
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x0f, 0x90, 0x10, 0x20, 0xf0, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x48, 0x47, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 0xc7, 0xc4, 0x62, 0x23, 0x11, 0x3f, 0x00, 0x00, 0x00, 0x00 },
{ 0x80, 0x40, 0x20, 0x10, 0x88, 0xcc, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x80, 0x80, 0xc0, 0xe1, 0xfe, 0xb8, 0x88, 0x0c, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x07, 0x07, 0x07, 0x03, 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, 0xc0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f, 0xa0, 0x20, 0x40, 0x80, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x48, 0x47, 0x88, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x28, 0x6b, 0x40, 0xa0, 0x99, 0x86, 0xff, 0x00, 0x00, 0x00, 0x00 },
{ 0x0f, 0x11, 0x22, 0x44, 0x48, 0x4c, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x80, 0x80, 0xc0, 0xe1, 0xfe, 0xb8, 0x88, 0x0c, 0x04, 0x06, 0x06, 0x06, 0x0e, 0x0e, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x07, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}
}
};
static const char PROGMEM tri_layer_image[][3][24] = {
{ // base
{ 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x88, 0x88, 0x5D, 0x5D, 0x3E, 0x3E, 0x7C, 0x7C, 0xF8, 0xF8, 0x7C, 0x7C, 0x3E, 0x3E, 0x5D, 0x5D, 0x88, 0x88, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{ // raise
{ 0x00, 0x00, 0x00, 0x80, 0x80, 0xC0, 0xC0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0, 0xC0, 0x80, 0x80, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x88, 0x88, 0x55, 0x55, 0x23, 0x23, 0x47, 0x47, 0x8F, 0x8F, 0x47, 0x47, 0x23, 0x23, 0x55, 0x55, 0x88, 0x88, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{ // lower
{ 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x88, 0x88, 0xD5, 0xD5, 0xE2, 0xE2, 0xC4, 0xC4, 0x88, 0x88, 0xC4, 0xC4, 0xE2, 0xE2, 0xD5, 0xD5, 0x88, 0x88, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x07, 0x07, 0x0F, 0x0F, 0x07, 0x07, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{ // adjust
{ 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0xC0, 0x60, 0xA0, 0x50, 0xB0, 0x58, 0xA8, 0x50, 0xB0, 0x60, 0xA0, 0x40, 0xC0, 0x80, 0x80, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x88, 0x88, 0x5D, 0xD5, 0x6B, 0xB6, 0x6D, 0xD6, 0xAD, 0xDA, 0x6D, 0xD6, 0x6B, 0xB6, 0x5D, 0xD5, 0x88, 0x88, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x02, 0x05, 0x06, 0x0D, 0x0A, 0x05, 0x06, 0x03, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{ // blank
{ 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, 0x00, 0x00, 0x00 },
},
{ // better gamepad
{ 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xE0, 0x70, 0xF0, 0xF0, 0xF0, 0xF0, 0x90, 0x90, 0xF0, 0xF0, 0xF0, 0xF0, 0x70, 0xE0, 0xE0, 0xC0, 0x00, 0x00, 0x00 },
{ 0x80, 0xF8, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xE6, 0xC3, 0xC3, 0xE6, 0xFF, 0xFF, 0xFE, 0xF7, 0xE3, 0xF6, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xF8, 0x80 },
{ 0x07, 0x0F, 0x0F, 0x0F, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x0F, 0x0F, 0x0F, 0x07 }
},
{ // mouse
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x20, 0x20, 0x20, 0xA0, 0x20, 0x20, 0x20, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x0F, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}
};

View file

@ -4,14 +4,12 @@
#pragma once
#ifndef OLED_UPDATE_INTERVAL
# ifdef OLED_DRIVER_SH1107
# define OLED_UPDATE_INTERVAL 75
# ifdef SPLIT_KEYBOARD
# define OLED_UPDATE_INTERVAL 60
# elif defined(OLED_DISPLAY_128X128)
# define OLED_UPDATE_INTERVAL 30
# else
# ifdef SPLIT_KEYBOARD
# define OLED_UPDATE_INTERVAL 60
# else
# define OLED_UPDATE_INTERVAL 15
# endif
# define OLED_UPDATE_INTERVAL 15
# endif
#endif
#define OLED_DISABLE_TIMEOUT
@ -40,24 +38,3 @@
#define OLED_LOGO_SCIFI
// # define OLED_LOGO_SETS3N
// # define OLED_LOGO_SKEEB
#ifdef OLED_DRIVER_SH1107
# define OLED_DISPLAY_CUSTOM
# define OLED_IC_SH1107 2
# define OLED_DISPLAY_128X128
# define OLED_DISPLAY_WIDTH 128
# define OLED_DISPLAY_HEIGHT 128
# define OLED_MATRIX_SIZE (OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)
# define OLED_BLOCK_TYPE uint32_t
# define OLED_SOURCE_MAP \
{ 0, 8, 16, 24, 32, 40, 48, 56 }
# define OLED_TARGET_MAP \
{ 56, 48, 40, 32, 24, 16, 8, 0 }
# define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8)
# define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)
# define OLED_COM_PINS COM_PINS_ALT
# define OLED_IC OLED_IC_SH1107
# ifndef OLED_BRIGHTNESS
# define OLED_BRIGHTNESS 50
# endif
#endif

View file

@ -16,6 +16,10 @@
*/
#include "drashna.h"
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include "lib/lib8tion/lib8tion.h"
#ifdef UNICODE_COMMON_ENABLE
# include "process_unicode_common.h"
# include "keyrecords/unicode.h"
@ -23,42 +27,39 @@
#ifdef AUDIO_CLICKY
# include "process_clicky.h"
#endif
#include <string.h>
bool is_oled_enabled = true, is_oled_locked = false;
extern bool host_driver_disabled;
uint32_t oled_timer = 0;
char keylog_str[OLED_KEYLOGGER_LENGTH] = {0};
static uint16_t log_timer = 0;
#ifdef OLED_DISPLAY_VERBOSE
const char PROGMEM display_border[3] = {0x0, 0xFF, 0x0};
#ifndef OLED_BRIGHTNESS_STEP
# define OLED_BRIGHTNESS_STEP 32
#endif
bool is_oled_enabled = true, is_oled_locked = false, is_oled_force_off = false;
uint32_t oled_timer = 0;
char oled_keylog_str[OLED_KEYLOGGER_LENGTH + 1] = {0};
deferred_token kittoken;
// clang-format off
static const char PROGMEM code_to_name[256] = {
// 0 1 2 3 4 5 6 7 8 9 A B c D E F
' ', ' ', ' ', ' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', // 0x
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', // 1x
'3', '4', '5', '6', '7', '8', '9', '0', 20, 19, 27, 26, 22, '-', '=', '[', // 2x
']','\\', '#', ';','\'', '`', ',', '.', '/', 128,0xD5,0xD6,0xD7,0xD8,0xD9,0xDA, // 3x
0xDB,0xDC,0xDD,0xDE,0XDF,0xFB,'P', 'S', 19, ' ', 17, 30, 16, 16, 31, 26, // 4x
27, 25, 24, 'N', '/', '*', '-', '+', 23, '1', '2', '3', '4', '5', '6', '7', // 5x
'8', '9', '0', '.','\\', 'A', 0, '=', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 6x
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 7x
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 8x
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // 9x
' ', ' ', ' ', ' ', ' ', 0, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // Ax
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // Bx
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // Cx
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', // Dx
'C', 'S', 'A', 'C', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 24, 26, 24, // Ex
25,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D,0x9D, 24, 25, 27, 26, ' ', ' ', ' ' // Fx
};
// clang-format on
extern uint8_t oled_buffer[OLED_MATRIX_SIZE];
extern OLED_BLOCK_TYPE oled_dirty;
void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_start, uint16_t x_end) {
uint16_t i = 0;
for (uint16_t y = y_start; y < y_end; y++) {
if (left) {
for (uint16_t x = x_start; x < x_end - 1; x++) {
i = y * OLED_DISPLAY_WIDTH + x;
oled_buffer[i] = oled_buffer[i + 1];
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
}
} else {
for (uint16_t x = x_end - 1; x > 0; x--) {
i = y * OLED_DISPLAY_WIDTH + x;
oled_buffer[i] = oled_buffer[i - 1];
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
}
}
}
}
/**
* @brief parses pressed keycodes and saves to buffer
@ -67,32 +68,34 @@ static const char PROGMEM code_to_name[256] = {
* @param record keyrecord_t data structure
*/
void add_keylog(uint16_t keycode, keyrecord_t *record) {
if (keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) {
keycode = QK_MOD_TAP_GET_TAP_KEYCODE(keycode);
} else if (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) {
keycode = QK_LAYER_TAP_GET_TAP_KEYCODE(keycode);
} else if (keycode >= QK_MODS && keycode <= QK_MODS_MAX) {
keycode = QK_MODS_GET_BASIC_KEYCODE(keycode);
if (IS_QK_MOD_TAP(keycode)) {
if (record->tap.count) {
keycode = keycode_config(QK_MOD_TAP_GET_TAP_KEYCODE(keycode));
} else {
keycode = keycode_config(0xE0 + biton(QK_MOD_TAP_GET_MODS(keycode) & 0xF) + biton(QK_MOD_TAP_GET_MODS(keycode) & 0x10));
}
} else if (IS_QK_LAYER_TAP(keycode) && record->tap.count) {
keycode = keycode_config(QK_LAYER_TAP_GET_TAP_KEYCODE(keycode));
} else if (IS_QK_MODS(keycode)) {
keycode = keycode_config(QK_MODS_GET_BASIC_KEYCODE(keycode));
} else if (IS_QK_ONE_SHOT_MOD(keycode)) {
keycode = keycode_config(0xE0 + biton(QK_ONE_SHOT_MOD_GET_MODS(keycode) & 0xF) + biton(QK_ONE_SHOT_MOD_GET_MODS(keycode) & 0x10));
} else if (IS_QK_BASIC(keycode)) {
keycode = keycode_config(keycode);
}
if ((keycode == KC_BSPC) && mod_config(get_mods() | get_oneshot_mods()) & MOD_MASK_CTRL) {
memset(keylog_str, ' ', OLED_KEYLOGGER_LENGTH);
keylog_str[OLED_KEYLOGGER_LENGTH-1] = 0x00;
return;
}
if (record->tap.count) {
keycode &= 0xFF;
} else if (keycode > 0xFF) {
memset(oled_keylog_str, ' ', OLED_KEYLOGGER_LENGTH);
oled_keylog_str[OLED_KEYLOGGER_LENGTH] = 0x00;
return;
}
memmove(keylog_str, keylog_str + 1, OLED_KEYLOGGER_LENGTH - 2);
if (keycode < ARRAY_SIZE(code_to_name)) {
keylog_str[(OLED_KEYLOGGER_LENGTH - 2)] = pgm_read_byte(&code_to_name[keycode]);
if (keycode > ARRAY_SIZE(code_to_name)) {
return;
}
log_timer = timer_read();
memmove(oled_keylog_str, oled_keylog_str + 1, OLED_KEYLOGGER_LENGTH - 1);
oled_keylog_str[(OLED_KEYLOGGER_LENGTH - 1)] = pgm_read_byte(&code_to_name[keycode]);
}
/**
@ -107,15 +110,25 @@ void add_keylog(uint16_t keycode, keyrecord_t *record) {
*/
bool process_record_user_oled(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
oled_timer_reset();
add_keylog(keycode, record);
if (keycode == OLED_BRIGHTNESS_INC) {
userspace_config.oled_brightness = qadd8(userspace_config.oled_brightness, OLED_BRIGHTNESS_STEP);
oled_set_brightness(userspace_config.oled_brightness);
eeconfig_update_user_config(&userspace_config.raw);
} else if (keycode == OLED_BRIGHTNESS_DEC) {
userspace_config.oled_brightness = qsub8(userspace_config.oled_brightness, OLED_BRIGHTNESS_STEP);
oled_set_brightness(userspace_config.oled_brightness);
eeconfig_update_user_config(&userspace_config.raw);
} else if (keycode == OLED_LOCK) {
is_oled_locked = !is_oled_locked;
if (is_oled_locked) {
oled_on();
}
}
}
return true;
}
void oled_timer_reset(void) {
oled_timer = timer_read32();
}
/**
* @brief Renders keylogger buffer to oled
*
@ -125,7 +138,7 @@ void render_keylogger_status(uint8_t col, uint8_t line) {
oled_set_cursor(col, line);
#endif
oled_write_P(PSTR(OLED_RENDER_KEYLOGGER), false);
oled_write(keylog_str, false);
oled_write(oled_keylog_str, false);
#ifdef OLED_DISPLAY_VERBOSE
oled_advance_page(true);
#endif
@ -138,7 +151,18 @@ void render_keylogger_status(uint8_t col, uint8_t line) {
void render_default_layer_state(uint8_t col, uint8_t line) {
#ifdef OLED_DISPLAY_VERBOSE
oled_set_cursor(col, line);
#endif
oled_write_P(PSTR(OLED_RENDER_LAYOUT_NAME), false);
static char layer_state_buffer[11] = {0};
static layer_state_t old_state = 0;
if (old_state != default_layer_state) {
snprintf(layer_state_buffer, sizeof(layer_state_buffer), "%-10s", get_layer_name_string(default_layer_state, false));
old_state = default_layer_state;
}
oled_write(layer_state_buffer, false);
oled_advance_page(true);
#else
oled_write_P(PSTR(OLED_RENDER_LAYOUT_NAME), false);
switch (get_highest_layer(default_layer_state)) {
case _QWERTY:
@ -154,8 +178,6 @@ void render_default_layer_state(uint8_t col, uint8_t line) {
oled_write_P(PSTR(OLED_RENDER_LAYOUT_DVORAK), false);
break;
}
#ifdef OLED_DISPLAY_VERBOSE
oled_advance_page(true);
#endif
}
@ -165,114 +187,6 @@ void render_default_layer_state(uint8_t col, uint8_t line) {
*/
void render_layer_state(uint8_t col, uint8_t line) {
#ifdef OLED_DISPLAY_VERBOSE
// clang-format off
static const char PROGMEM tri_layer_image[][3][24] = {
// base
{
{
0x00, 0x00, 0x00, 0x80, 0x80, 0x40,
0x40, 0x20, 0x20, 0x10, 0x10, 0x08,
0x08, 0x10, 0x10, 0x20, 0x20, 0x40,
0x40, 0x80, 0x80, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x88, 0x88, 0x5D,
0x5D, 0x3E, 0x3E, 0x7C, 0x7C, 0xF8,
0xF8, 0x7C, 0x7C, 0x3E, 0x3E, 0x5D,
0x5D, 0x88, 0x88, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x02, 0x02, 0x04, 0x04, 0x08,
0x08, 0x04, 0x04, 0x02, 0x02, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00
}
},
// raise
{
{
0x00, 0x00, 0x00, 0x80, 0x80, 0xC0,
0xC0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8,
0xF8, 0xF0, 0xF0, 0xE0, 0xE0, 0xC0,
0xC0, 0x80, 0x80, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x88, 0x88, 0x55,
0x55, 0x23, 0x23, 0x47, 0x47, 0x8F,
0x8F, 0x47, 0x47, 0x23, 0x23, 0x55,
0x55, 0x88, 0x88, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x02, 0x02, 0x04, 0x04, 0x08,
0x08, 0x04, 0x04, 0x02, 0x02, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00
}
},
// lower
{
{
0x00, 0x00, 0x00, 0x80, 0x80, 0x40,
0x40, 0x20, 0x20, 0x10, 0x10, 0x08,
0x08, 0x10, 0x10, 0x20, 0x20, 0x40,
0x40, 0x80, 0x80, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x88, 0x88, 0xD5,
0xD5, 0xE2, 0xE2, 0xC4, 0xC4, 0x88,
0x88, 0xC4, 0xC4, 0xE2, 0xE2, 0xD5,
0xD5, 0x88, 0x88, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x03, 0x03, 0x07, 0x07, 0x0F,
0x0F, 0x07, 0x07, 0x03, 0x03, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00
}
},
// adjust
{
{
0x00, 0x00, 0x00, 0x80, 0x80, 0x40,
0xC0, 0x60, 0xA0, 0x50, 0xB0, 0x58,
0xA8, 0x50, 0xB0, 0x60, 0xA0, 0x40,
0xC0, 0x80, 0x80, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x88, 0x88, 0x5D,
0xD5, 0x6B, 0xB6, 0x6D, 0xD6, 0xAD,
0xDA, 0x6D, 0xD6, 0x6B, 0xB6, 0x5D,
0xD5, 0x88, 0x88, 0x00, 0x00, 0x00
},
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
0x01, 0x03, 0x02, 0x05, 0x06, 0x0D,
0x0A, 0x05, 0x06, 0x03, 0x02, 0x01,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00
}
},
// blank
{
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
},
// better gamepad
{
{ 0, 0, 0,192,224,224,112,240,240,240,240,144,144,240,240,240,240,112,224,224,192, 0, 0, 0 },
{ 128,248,255,255,255,254,252,230,195,195,230,255,255,254,247,227,246,253,254,255,255,255,248,128 },
{ 7, 15, 15, 15, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 15, 15, 7 }
},
// mouse
{
{ 0, 0, 0, 0, 0, 0, 0, 0,192, 32, 32, 32,160, 32, 32, 32,192, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0,240, 15, 0, 0, 0, 3, 0, 0, 0, 15,240, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 3, 6, 4, 4, 4, 4, 4, 4, 4, 6, 3, 0, 0, 0, 0, 0, 0 }
}
};
// clang-format on
uint8_t layer_is[4] = {0, 4, 4, 4};
if (layer_state_is(_ADJUST)) {
layer_is[0] = 3;
@ -376,19 +290,23 @@ void render_mod_status(uint8_t modifiers, uint8_t col, uint8_t line) {
static const char PROGMEM mod_status[5][3] = {{0xE8, 0xE9, 0}, {0xE4, 0xE5, 0}, {0xE6, 0xE7, 0}, {0xEA, 0xEB, 0}, {0xEC, 0xED, 0}};
#if defined(OLED_DISPLAY_VERBOSE)
oled_set_cursor(col, line);
#endif
bool is_caps = host_keyboard_led_state().caps_lock;
#ifdef CAPS_WORD_ENABLE
is_caps |= is_caps_word_on();
#endif
oled_write_P(PSTR(OLED_RENDER_MODS_NAME), false);
#if defined(OLED_DISPLAY_VERBOSE)
oled_write_P(mod_status[0], (modifiers & MOD_BIT(KC_LSFT)));
oled_write_P(mod_status[0], (modifiers & MOD_BIT(KC_LSFT)) || is_caps);
oled_write_P(mod_status[!keymap_config.swap_lctl_lgui ? 3 : 4], (modifiers & MOD_BIT(KC_LGUI)));
oled_write_P(mod_status[2], (modifiers & MOD_BIT(KC_LALT)));
oled_write_P(mod_status[1], (modifiers & MOD_BIT(KC_LCTL)));
oled_write_P(mod_status[1], (modifiers & MOD_BIT(KC_RCTL)));
oled_write_P(mod_status[2], (modifiers & MOD_BIT(KC_RALT)));
oled_write_P(mod_status[!keymap_config.swap_lctl_lgui ? 3 : 4], (modifiers & MOD_BIT(KC_RGUI)));
oled_write_P(mod_status[0], (modifiers & MOD_BIT(KC_RSFT)));
oled_write_P(mod_status[0], (modifiers & MOD_BIT(KC_RSFT)) || is_caps);
#else
oled_write_P(mod_status[0], (modifiers & MOD_MASK_SHIFT));
oled_write_P(mod_status[0], (modifiers & MOD_MASK_SHIFT) || is_caps);
oled_write_P(mod_status[!keymap_config.swap_lctl_lgui ? 3 : 4], (modifiers & MOD_MASK_GUI));
oled_write_P(PSTR(" "), false);
oled_write_P(mod_status[2], (modifiers & MOD_MASK_ALT));
@ -508,7 +426,7 @@ void render_user_status(uint8_t col, uint8_t line) {
static const char PROGMEM rgb_layer_status[2][3] = {{0xEE, 0xEF, 0}, {0xF0, 0xF1, 0}};
oled_write_P(rgb_layer_status[userspace_config.rgb_layer_change], false);
static const char PROGMEM cat_mode[2][3] = {{0xF8, 0xF9, 0}, {0xF6, 0xF7, 0}};
oled_write_P(cat_mode[0], host_driver_disabled);
oled_write_P(cat_mode[0], get_keyboard_lock());
#if defined(UNICODE_COMMON_ENABLE)
static const char PROGMEM uc_mod_status[5][3] = {{0xEC, 0xED, 0}, {0x20, 0x20, 0}, {0x20, 0x20, 0}, {0x20, 0x20, 0}, {0xEA, 0xEB, 0}};
oled_write_P(uc_mod_status[get_unicode_input_mode()], false);
@ -538,14 +456,53 @@ void render_rgb_hsv(uint8_t col, uint8_t line) {
oled_write_P(PSTR(", "), false);
oled_write(get_u8_str(rgb_matrix_get_val(), ' '), false);
#elif RGBLIGHT_ENABLE
oled_write(get_u8_str(rgblight_get_hue(), ' '), false);
oled_write_P(PSTR(", "), false);
oled_write(get_u8_str(rgblight_get_sat(), ' '), false);
oled_write_P(PSTR(", "), false);
oled_write(get_u8_str(rgblight_get_val(), ' '), false);
if (is_rgblight_startup_running()) {
oled_write_P(PSTR("Start Animation"), false);
} else {
oled_write(get_u8_str(rgblight_get_hue(), ' '), false);
oled_write_P(PSTR(", "), false);
oled_write(get_u8_str(rgblight_get_sat(), ' '), false);
oled_write_P(PSTR(", "), false);
oled_write(get_u8_str(rgblight_get_val(), ' '), false);
}
#endif
}
void render_rgb_mode(uint8_t col, uint8_t line) {
oled_set_cursor(col, line);
__attribute__((unused)) static uint8_t mode;
bool need_update = false;
static char buf[21] = {0};
#ifdef RGB_MATRIX_ENABLE
if (mode != rgb_matrix_get_mode()) {
snprintf(buf, sizeof(buf), "%-20s", rgb_matrix_name(rgb_matrix_get_mode()));
mode = rgb_matrix_get_mode();
need_update = true;
}
#elif RGBLIGHT_ENABLE
if (mode != rgblight_get_mode()) {
snprintf(buf, sizeof(buf), "%-20s", rgblight_name(rgblight_get_mode()));
mode = rgblight_get_mode();
need_update = true;
}
#endif
if (need_update) {
for (uint8_t i = 1; i < sizeof(buf); ++i) {
if (buf[i] == 0)
break;
else if (buf[i] == '_')
buf[i] = ' ';
else if (buf[i - 1] == ' ')
buf[i] = toupper(buf[i]);
else if (buf[i - 1] != ' ')
buf[i] = tolower(buf[i]);
}
}
oled_write(buf, false);
}
void render_wpm(uint8_t padding, uint8_t col, uint8_t line) {
#ifdef WPM_ENABLE
oled_set_cursor(col, line);
@ -642,9 +599,6 @@ void render_pointing_dpi_status(uint16_t cpi, uint8_t padding, uint8_t col, uint
// #define ANIM_FRAME_DURATION 500 // how long each frame lasts in ms
// #define SLEEP_TIMER 60000 // should sleep after this period of 0 wpm, needs fixing
#define OLED_ANIM_SIZE 36
#define OLED_ANIM_ROWS 4
#define OLED_ANIM_MAX_FRAMES 3
#if (OLED_SLEEP_FRAMES > OLED_ANIM_MAX_FRAMES) || (OLED_WAKE_FRAMES > OLED_ANIM_MAX_FRAMES) || (OLED_KAKI_FRAMES > OLED_ANIM_MAX_FRAMES) || (OLED_RTOGI_FRAMES > OLED_ANIM_MAX_FRAMES)
# error frame size too large
#endif
@ -653,81 +607,6 @@ static uint8_t animation_frame = 0;
static uint8_t animation_type = 0;
void render_kitty(uint8_t col, uint8_t line) {
// Images credit j-inc(/James Incandenza) and pixelbenny.
// Credit to obosob for initial animation approach.
// heavily modified by drashna because he's a glutton for punishment
// clang-format off
static const char PROGMEM animation[4][OLED_ANIM_MAX_FRAMES][OLED_ANIM_ROWS][OLED_ANIM_SIZE] = {
// sleep frames
{
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xa8, 0x48, 0xa8, 0x18, 0x08, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00, 0x80, 0x44, 0x84, 0x06, 0x05, 0x04, 0x80, 0x40, 0x20, 0x10, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x18, 0x04, 0x04, 0x02, 0x7a, 0x86, 0x01, 0x80, 0x80, 0x01, 0x03, 0x05, 0x07, 0x01, 0x00, 0x00, 0x80, 0x83, 0x45, 0xfa, 0x3c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x33, 0x24, 0x28, 0x28, 0x29, 0x29, 0x29, 0x3a, 0x18, 0x1c, 0x39, 0x24, 0x24, 0x3a, 0x2d, 0x26, 0x31, 0x1f, 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, 0x22, 0x22, 0x3a, 0x2a, 0x26, 0x22, 0x80, 0xc0, 0x80, 0x00, 0x24, 0x34, 0x2c, 0xe4, 0x60, 0x10, 0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x38, 0x04, 0x02, 0x02, 0x01, 0x79, 0x87, 0x01, 0x80, 0x81, 0x83, 0x05, 0x05, 0x03, 0x01, 0x00, 0x00, 0x80, 0x43, 0x05, 0xfa, 0x3c, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x33, 0x24, 0x28, 0x28, 0x28, 0x29, 0x29, 0x3a, 0x18, 0x1c, 0x39, 0x24, 0x24, 0x3a, 0x2d, 0x26, 0x31, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00 }
}
},
// wake frames
{
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x08, 0x10, 0x60, 0x80, 0x00, 0x80, 0x60, 0x10, 0x08, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x80, 0x40, 0x40, 0x5c, 0x00, 0x01, 0x41, 0x01, 0x00, 0x5c, 0x40, 0x40, 0x80, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x80, 0xe1, 0x12, 0x0a, 0x06, 0x00, 0x80, 0x00, 0x06, 0x0a, 0x12, 0xe1, 0x80, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x11, 0x10, 0x10, 0x14, 0x14, 0x1f, 0x1c, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00 }
},
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x08, 0x10, 0x60, 0x80, 0x00, 0x80, 0x60, 0x10, 0x08, 0x30, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x90, 0x12, 0x0a, 0x02, 0xf4, 0x09, 0x0d, 0xf1, 0x04, 0x02, 0x0a, 0x12, 0x90, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x40, 0x80, 0xe1, 0x12, 0x0a, 0x06, 0x01, 0x81, 0x00, 0x06, 0x0a, 0x12, 0xe1, 0x80, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x11, 0x10, 0x10, 0x14, 0x14, 0x1f, 0x1c, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00 }
}
},
// kaki frames
{
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x40, 0x40, 0x80, 0x80, 0x80, 0x00, 0xfc, 0x84, 0x08, 0x08, 0x10, 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x1e, 0x60, 0x80, 0x00, 0x00, 0x91, 0xa1, 0x80, 0x00, 0x00, 0x22, 0x84, 0x40, 0x50, 0x48, 0xc1, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x41, 0x82, 0xe2, 0x12, 0x0a, 0x06, 0x00, 0x80, 0x88, 0x4f, 0x02, 0x22, 0xe2, 0x9f, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x14, 0x10, 0x10, 0x10, 0x10, 0x10, 0x14, 0x14, 0x1f, 0x1a, 0x0a, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 }
},
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x06, 0x1a, 0x22, 0xc2, 0x04, 0x04, 0x04, 0x07, 0x00, 0xc0, 0x20, 0x10, 0x80, 0x80, 0x01, 0x01, 0x02, 0xfc, 0xfe, 0x02, 0x3c, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0d, 0x8d, 0x55, 0x50, 0x94, 0xf0, 0x10, 0x09, 0x08, 0x00, 0x80, 0x00, 0x06, 0x09, 0x1b, 0xee, 0x00, 0x00, 0x00, 0x00, 0x81, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x19, 0x18, 0x1c, 0x14, 0x16, 0x15, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00 }
},
{
{ 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x10, 0x20, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x0f, 0xf0, 0x00, 0x01, 0x02, 0x04, 0x04, 0x03, 0x80, 0x40, 0x40, 0x20, 0x00, 0x01, 0x02, 0x8c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x0d, 0x8d, 0x55, 0x50, 0x94, 0xf0, 0x10, 0x0a, 0x0e, 0x1d, 0x95, 0x24, 0x24, 0x27, 0x13, 0xe1, 0x01, 0x01, 0x01, 0x01, 0x02, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x1f, 0x14, 0x14, 0x10, 0x10, 0x11, 0x1f, 0x10, 0x10, 0x18, 0x0f, 0x18, 0x10, 0x10, 0x1f, 0x19, 0x18, 0x1c, 0x14, 0x14, 0x17, 0x14, 0x14, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00 }
}
},
// rtogi frames
{
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x0f, 0x90, 0x10, 0x20, 0xf0, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x48, 0x47, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x88, 0xc7, 0xc4, 0x62, 0x23, 0x11, 0x3f, 0x00, 0x00, 0x00, 0x00 },
{ 0x80, 0x40, 0x20, 0x10, 0x88, 0xcc, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x80, 0x80, 0xc0, 0xe1, 0xfe, 0xb8, 0x88, 0x0c, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x07, 0x07, 0x07, 0x03, 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, 0xc0, 0x20, 0x10, 0x10, 0x08, 0x04, 0x02, 0x01, 0x1f, 0xa0, 0x20, 0x40, 0x80, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x48, 0x47, 0x88, 0x00, 0x00, 0x00, 0x00, 0x24, 0x24, 0x28, 0x6b, 0x40, 0xa0, 0x99, 0x86, 0xff, 0x00, 0x00, 0x00, 0x00 },
{ 0x0f, 0x11, 0x22, 0x44, 0x48, 0x4c, 0x43, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x80, 0x80, 0xc0, 0xe1, 0xfe, 0xb8, 0x88, 0x0c, 0x04, 0x06, 0x06, 0x06, 0x0e, 0x0e, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x06, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x07, 0x07, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
}
}
};
// clang-format on
for (uint8_t i = 0; i < 4; i++) {
oled_set_cursor(col, line + i);
oled_write_raw_P(animation[animation_type][animation_frame][i], OLED_ANIM_SIZE);
@ -776,13 +655,6 @@ uint32_t kitty_animation_phases(uint32_t triger_time, void *cb_arg) {
void render_mouse_mode(uint8_t col, uint8_t line) {
#if (defined(KEYBOARD_bastardkb_charybdis) || defined(KEYBOARD_handwired_tractyl_manuform)) && defined(POINTING_DEVICE_ENABLE)
// credit and thanks to jaspertandy on discord for these images
static const char PROGMEM mouse_logo[3][2][16] = {// mouse icon
{{0, 0, 0, 252, 2, 2, 2, 58, 2, 2, 2, 252, 0, 0, 0, 0}, {0, 0, 63, 96, 64, 64, 64, 64, 64, 64, 64, 96, 63, 0, 0, 0}},
// crosshair icon
{{128, 240, 136, 228, 146, 138, 202, 127, 202, 138, 146, 228, 136, 240, 128, 0}, {0, 7, 8, 19, 36, 40, 41, 127, 41, 40, 36, 19, 8, 7, 0, 0}},
// dragscroll icon
{{0, 0, 112, 136, 156, 2, 15, 1, 15, 2, 140, 68, 56, 0, 0, 0}, {0, 0, 2, 6, 15, 28, 60, 124, 60, 28, 15, 6, 2, 0, 0, 0}}};
uint8_t image_index = 0;
# ifdef OLED_DISPLAY_TEST
image_index = animation_frame;
@ -848,7 +720,18 @@ void render_status_left(void) {
}
__attribute__((weak)) void oled_render_large_display(bool side) {
if (!side) {
if (side) {
render_rgb_hsv(1, 7);
render_rgb_mode(1, 8);
render_wpm_graph(48, 72);
} else {
oled_advance_page(true);
oled_advance_page(true);
oled_set_cursor(0, 9);
oled_write_raw_P(qmk_logo, 384); // is 3 rows of 128 pixels, so 384 bytes.
render_unicode_mode(1, 14);
}
}
@ -864,7 +747,7 @@ __attribute__((weak)) oled_rotation_t oled_init_keymap(oled_rotation_t rotation)
oled_rotation_t oled_init_user(oled_rotation_t rotation) {
if (is_keyboard_master()) {
memset(keylog_str, ' ', OLED_KEYLOGGER_LENGTH);
memset(oled_keylog_str, ' ', OLED_KEYLOGGER_LENGTH);
}
kittoken = defer_exec(3000, kitty_animation_phases, NULL);
@ -894,12 +777,7 @@ bool oled_task_user(void) {
}
#if defined(OLED_DISPLAY_VERBOSE)
static const char PROGMEM header_image[] = {
0, 192, 32, 16, 8, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 7, 15, 31, 63, 127, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 127, 63, 31, 15, 7, 3, 1, 1, 1, 1, 1, 1, 1, 1, 2, 4, 8, 16, 32, 192, 0,
// 0,255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 7, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,255, 0
};
oled_write_raw_P(header_image, sizeof(header_image));
oled_set_cursor(4, 0);
render_oled_title(is_keyboard_left());
#endif
@ -934,7 +812,6 @@ bool oled_task_user(void) {
oled_write_raw_P(display_border, sizeof(display_border));
}
static const char PROGMEM footer_image[] = {0, 3, 4, 8, 16, 32, 64, 128, 128, 128, 128, 128, 128, 128, 192, 224, 240, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 240, 224, 192, 128, 128, 128, 128, 128, 128, 128, 64, 32, 16, 8, 4, 3, 0};
oled_set_cursor(0, num_of_rows);
oled_write_raw_P(footer_image, sizeof(footer_image));
#endif
@ -942,8 +819,12 @@ bool oled_task_user(void) {
return false;
}
extern bool oled_initialized;
__attribute__((weak)) void housekeeping_task_oled(void) {
is_oled_enabled = is_oled_locked ? true : !(timer_elapsed32(oled_timer) > 60000);
void housekeeping_task_oled(void) {
is_oled_enabled = false;
if ((is_oled_locked || (last_input_activity_elapsed() < 60000)) && !is_oled_force_off) {
is_oled_enabled = true;
}
if (oled_get_brightness() != userspace_config.oled_brightness) {
oled_set_brightness(userspace_config.oled_brightness);
}
}

View file

@ -18,6 +18,7 @@
#include "quantum.h"
#include "oled_driver.h"
#include "oled_assets.h"
#ifdef DEFFERED_EXEC_ENABLE
extern deferred_token kittoken;
#endif
@ -55,7 +56,7 @@ void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_st
# define OLED_RENDER_KEYLOGGER "Keylogger: "
# ifndef OLED_KEYLOGGER_LENGTH
# define OLED_KEYLOGGER_LENGTH 10
# define OLED_KEYLOGGER_LENGTH 9
# endif
# define OLED_RENDER_LAYOUT_NAME "Layout: "
# define OLED_RENDER_LAYOUT_QWERTY "Qwerty"
@ -102,7 +103,7 @@ void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_st
#else
# define OLED_RENDER_KEYLOGGER "KLogr"
# ifndef OLED_KEYLOGGER_LENGTH
# define OLED_KEYLOGGER_LENGTH 6
# define OLED_KEYLOGGER_LENGTH 5
# endif
# define OLED_RENDER_LAYOUT_NAME "Lyout"
@ -149,7 +150,7 @@ void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_st
# define OLED_RENDER_WPM_COUNTER "WPM: "
#endif
extern char keylog_str[];
extern char oled_keylog_str[OLED_KEYLOGGER_LENGTH + 1];
#ifndef OLED_WPM_GRAPH_MAX_WPM
# define OLED_WPM_GRAPH_MAX_WPM 120

View file

@ -0,0 +1,12 @@
CUSTOM_OLED_DRIVER ?= yes
ifeq ($(strip $(OLED_ENABLE)), yes)
ifeq ($(strip $(CUSTOM_OLED_DRIVER)), yes)
OPT_DEFS += -DCUSTOM_OLED_DRIVER
SRC += $(USER_PATH)/oled/oled_stuff.c
endif
ifeq ($(strip $(OLED_DISPLAY_TEST)), yes)
OPT_DEFS += -DOLED_DISPLAY_TEST
endif
endif
DEFERRED_EXEC_ENABLE = yes

View file

@ -1,860 +0,0 @@
/*
Copyright 2019 Ryan Caltabiano <https://github.com/XScorpion2>
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 "i2c_master.h"
#include "oled_driver.h"
#include OLED_FONT_H
#include "timer.h"
#include "print.h"
#include <string.h>
#include "progmem.h"
#include "keyboard.h"
// for SH1107: https://www.displayfuture.com/Display/datasheet/controller/SH1107.pdf
// Fundamental Commands
#define CONTRAST 0x81
#define DISPLAY_ALL_ON 0xA5
#define DISPLAY_ALL_ON_RESUME 0xA4
#define NORMAL_DISPLAY 0xA6
#define INVERT_DISPLAY 0xA7
#define DISPLAY_ON 0xAF
#define DISPLAY_OFF 0xAE
#define NOP 0xE3
// Scrolling Commands
#define ACTIVATE_SCROLL 0x2F
#define DEACTIVATE_SCROLL 0x2E
#define SCROLL_RIGHT 0x26
#define SCROLL_LEFT 0x27
#define SCROLL_RIGHT_UP 0x29
#define SCROLL_LEFT_UP 0x2A
// Addressing Setting Commands
#define MEMORY_MODE 0x20
#define COLUMN_ADDR 0x21
#define PAGE_ADDR 0x22
#define PAM_SETCOLUMN_LSB 0x00
#define PAM_SETCOLUMN_MSB 0x10
#define PAM_PAGE_ADDR 0xB0 // 0xb0 -- 0xb7
// Hardware Configuration Commands
#define DISPLAY_START_LINE 0x40
#define SEGMENT_REMAP 0xA0
#define SEGMENT_REMAP_INV 0xA1
#define MULTIPLEX_RATIO 0xA8
#define COM_SCAN_INC 0xC0
#define COM_SCAN_DEC 0xC8
#define DISPLAY_OFFSET 0xD3
#define COM_PINS 0xDA
#define COM_PINS_SEQ 0x02
#define COM_PINS_ALT 0x12
#define COM_PINS_SEQ_LR 0x22
#define COM_PINS_ALT_LR 0x32
// Timing & Driving Commands
#define DISPLAY_CLOCK 0xD5
#define PRE_CHARGE_PERIOD 0xD9
#define VCOM_DETECT 0xDB
// Advance Graphic Commands
#define FADE_BLINK 0x23
#define ENABLE_FADE 0x20
#define ENABLE_BLINK 0x30
// Charge Pump Commands
#define CHARGE_PUMP 0x8D
// Commands specific to the SH1107 chip
#define SH1107_DISPLAY_START_LINE 0xDC
#define SH1107_MEMORY_MODE_PAGE 0x20
#define SH1107_MEMORY_MODE_VERTICAL 0x21
// Misc defines
#ifndef OLED_BLOCK_COUNT
# define OLED_BLOCK_COUNT (sizeof(OLED_BLOCK_TYPE) * 8)
#endif
#ifndef OLED_BLOCK_SIZE
# define OLED_BLOCK_SIZE (OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)
#endif
#define OLED_ALL_BLOCKS_MASK (((((OLED_BLOCK_TYPE)1 << (OLED_BLOCK_COUNT - 1)) - 1) << 1) | 1)
#ifndef OLED_COM_PIN_COUNT
# define OLED_COM_PIN_COUNT 128
#endif
#ifndef OLED_COM_PIN_OFFSET
# define OLED_COM_PIN_OFFSET 0
#endif
// i2c defines
#define I2C_CMD 0x00
#define I2C_DATA 0x40
#if defined(__AVR__)
# define I2C_TRANSMIT_P(data) i2c_transmit_P((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), OLED_I2C_TIMEOUT)
#else // defined(__AVR__)
# define I2C_TRANSMIT_P(data) i2c_transmit((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), OLED_I2C_TIMEOUT)
#endif // defined(__AVR__)
#define I2C_TRANSMIT(data) i2c_transmit((OLED_DISPLAY_ADDRESS << 1), &data[0], sizeof(data), OLED_I2C_TIMEOUT)
#define I2C_WRITE_REG(mode, data, size) i2c_writeReg((OLED_DISPLAY_ADDRESS << 1), mode, data, size, OLED_I2C_TIMEOUT)
#define HAS_FLAGS(bits, flags) ((bits & flags) == flags)
// Display buffer's is the same as the OLED memory layout
// this is so we don't end up with rounding errors with
// parts of the display unusable or don't get cleared correctly
// and also allows for drawing & inverting
uint8_t oled_buffer[OLED_MATRIX_SIZE];
uint8_t *oled_cursor;
OLED_BLOCK_TYPE oled_dirty = 0;
bool oled_initialized = false;
bool oled_active = false;
bool oled_scrolling = false;
bool oled_inverted = false;
uint8_t oled_brightness = OLED_BRIGHTNESS;
oled_rotation_t oled_rotation = 0;
uint8_t oled_rotation_width = 0;
uint8_t oled_scroll_speed = 0; // this holds the speed after being remapped to ssd1306 internal values
uint8_t oled_scroll_start = 0;
uint8_t oled_scroll_end = 7;
#if OLED_TIMEOUT > 0
uint32_t oled_timeout;
#endif
#if OLED_SCROLL_TIMEOUT > 0
uint32_t oled_scroll_timeout;
#endif
#if OLED_UPDATE_INTERVAL > 0
uint16_t oled_update_timeout;
#endif
// Internal variables to reduce math instructions
#if defined(__AVR__)
// identical to i2c_transmit, but for PROGMEM since all initialization is in PROGMEM arrays currently
// probably should move this into i2c_master...
static i2c_status_t i2c_transmit_P(uint8_t address, const uint8_t *data, uint16_t length, uint16_t timeout) {
i2c_status_t status = i2c_start(address | I2C_WRITE, timeout);
for (uint16_t i = 0; i < length && status >= 0; i++) {
status = i2c_write(pgm_read_byte((const char *)data++), timeout);
if (status) break;
}
i2c_stop();
return status;
}
#endif
// Flips the rendering bits for a character at the current cursor position
static void InvertCharacter(uint8_t *cursor) {
const uint8_t *end = cursor + OLED_FONT_WIDTH;
while (cursor < end) {
*cursor = ~(*cursor);
cursor++;
}
}
bool oled_init(oled_rotation_t rotation) {
#if defined(USE_I2C) && defined(SPLIT_KEYBOARD)
if (!is_keyboard_master()) {
return true;
}
#endif
oled_rotation = oled_init_user(oled_init_kb(rotation));
if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
oled_rotation_width = OLED_DISPLAY_WIDTH;
} else {
oled_rotation_width = OLED_DISPLAY_HEIGHT;
}
i2c_init();
static const uint8_t PROGMEM display_setup1[] = {
I2C_CMD,
DISPLAY_OFF,
DISPLAY_CLOCK,
0x80,
MULTIPLEX_RATIO,
OLED_DISPLAY_WIDTH - 1,
SH1107_DISPLAY_START_LINE,
0x00,
CHARGE_PUMP,
0x14,
SH1107_MEMORY_MODE_PAGE,
};
if (I2C_TRANSMIT_P(display_setup1) != I2C_STATUS_SUCCESS) {
print("oled_init cmd set 1 failed\n");
return false;
}
if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_180)) {
static const uint8_t PROGMEM display_normal[] = {
I2C_CMD,
SEGMENT_REMAP_INV,
COM_SCAN_DEC,
DISPLAY_OFFSET,
OLED_COM_PIN_OFFSET,
};
if (I2C_TRANSMIT_P(display_normal) != I2C_STATUS_SUCCESS) {
print("oled_init cmd normal rotation failed\n");
return false;
}
} else {
static const uint8_t PROGMEM display_flipped[] = {
I2C_CMD,
SEGMENT_REMAP,
COM_SCAN_INC,
DISPLAY_OFFSET,
(OLED_COM_PIN_COUNT - OLED_COM_PIN_OFFSET) % OLED_COM_PIN_COUNT,
};
if (I2C_TRANSMIT_P(display_flipped) != I2C_STATUS_SUCCESS) {
print("display_flipped failed\n");
return false;
}
}
static const uint8_t PROGMEM display_setup2[] = {
I2C_CMD, COM_PINS,
OLED_COM_PINS,
CONTRAST, OLED_BRIGHTNESS,
PRE_CHARGE_PERIOD, 0x22,
VCOM_DETECT, 0x35,
DISPLAY_ALL_ON_RESUME,
NORMAL_DISPLAY,
DEACTIVATE_SCROLL,
DISPLAY_ON
};
if (I2C_TRANSMIT_P(display_setup2) != I2C_STATUS_SUCCESS) {
print("display_setup2 failed\n");
return false;
}
#if OLED_TIMEOUT > 0
oled_timeout = timer_read32() + OLED_TIMEOUT;
#endif
#if OLED_SCROLL_TIMEOUT > 0
oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT;
#endif
oled_clear();
oled_initialized = true;
oled_active = true;
oled_scrolling = false;
return true;
}
__attribute__((weak)) oled_rotation_t oled_init_kb(oled_rotation_t rotation) {
return rotation;
}
__attribute__((weak)) oled_rotation_t oled_init_user(oled_rotation_t rotation) {
return rotation;
}
void oled_clear(void) {
memset(oled_buffer, 0, sizeof(oled_buffer));
oled_cursor = &oled_buffer[0];
oled_dirty = OLED_ALL_BLOCKS_MASK;
}
static void calc_bounds(uint8_t update_start, uint8_t *cmd_array) {
// Calculate commands to set memory addressing bounds.
uint8_t start_page = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_WIDTH;
uint8_t start_column = OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_WIDTH;
// Commands for Page Addressing Mode. Sets starting page and column; has no end bound.
// Column value must be split into high and low nybble and sent as two commands.
cmd_array[0] = PAM_PAGE_ADDR | start_page;
cmd_array[1] = PAM_SETCOLUMN_LSB | ((OLED_COLUMN_OFFSET + start_column) & 0x0f);
cmd_array[2] = PAM_SETCOLUMN_MSB | ((OLED_COLUMN_OFFSET + start_column) >> 4 & 0x0f);
}
static void calc_bounds_90(uint8_t update_start, uint8_t *cmd_array) {
// Block numbering starts from the bottom left corner, going up and then to
// the right. The controller needs the page and column numbers for the top
// left and bottom right corners of that block.
// Total number of pages across the screen height.
const uint8_t height_in_pages = OLED_DISPLAY_HEIGHT / 8;
// Difference of starting page numbers for adjacent blocks; may be 0 if
// blocks are large enough to occupy one or more whole 8px columns.
const uint8_t page_inc_per_block = OLED_BLOCK_SIZE % OLED_DISPLAY_HEIGHT / 8;
// Top page number for a block which is at the bottom edge of the screen.
const uint8_t bottom_block_top_page = (height_in_pages - page_inc_per_block) % height_in_pages;
// Only the Page Addressing Mode is supported
uint8_t start_page = bottom_block_top_page - (OLED_BLOCK_SIZE * update_start % OLED_DISPLAY_HEIGHT / 8);
uint8_t start_column = OLED_BLOCK_SIZE * update_start / OLED_DISPLAY_HEIGHT * 8;
cmd_array[0] = PAM_PAGE_ADDR | start_page;
cmd_array[1] = PAM_SETCOLUMN_LSB | ((OLED_COLUMN_OFFSET + start_column) & 0x0f);
cmd_array[2] = PAM_SETCOLUMN_MSB | ((OLED_COLUMN_OFFSET + start_column) >> 4 & 0x0f);
}
uint8_t crot(uint8_t a, int8_t n) {
const uint8_t mask = 0x7;
n &= mask;
return a << n | a >> (-n & mask);
}
static void rotate_90(const uint8_t *src, uint8_t *dest) {
for (uint8_t i = 0, shift = 7; i < 8; ++i, --shift) {
uint8_t selector = (1 << i);
for (uint8_t j = 0; j < 8; ++j) {
dest[i] |= crot(src[j] & selector, shift - (int8_t)j);
}
}
}
void oled_render(void) {
// Do we have work to do?
oled_dirty &= OLED_ALL_BLOCKS_MASK;
if (!oled_dirty || !oled_initialized || oled_scrolling) {
return;
}
// Turn on display if it is off
oled_on();
uint8_t update_start = 0;
uint8_t num_processed = 0;
while (oled_dirty && num_processed++ < OLED_UPDATE_PROCESS_LIMIT) { // render all dirty blocks (up to the configured limit)
// Find next dirty block
while (!(oled_dirty & ((OLED_BLOCK_TYPE)1 << update_start))) {
++update_start;
}
// Set column & page position
static uint8_t display_start[] = {I2C_CMD, PAM_PAGE_ADDR, PAM_SETCOLUMN_LSB, PAM_SETCOLUMN_MSB};
if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
calc_bounds(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
} else {
calc_bounds_90(update_start, &display_start[1]); // Offset from I2C_CMD byte at the start
}
// Send column & page position
if (I2C_TRANSMIT(display_start) != I2C_STATUS_SUCCESS) {
print("oled_render offset command failed\n");
return;
}
if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
// Send render data chunk as is
if (I2C_WRITE_REG(I2C_DATA, &oled_buffer[OLED_BLOCK_SIZE * update_start], OLED_BLOCK_SIZE) != I2C_STATUS_SUCCESS) {
print("oled_render data failed\n");
return;
}
} else {
// Rotate the render chunks
const static uint8_t source_map[] = OLED_SOURCE_MAP;
const static uint8_t target_map[] = OLED_TARGET_MAP;
static uint8_t temp_buffer[OLED_BLOCK_SIZE];
memset(temp_buffer, 0, sizeof(temp_buffer));
for (uint8_t i = 0; i < sizeof(source_map); ++i) {
rotate_90(&oled_buffer[OLED_BLOCK_SIZE * update_start + source_map[i]], &temp_buffer[target_map[i]]);
}
// For SH1106 or SH1107 the data chunk must be split into separate pieces for each page
const uint8_t columns_in_block = (OLED_BLOCK_SIZE + OLED_DISPLAY_HEIGHT - 1) / OLED_DISPLAY_HEIGHT * 8;
const uint8_t num_pages = OLED_BLOCK_SIZE / columns_in_block;
for (uint8_t i = 0; i < num_pages; ++i) {
// Send column & page position for all pages except the first one
if (i > 0) {
display_start[1]++;
if (I2C_TRANSMIT(display_start) != I2C_STATUS_SUCCESS) {
print("oled_render offset command failed\n");
return;
}
}
// Send data for the page
if (I2C_WRITE_REG(I2C_DATA, &temp_buffer[columns_in_block * i], columns_in_block) != I2C_STATUS_SUCCESS) {
print("oled_render90 data failed\n");
return;
}
}
}
// Clear dirty flag
oled_dirty &= ~((OLED_BLOCK_TYPE)1 << update_start);
}
}
void oled_set_cursor(uint8_t col, uint8_t line) {
uint16_t index = line * oled_rotation_width + col * OLED_FONT_WIDTH;
// Out of bounds?
if (index >= OLED_MATRIX_SIZE) {
index = 0;
}
oled_cursor = &oled_buffer[index];
}
void oled_advance_page(bool clearPageRemainder) {
uint16_t index = oled_cursor - &oled_buffer[0];
uint8_t remaining = oled_rotation_width - (index % oled_rotation_width);
if (clearPageRemainder) {
// Remaining Char count
remaining = remaining / OLED_FONT_WIDTH;
// Write empty character until next line
while (remaining--)
oled_write_char(' ', false);
} else {
// Next page index out of bounds?
if (index + remaining >= OLED_MATRIX_SIZE) {
index = 0;
remaining = 0;
}
oled_cursor = &oled_buffer[index + remaining];
}
}
void oled_advance_char(void) {
uint16_t nextIndex = oled_cursor - &oled_buffer[0] + OLED_FONT_WIDTH;
uint8_t remainingSpace = oled_rotation_width - (nextIndex % oled_rotation_width);
// Do we have enough space on the current line for the next character
if (remainingSpace < OLED_FONT_WIDTH) {
nextIndex += remainingSpace;
}
// Did we go out of bounds
if (nextIndex >= OLED_MATRIX_SIZE) {
nextIndex = 0;
}
// Update cursor position
oled_cursor = &oled_buffer[nextIndex];
}
// Main handler that writes character data to the display buffer
void oled_write_char(const char data, bool invert) {
// Advance to the next line if newline
if (data == '\n') {
// Old source wrote ' ' until end of line...
oled_advance_page(true);
return;
}
if (data == '\r') {
oled_advance_page(false);
return;
}
// copy the current render buffer to check for dirty after
static uint8_t oled_temp_buffer[OLED_FONT_WIDTH];
memcpy(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH);
_Static_assert(sizeof(font) >= ((OLED_FONT_END + 1 - OLED_FONT_START) * OLED_FONT_WIDTH), "OLED_FONT_END references outside array");
// set the reder buffer data
uint8_t cast_data = (uint8_t)data; // font based on unsigned type for index
if (cast_data < OLED_FONT_START || cast_data > OLED_FONT_END) {
memset(oled_cursor, 0x00, OLED_FONT_WIDTH);
} else {
const uint8_t *glyph = &font[(cast_data - OLED_FONT_START) * OLED_FONT_WIDTH];
memcpy_P(oled_cursor, glyph, OLED_FONT_WIDTH);
}
// Invert if needed
if (invert) {
InvertCharacter(oled_cursor);
}
// Dirty check
if (memcmp(&oled_temp_buffer, oled_cursor, OLED_FONT_WIDTH)) {
uint16_t index = oled_cursor - &oled_buffer[0];
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (index / OLED_BLOCK_SIZE));
// Edgecase check if the written data spans the 2 chunks
oled_dirty |= ((OLED_BLOCK_TYPE)1 << ((index + OLED_FONT_WIDTH - 1) / OLED_BLOCK_SIZE));
}
// Finally move to the next char
oled_advance_char();
}
void oled_write(const char *data, bool invert) {
const char *end = data + strlen(data);
while (data < end) {
oled_write_char(*data, invert);
data++;
}
}
void oled_write_ln(const char *data, bool invert) {
oled_write(data, invert);
oled_advance_page(true);
}
void oled_pan(bool left) {
uint16_t i = 0;
for (uint16_t y = 0; y < OLED_DISPLAY_HEIGHT / 8; y++) {
if (left) {
for (uint16_t x = 0; x < OLED_DISPLAY_WIDTH - 1; x++) {
i = y * OLED_DISPLAY_WIDTH + x;
oled_buffer[i] = oled_buffer[i + 1];
}
} else {
for (uint16_t x = OLED_DISPLAY_WIDTH - 1; x > 0; x--) {
i = y * OLED_DISPLAY_WIDTH + x;
oled_buffer[i] = oled_buffer[i - 1];
}
}
}
oled_dirty = OLED_ALL_BLOCKS_MASK;
}
void oled_pan_section(bool left, uint16_t y_start, uint16_t y_end, uint16_t x_start, uint16_t x_end) {
uint16_t i = 0;
for (uint16_t y = y_start; y < y_end; y++) {
if (left) {
for (uint16_t x = x_start; x < x_end - 1; x++) {
i = y * OLED_DISPLAY_WIDTH + x;
oled_buffer[i] = oled_buffer[i + 1];
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
}
} else {
for (uint16_t x = x_end - 1; x > 0; x--) {
i = y * OLED_DISPLAY_WIDTH + x;
oled_buffer[i] = oled_buffer[i - 1];
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
}
}
}
}
oled_buffer_reader_t oled_read_raw(uint16_t start_index) {
if (start_index > OLED_MATRIX_SIZE) start_index = OLED_MATRIX_SIZE;
oled_buffer_reader_t ret_reader;
ret_reader.current_element = &oled_buffer[start_index];
ret_reader.remaining_element_count = OLED_MATRIX_SIZE - start_index;
return ret_reader;
}
void oled_write_raw_byte(const char data, uint16_t index) {
if (index > OLED_MATRIX_SIZE) index = OLED_MATRIX_SIZE;
if (oled_buffer[index] == data) return;
oled_buffer[index] = data;
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (index / OLED_BLOCK_SIZE));
}
void oled_write_raw(const char *data, uint16_t size) {
uint16_t cursor_start_index = oled_cursor - &oled_buffer[0];
if ((size + cursor_start_index) > OLED_MATRIX_SIZE) size = OLED_MATRIX_SIZE - cursor_start_index;
for (uint16_t i = cursor_start_index; i < cursor_start_index + size; i++) {
uint8_t c = *data++;
if (oled_buffer[i] == c) continue;
oled_buffer[i] = c;
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
}
}
void oled_write_pixel(uint8_t x, uint8_t y, bool on) {
if (x >= oled_rotation_width) {
return;
}
uint16_t index = x + (y / 8) * oled_rotation_width;
if (index >= OLED_MATRIX_SIZE) {
return;
}
uint8_t data = oled_buffer[index];
if (on) {
data |= (1 << (y % 8));
} else {
data &= ~(1 << (y % 8));
}
if (oled_buffer[index] != data) {
oled_buffer[index] = data;
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (index / OLED_BLOCK_SIZE));
}
}
#if defined(__AVR__)
void oled_write_P(const char *data, bool invert) {
uint8_t c = pgm_read_byte(data);
while (c != 0) {
oled_write_char(c, invert);
c = pgm_read_byte(++data);
}
}
void oled_write_ln_P(const char *data, bool invert) {
oled_write_P(data, invert);
oled_advance_page(true);
}
void oled_write_raw_P(const char *data, uint16_t size) {
uint16_t cursor_start_index = oled_cursor - &oled_buffer[0];
if ((size + cursor_start_index) > OLED_MATRIX_SIZE) size = OLED_MATRIX_SIZE - cursor_start_index;
for (uint16_t i = cursor_start_index; i < cursor_start_index + size; i++) {
uint8_t c = pgm_read_byte(data++);
if (oled_buffer[i] == c) continue;
oled_buffer[i] = c;
oled_dirty |= ((OLED_BLOCK_TYPE)1 << (i / OLED_BLOCK_SIZE));
}
}
#endif // defined(__AVR__)
bool oled_on(void) {
if (!oled_initialized) {
return oled_active;
}
#if OLED_TIMEOUT > 0
oled_timeout = timer_read32() + OLED_TIMEOUT;
#endif
static const uint8_t PROGMEM display_on[] =
#ifdef OLED_FADE_OUT
{I2C_CMD, FADE_BLINK, 0x00};
#else
{I2C_CMD, DISPLAY_ON};
#endif
if (!oled_active) {
if (I2C_TRANSMIT_P(display_on) != I2C_STATUS_SUCCESS) {
print("oled_on cmd failed\n");
return oled_active;
}
oled_active = true;
}
return oled_active;
}
bool oled_off(void) {
if (!oled_initialized) {
return !oled_active;
}
static const uint8_t PROGMEM display_off[] =
#ifdef OLED_FADE_OUT
{I2C_CMD, FADE_BLINK, ENABLE_FADE | OLED_FADE_OUT_INTERVAL};
#else
{I2C_CMD, DISPLAY_OFF};
#endif
if (oled_active) {
if (I2C_TRANSMIT_P(display_off) != I2C_STATUS_SUCCESS) {
print("oled_off cmd failed\n");
return oled_active;
}
oled_active = false;
}
return !oled_active;
}
bool is_oled_on(void) {
return oled_active;
}
uint8_t oled_set_brightness(uint8_t level) {
if (!oled_initialized) {
return oled_brightness;
}
uint8_t set_contrast[] = {I2C_CMD, CONTRAST, level};
if (oled_brightness != level) {
if (I2C_TRANSMIT(set_contrast) != I2C_STATUS_SUCCESS) {
print("set_brightness cmd failed\n");
return oled_brightness;
}
oled_brightness = level;
}
return oled_brightness;
}
uint8_t oled_get_brightness(void) {
return oled_brightness;
}
// Set the specific 8 lines rows of the screen to scroll.
// 0 is the default for start, and 7 for end, which is the entire
// height of the screen. For 128x32 screens, rows 4-7 are not used.
void oled_scroll_set_area(uint8_t start_line, uint8_t end_line) {
oled_scroll_start = start_line;
oled_scroll_end = end_line;
}
void oled_scroll_set_speed(uint8_t speed) {
// Sets the speed for scrolling... does not take effect
// until scrolling is either started or restarted
// the ssd1306 supports 8 speeds
// FrameRate2 speed = 7
// FrameRate3 speed = 4
// FrameRate4 speed = 5
// FrameRate5 speed = 0
// FrameRate25 speed = 6
// FrameRate64 speed = 1
// FrameRate128 speed = 2
// FrameRate256 speed = 3
// for ease of use these are remaped here to be in order
static const uint8_t scroll_remap[8] = {7, 4, 5, 0, 6, 1, 2, 3};
oled_scroll_speed = scroll_remap[speed];
}
bool oled_scroll_right(void) {
if (!oled_initialized) {
return oled_scrolling;
}
// Dont enable scrolling if we need to update the display
// This prevents scrolling of bad data from starting the scroll too early after init
if (!oled_dirty && !oled_scrolling) {
uint8_t display_scroll_right[] = {I2C_CMD, SCROLL_RIGHT, 0x00, oled_scroll_start, oled_scroll_speed, oled_scroll_end, 0x00, 0xFF, ACTIVATE_SCROLL};
if (I2C_TRANSMIT(display_scroll_right) != I2C_STATUS_SUCCESS) {
print("oled_scroll_right cmd failed\n");
return oled_scrolling;
}
oled_scrolling = true;
}
return oled_scrolling;
}
bool oled_scroll_left(void) {
if (!oled_initialized) {
return oled_scrolling;
}
// Dont enable scrolling if we need to update the display
// This prevents scrolling of bad data from starting the scroll too early after init
if (!oled_dirty && !oled_scrolling) {
uint8_t display_scroll_left[] = {I2C_CMD, SCROLL_LEFT, 0x00, oled_scroll_start, oled_scroll_speed, oled_scroll_end, 0x00, 0xFF, ACTIVATE_SCROLL};
if (I2C_TRANSMIT(display_scroll_left) != I2C_STATUS_SUCCESS) {
print("oled_scroll_left cmd failed\n");
return oled_scrolling;
}
oled_scrolling = true;
}
return oled_scrolling;
}
bool oled_scroll_off(void) {
if (!oled_initialized) {
return !oled_scrolling;
}
if (oled_scrolling) {
static const uint8_t PROGMEM display_scroll_off[] = {I2C_CMD, DEACTIVATE_SCROLL};
if (I2C_TRANSMIT_P(display_scroll_off) != I2C_STATUS_SUCCESS) {
print("oled_scroll_off cmd failed\n");
return oled_scrolling;
}
oled_scrolling = false;
oled_dirty = OLED_ALL_BLOCKS_MASK;
}
return !oled_scrolling;
}
bool is_oled_scrolling(void) {
return oled_scrolling;
}
bool oled_invert(bool invert) {
if (!oled_initialized) {
return oled_inverted;
}
if (invert && !oled_inverted) {
static const uint8_t PROGMEM display_inverted[] = {I2C_CMD, INVERT_DISPLAY};
if (I2C_TRANSMIT_P(display_inverted) != I2C_STATUS_SUCCESS) {
print("oled_invert cmd failed\n");
return oled_inverted;
}
oled_inverted = true;
} else if (!invert && oled_inverted) {
static const uint8_t PROGMEM display_normal[] = {I2C_CMD, NORMAL_DISPLAY};
if (I2C_TRANSMIT_P(display_normal) != I2C_STATUS_SUCCESS) {
print("oled_invert cmd failed\n");
return oled_inverted;
}
oled_inverted = false;
}
return oled_inverted;
}
uint8_t oled_max_chars(void) {
if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
return OLED_DISPLAY_WIDTH / OLED_FONT_WIDTH;
}
return OLED_DISPLAY_HEIGHT / OLED_FONT_WIDTH;
}
uint8_t oled_max_lines(void) {
if (!HAS_FLAGS(oled_rotation, OLED_ROTATION_90)) {
return OLED_DISPLAY_HEIGHT / OLED_FONT_HEIGHT;
}
return OLED_DISPLAY_WIDTH / OLED_FONT_HEIGHT;
}
void oled_task(void) {
if (!oled_initialized) {
return;
}
#if OLED_UPDATE_INTERVAL > 0
if (timer_elapsed(oled_update_timeout) >= OLED_UPDATE_INTERVAL) {
oled_update_timeout = timer_read();
oled_set_cursor(0, 0);
oled_task_kb();
}
#else
oled_set_cursor(0, 0);
oled_task_kbr();
#endif
#if OLED_SCROLL_TIMEOUT > 0
if (oled_dirty && oled_scrolling) {
oled_scroll_timeout = timer_read32() + OLED_SCROLL_TIMEOUT;
oled_scroll_off();
}
#endif
// Smart render system, no need to check for dirty
oled_render();
// Display timeout check
#if OLED_TIMEOUT > 0
if (oled_active && timer_expired32(timer_read32(), oled_timeout)) {
oled_off();
}
#endif
#if OLED_SCROLL_TIMEOUT > 0
if (!oled_scrolling && timer_expired32(timer_read32(), oled_scroll_timeout)) {
# ifdef OLED_SCROLL_TIMEOUT_RIGHT
oled_scroll_right();
# else
oled_scroll_left();
# endif
}
#endif
}
__attribute__((weak)) bool oled_task_kb(void) {
return oled_task_user();
}
__attribute__((weak)) bool oled_task_user(void) {
return true;
}

View file

@ -35,12 +35,11 @@ report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) {
mouse_report.y = 0;
if (x != 0 && y != 0 && (timer_elapsed(mouse_debounce_timer) > TAP_CHECK)) {
#ifdef OLED_ENABLE
oled_timer_reset();
#endif
if (enable_acceleration) {
x = (mouse_xy_report_t)(x > 0 ? pow(4, x) / 2 + x : -pow(4, abs(x)) / 2 + x);
y = (mouse_xy_report_t)(y > 0 ? pow(5, y) / 2 + y : -pow(5, abs(y)) / 2 + y);
float magnitude = sqrtf( mouse_report.x * mouse_report.x + mouse_report.y * mouse_report.y );
float adjusted_magnitude = powf(magnitude, 1.2f);
x = (mouse_xy_report_t)(x * adjusted_magnitude);
y = (mouse_xy_report_t)(y * adjusted_magnitude);
// x = (mouse_xy_report_t)(x > 0 ? x * x / 16 + x : -x * x / 16 + x);
// y = (mouse_xy_report_t)(y > 0 ? y * y / 16 + y : -y * y / 16 + y);
}
@ -56,6 +55,12 @@ bool process_record_pointing(uint16_t keycode, keyrecord_t* record) {
case KC_ACCEL:
enable_acceleration = record->event.pressed;
break;
#if defined(POINTING_DEVICE_MOUSE_JIGGLER_ENABLE)
case PD_JIGGLER:
if (record->event.pressed) {
pointing_device_mouse_jiggler_toggle();
}
#endif
default:
mouse_debounce_timer = timer_read();
break;
@ -73,6 +78,24 @@ layer_state_t layer_state_set_pointing(layer_state_t state) {
return state;
}
#if defined(POINTING_DEVICE_MOUSE_JIGGLER_ENABLE)
static uint16_t mouse_jiggler_timer;
bool has_mouse_report_changed(report_mouse_t* new_report, report_mouse_t* old_report) {
// Only report every 5 seconds.
if (userspace_config.mouse_jiggler && timer_elapsed(mouse_jiggler_timer) > 5000) {
mouse_jiggler_timer = timer_read();
return true;
}
return memcmp(new_report, old_report, sizeof(report_mouse_t));
}
void pointing_device_mouse_jiggler_toggle(void) {
mouse_jiggler_timer = timer_read();
userspace_config.mouse_jiggler = !userspace_config.mouse_jiggler;
}
#endif
#if defined(POINTING_DEVICE_AUTO_MOUSE_ENABLE)
__attribute__((weak)) bool is_mouse_record_keymap(uint16_t keycode, keyrecord_t *record) { return false; }

View file

@ -8,3 +8,4 @@ report_mouse_t pointing_device_task_keymap(report_mouse_t mouse_report);
void matrix_scan_pointing(void);
bool process_record_pointing(uint16_t keycode, keyrecord_t* record);
layer_state_t layer_state_set_pointing(layer_state_t state);
void pointing_device_mouse_jiggler_toggle(void);

View file

@ -121,7 +121,7 @@
# ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS
# define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8
# endif
#endif // MOUSEKEY_ENABLE
#endif // MOUSEKEY_ENABLE
#define MOUSE_EXTENDED_REPORT
@ -134,7 +134,7 @@
#endif
#if defined(SPLIT_KEYBOARD) && defined(PROTOCOL_CHIBIOS) && !defined(USB_SUSPEND_WAKEUP_DELAY)
# define USB_SUSPEND_WAKEUP_DELAY 200
# define USB_SUSPEND_WAKEUP_DELAY 500
#endif
#if defined(XAP_ENABLE) && !defined(__AVR__)

View file

@ -6,7 +6,7 @@
#define RGB_MATRIX_KEYPRESSES // reacts to keypresses (will slow down matrix scan by a lot)
// # define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (not recommened)
#define RGB_MATRIX_FRAMEBUFFER_EFFECTS
// # define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
#define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended
#undef ENABLE_RGB_MATRIX_ALPHAS_MODS
#undef ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN

View file

@ -74,7 +74,7 @@ bool process_record_user_rgb_matrix(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
userspace_config.rgb_matrix_idle_anim ^= 1;
dprintf("RGB Matrix Idle Animation [EEPROM]: %u\n", userspace_config.rgb_matrix_idle_anim);
eeconfig_update_user(userspace_config.raw);
eeconfig_update_user_config(&userspace_config.raw);
if (userspace_config.rgb_matrix_idle_anim) {
rgb_matrix_mode_noeeprom(RGB_MATRIX_TYPING_HEATMAP);
}
@ -146,3 +146,45 @@ __attribute__((weak)) bool rgb_matrix_indicators_keymap(void) {
bool rgb_matrix_indicators_user(void) {
return rgb_matrix_indicators_keymap();
}
//----------------------------------------------------------
// RGB Matrix naming
#include <rgb_matrix.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";
}
}

View file

@ -13,3 +13,5 @@ void rgb_matrix_layer_helper(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode
bool rgb_matrix_indicators_advanced_keymap(uint8_t led_min, uint8_t led_max);
bool rgb_matrix_indicators_keymap(void);
const char* rgb_matrix_name(uint8_t effect);

View file

@ -11,6 +11,9 @@ void rgblight_sethsv_default_helper(uint8_t index) {
rgblight_sethsv_at(rgblight_get_hue(), rgblight_get_sat(), rgblight_get_val(), index);
}
void rgblight_set_hsv_and_mode(uint8_t hue, uint8_t sat, uint8_t val, uint8_t mode) {
if (val > RGBLIGHT_LIMIT_VAL) {
val = RGBLIGHT_LIMIT_VAL;
}
rgblight_sethsv_noeeprom(hue, sat, val);
// wait_us(175); // Add a slight delay between color and mode to ensure it's processed correctly
rgblight_mode_noeeprom(mode);
@ -48,6 +51,15 @@ uint32_t rgb_startup_animation(uint32_t triger_time, void *cb_arg) {
}
#endif
bool is_rgblight_startup_running(void) {
#if defined(RGBLIGHT_STARTUP_ANIMATION)
return is_rgblight_startup && is_keyboard_master();
#else
return false;
#endif
}
void keyboard_post_init_rgb_light(void) {
#if defined(RGBLIGHT_STARTUP_ANIMATION)
is_enabled = rgblight_is_enabled();
@ -121,3 +133,33 @@ layer_state_t default_layer_state_set_rgb_light(layer_state_t state) {
}
return state;
}
#define _RGBM_SINGLE_STATIC(sym) \
case RGBLIGHT_MODE_##sym: \
return #sym;
#define _RGBM_SINGLE_DYNAMIC(sym) \
case RGBLIGHT_MODE_##sym: \
return #sym;
#define _RGBM_MULTI_STATIC(sym) \
case RGBLIGHT_MODE_##sym: \
return #sym;
#define _RGBM_MULTI_DYNAMIC(sym) \
case RGBLIGHT_MODE_##sym: \
return #sym;
#define _RGBM_TMP_STATIC(sym, msym) \
case RGBLIGHT_MODE_##sym: \
return #msym;
#define _RGBM_TMP_DYNAMIC(sym, msym) \
case RGBLIGHT_MODE_##sym: \
return #msym;
const char* rgblight_name(uint8_t effect) {
switch (effect) {
#include "rgblight_modes.h"
case 0:
return "Off";
default:
return "UNKNOWN";
}
}

View file

@ -10,3 +10,6 @@ void matrix_scan_rgb_light(void);
layer_state_t layer_state_set_rgb_light(layer_state_t state);
layer_state_t default_layer_state_set_rgb_light(layer_state_t state);
void rgblight_sethsv_default_helper(uint8_t index);
const char* rgblight_name(uint8_t effect);
bool is_rgblight_startup_running(void);

View file

@ -1,11 +1,21 @@
SRC += $(USER_PATH)/drashna.c \
$(USER_PATH)/callbacks.c \
$(USER_PATH)/keyrecords/process_records.c \
$(USER_PATH)/keyrecords/tapping.c
$(USER_PATH)/keyrecords/tapping.c \
$(USER_PATH)/eeconfig_users.c
# TOP_SYMBOLS = yes
ifneq ($(PLATFORM),CHIBIOS)
DEBOUNCE_TYPE = asym_eager_defer_pk
DEFERRED_EXEC_ENABLE = yes
OS_DETECTION_ENABLE = yes
ifeq ($(PLATFORM),CHIBIOS)
# cortex-m4 has DSP+FPU support, so use hack to enable it for lib8tion
ifeq ($(strip $(MCU)), cortex-m4)
OPT_DEFS += -DFASTLED_TEENSY3
endif
else
ifneq ($(strip $(LTO_SUPPORTED)), no)
LTO_ENABLE = yes
endif
@ -14,16 +24,7 @@ ifneq ($(PLATFORM),CHIBIOS)
endif
# DEBUG_MATRIX_SCAN_RATE_ENABLE = api
ifneq ($(strip $(NO_SECRETS)), yes)
ifneq ("$(wildcard $(USER_PATH)/../../../qmk_secrets/secrets.c)","")
SRC += $(USER_PATH)/../../../qmk_secrets/secrets.c
$(shell touch $(USER_PATH)/../../../qmk_secrets/secrets.c)
SECURE_ENABLE = yes
endif
ifeq ($(strip $(NO_SECRETS)), lite)
OPT_DEFS += -DNO_SECRETS
endif
endif
-include $(USER_PATH)/../../../qmk_secrets/rules.mk
ifeq ($(strip $(MAKE_BOOTLOADER)), yes)
OPT_DEFS += -DMAKE_BOOTLOADER
@ -67,7 +68,6 @@ ifeq ($(strip $(RGBLIGHT_ENABLE)), yes)
endif
ifeq ($(strip $(RGBLIGHT_STARTUP_ANIMATION)), yes)
OPT_DEFS += -DRGBLIGHT_STARTUP_ANIMATION
DEFERRED_EXEC_ENABLE = yes
endif
endif
endif
@ -92,23 +92,7 @@ ifeq ($(strip $(I2C_SCANNER_ENABLE)), yes)
CONSOLE_ENABLE := yes
endif
CUSTOM_OLED_DRIVER ?= yes
ifeq ($(strip $(OLED_ENABLE)), yes)
ifeq ($(strip $(OLED_DRIVER)), custom)
OPT_DEFS += -DOLED_ENABLE \
-DOLED_DRIVER_SH1107
SRC += $(USER_PATH)/oled/sh110x.c
QUANTUM_LIB_SRC += i2c_master.c
endif
ifeq ($(strip $(CUSTOM_OLED_DRIVER)), yes)
OPT_DEFS += -DCUSTOM_OLED_DRIVER
SRC += $(USER_PATH)/oled/oled_stuff.c
endif
ifeq ($(strip $(OLED_DISPLAY_TEST)), yes)
OPT_DEFS += -DOLED_DISPLAY_TEST
endif
DEFERRED_EXEC_ENABLE = yes
endif
-include $(USER_PATH)/oled/rules.mk
CUSTOM_POINTING_DEVICE ?= yes
ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
@ -117,6 +101,10 @@ ifeq ($(strip $(POINTING_DEVICE_ENABLE)), yes)
OPT_DEFS += -DCUSTOM_POINTING_DEVICE
OPT_DEFS += -DPOINTING_DEVICE_AUTO_MOUSE_ENABLE
endif
POINTING_DEVICE_MOUSE_JIGGLER_ENABLE ?= yes
ifeq ($(strip $(POINTING_DEVICE_MOUSE_JIGGLER_ENABLE)), yes)
OPT_DEFS += -DPOINTING_DEVICE_MOUSE_JIGGLER_ENABLE
endif
endif
CUSTOM_SPLIT_TRANSPORT_SYNC ?= yes
@ -128,10 +116,6 @@ ifeq ($(strip $(CUSTOM_SPLIT_TRANSPORT_SYNC)), yes)
endif
ifeq ($(strip $(AUTOCORRECTION_ENABLE)), yes)
AUTOCORRECT_ENABLE = yes
endif
CUSTOM_BOOTMAGIC_ENABLE ?= yes
ifeq ($(strip $(CUSTOM_BOOTMAGIC_ENABLE)), yes)
ifeq ($(strip $(BOOTMAGIC_ENABLE)), yes)
@ -139,7 +123,14 @@ ifeq ($(strip $(CUSTOM_BOOTMAGIC_ENABLE)), yes)
endif
endif
OS_DETECTION_ENABLE ?= yes
ifeq ($(strip $(OS_DETECTION_ENABLE)), yes)
DEFERRED_EXEC_ENABLE = yes
CUSTOM_DYNAMIC_MACROS_ENABLE ?= no
ifeq ($(strip $(CUSTOM_DYNAMIC_MACROS_ENABLE)), yes)
SRC += $(USER_PATH)/keyrecords/dynamic_macros.c
OPT_DEFS += -DCUSTOM_DYNAMIC_MACROS_ENABLE
endif
ifeq ($(strip $(HARDWARE_DEBUG_ENABLE)), yes)
LTO_ENABLE := no
OPT := 0
OPT_DEFS += -g
endif

View file

@ -9,6 +9,9 @@
#define SPLIT_MODS_ENABLE
#define SPLIT_WATCHDOG_ENABLE
#define SPLIT_WPM_ENABLE
#define SPLIT_ACTIVITY_ENABLE
#define SPLIT_DETECTED_OS_ENABLE
#define SPLIT_HAPTIC_ENABLE
#ifdef SPLIT_OLED_ENABLE
# undef SPLIT_OLED_ENABLE
#endif
@ -16,5 +19,8 @@
# define SELECT_SOFT_SERIAL_SPEED 1
#endif
#ifdef CUSTOM_SPLIT_TRANSPORT_SYNC
# define SPLIT_TRANSACTION_IDS_USER RPC_ID_USER_STATE_SYNC, RPC_ID_USER_KEYMAP_SYNC, RPC_ID_USER_CONFIG_SYNC, RPC_ID_USER_PLACEHOLDER, RPC_ID_USER_KEYLOG_STR
# define SPLIT_TRANSACTION_IDS_USER RPC_ID_USER_STATE_SYNC, RPC_ID_USER_KEYMAP_SYNC, RPC_ID_USER_CONFIG_SYNC, RPC_ID_USER_PLACEHOLDER, RPC_ID_USER_OLED_KEYLOG_STR
#endif
#define CRC8_USE_TABLE
#define CRC8_OPTIMIZE_SPEED

View file

@ -15,9 +15,6 @@ extern unicode_config_t unicode_config;
extern audio_config_t audio_config;
extern bool delayed_tasks_run;
#endif
#if defined(OLED_ENABLE) && !defined(SPLIT_OLED_ENABLE) && defined(CUSTOM_OLED_DRIVER)
extern bool is_oled_enabled;
#endif
#if defined(POINTING_DEVICE_ENABLE) && defined(KEYBOARD_handwired_tractyl_manuform)
extern bool tap_toggling;
#endif
@ -26,7 +23,6 @@ extern bool swap_hands;
#endif
extern userspace_config_t userspace_config;
extern bool host_driver_disabled;
uint16_t transport_keymap_config = 0;
uint32_t transport_userspace_config = 0, transport_user_state = 0;
@ -52,8 +48,8 @@ void user_config_sync(uint8_t initiator2target_buffer_size, const void* initiato
#ifdef CUSTOM_OLED_DRIVER
# include "oled/oled_stuff.h"
void keylogger_string_sync(uint8_t initiator2target_buffer_size, const void* initiator2target_buffer, uint8_t target2initiator_buffer_size, void* target2initiator_buffer) {
if (initiator2target_buffer_size == (OLED_KEYLOGGER_LENGTH)) {
memcpy(&keylog_str, initiator2target_buffer, initiator2target_buffer_size);
if (initiator2target_buffer_size == (OLED_KEYLOGGER_LENGTH+1)) {
memcpy(&oled_keylog_str, initiator2target_buffer, initiator2target_buffer_size);
}
}
#endif
@ -64,7 +60,7 @@ void keyboard_post_init_transport_sync(void) {
transaction_register_rpc(RPC_ID_USER_KEYMAP_SYNC, user_keymap_sync);
transaction_register_rpc(RPC_ID_USER_CONFIG_SYNC, user_config_sync);
#ifdef CUSTOM_OLED_DRIVER
transaction_register_rpc(RPC_ID_USER_KEYLOG_STR, keylogger_string_sync);
transaction_register_rpc(RPC_ID_USER_OLED_KEYLOG_STR, keylogger_string_sync);
#endif
}
@ -76,9 +72,6 @@ void user_transport_update(void) {
user_state.audio_enable = is_audio_on();
user_state.audio_clicky_enable = is_clicky_on();
#endif
#if defined(OLED_ENABLE) && !defined(SPLIT_OLED_ENABLE) && defined(CUSTOM_OLED_DRIVER)
user_state.is_oled_enabled = is_oled_enabled;
#endif
#if defined(POINTING_DEVICE_ENABLE) && defined(POINTING_DEVICE_AUTO_MOUSE_ENABLE)
user_state.tap_toggling = get_auto_mouse_toggle();
#endif
@ -89,7 +82,7 @@ void user_transport_update(void) {
#ifdef SWAP_HANDS_ENABLE
user_state.swap_hands = swap_hands;
#endif
user_state.host_driver_disabled = host_driver_disabled;
user_state.host_driver_disabled = get_keyboard_lock();
transport_user_state = user_state.raw;
} else {
@ -100,9 +93,6 @@ void user_transport_update(void) {
unicode_config.input_mode = user_state.unicode_mode;
unicode_typing_mode = user_state.unicode_typing_mode;
#endif
#if defined(OLED_ENABLE) && !defined(SPLIT_OLED_ENABLE) && defined(CUSTOM_OLED_DRIVER)
is_oled_enabled = user_state.is_oled_enabled;
#endif
#if defined(POINTING_DEVICE_ENABLE) && defined(POINTING_DEVICE_AUTO_MOUSE_ENABLE)
if (get_auto_mouse_toggle() != user_state.tap_toggling) {
auto_mouse_toggle();
@ -111,7 +101,7 @@ void user_transport_update(void) {
#ifdef SWAP_HANDS_ENABLE
swap_hands = user_state.swap_hands;
#endif
host_driver_disabled = user_state.host_driver_disabled;
set_keyboard_lock(user_state.host_driver_disabled);
}
}
@ -122,7 +112,7 @@ void user_transport_sync(void) {
static uint32_t last_config = 0, last_sync[4], last_user_state = 0;
bool needs_sync = false;
#ifdef CUSTOM_OLED_DRIVER
static char keylog_temp[OLED_KEYLOGGER_LENGTH] = {0};
static char keylog_temp[OLED_KEYLOGGER_LENGTH + 1] = {0};
#endif
// Check if the state values are different
@ -183,9 +173,9 @@ void user_transport_sync(void) {
#ifdef CUSTOM_OLED_DRIVER
// Check if the state values are different
if (memcmp(&keylog_str, &keylog_temp, OLED_KEYLOGGER_LENGTH)) {
if (memcmp(&oled_keylog_str, &keylog_temp, OLED_KEYLOGGER_LENGTH + 1)) {
needs_sync = true;
memcpy(&keylog_temp, &keylog_str, OLED_KEYLOGGER_LENGTH);
memcpy(&keylog_temp, &oled_keylog_str, OLED_KEYLOGGER_LENGTH + 1);
}
if (timer_elapsed32(last_sync[3]) > 250) {
needs_sync = true;
@ -193,7 +183,7 @@ void user_transport_sync(void) {
// Perform the sync if requested
if (needs_sync) {
if (transaction_rpc_send(RPC_ID_USER_KEYLOG_STR, OLED_KEYLOGGER_LENGTH, &keylog_str)) {
if (transaction_rpc_send(RPC_ID_USER_OLED_KEYLOG_STR, OLED_KEYLOGGER_LENGTH + 1, &oled_keylog_str)) {
last_sync[3] = timer_read32();
}
needs_sync = false;

View file

@ -6,7 +6,6 @@
#include "drashna.h"
#ifdef OLED_ENABLE
# include "oled/oled_stuff.h"
extern char keylog_str[];
#endif
typedef union {