From 3a3e5abac992712a8bb4e9b61430f5fc62dc6043 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Wed, 31 May 2023 11:44:06 -0700 Subject: [Keymap] Drashna Keymap updates for 0.21.0 (#21073) --- users/drashna/bootmagic_better.c | 2 +- users/drashna/callbacks.c | 107 ++-- users/drashna/config.h | 21 +- users/drashna/drashna.c | 114 +++- users/drashna/drashna.h | 28 +- users/drashna/eeconfig_users.c | 53 ++ users/drashna/eeconfig_users.h | 12 + users/drashna/keyrecords/dynamic_macros.c | 283 ++++++++++ users/drashna/keyrecords/dynamic_macros.h | 50 ++ users/drashna/keyrecords/process_records.c | 68 +-- users/drashna/keyrecords/process_records.h | 88 +-- users/drashna/keyrecords/tapping.c | 5 + users/drashna/keyrecords/unicode.c | 10 + users/drashna/keyrecords/unicode.h | 1 + users/drashna/keyrecords/wrappers.h | 2 +- users/drashna/oled/drashna_font.h | 394 +------------ users/drashna/oled/oled_assets.h | 207 +++++++ users/drashna/oled/oled_config.h | 33 +- users/drashna/oled/oled_stuff.c | 421 +++++--------- users/drashna/oled/oled_stuff.h | 7 +- users/drashna/oled/rules.mk | 12 + users/drashna/oled/sh110x.c | 860 ----------------------------- users/drashna/pointing/pointing.c | 33 +- users/drashna/pointing/pointing.h | 1 + users/drashna/post_config.h | 4 +- users/drashna/rgb/rgb_matrix_config.h | 2 +- users/drashna/rgb/rgb_matrix_stuff.c | 44 +- users/drashna/rgb/rgb_matrix_stuff.h | 2 + users/drashna/rgb/rgb_stuff.c | 42 ++ users/drashna/rgb/rgb_stuff.h | 3 + users/drashna/rules.mk | 65 +-- users/drashna/split/split_config.h | 8 +- users/drashna/split/transport_sync.c | 28 +- users/drashna/split/transport_sync.h | 1 - 34 files changed, 1253 insertions(+), 1758 deletions(-) create mode 100644 users/drashna/eeconfig_users.c create mode 100644 users/drashna/eeconfig_users.h create mode 100644 users/drashna/keyrecords/dynamic_macros.c create mode 100644 users/drashna/keyrecords/dynamic_macros.h create mode 100644 users/drashna/oled/oled_assets.h create mode 100644 users/drashna/oled/rules.mk delete mode 100644 users/drashna/oled/sh110x.c (limited to 'users') diff --git a/users/drashna/bootmagic_better.c b/users/drashna/bootmagic_better.c index ffd2e609ae..fa1078e37d 100644 --- a/users/drashna/bootmagic_better.c +++ b/users/drashna/bootmagic_better.c @@ -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 diff --git a/users/drashna/callbacks.c b/users/drashna/callbacks.c index 568f56c8d1..cab7e5278f 100644 --- a/users/drashna/callbacks.c +++ b/users/drashna/callbacks.c @@ -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) { diff --git a/users/drashna/config.h b/users/drashna/config.h index b4aa1283eb..ec9bbf1afb 100644 --- a/users/drashna/config.h +++ b/users/drashna/config.h @@ -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 diff --git a/users/drashna/drashna.c b/users/drashna/drashna.c index 259810c70f..cad6db8f3d 100644 --- a/users/drashna/drashna.c +++ b/users/drashna/drashna.c @@ -2,6 +2,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "drashna.h" +#include +#include 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"; + } +} diff --git a/users/drashna/drashna.h b/users/drashna/drashna.h index 4e2a4d5acb..49cdf6ca21 100644 --- a/users/drashna/drashna.h +++ b/users/drashna/drashna.h @@ -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); diff --git a/users/drashna/eeconfig_users.c b/users/drashna/eeconfig_users.c new file mode 100644 index 0000000000..8e0f1f10b6 --- /dev/null +++ b/users/drashna/eeconfig_users.c @@ -0,0 +1,53 @@ +// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "eeconfig_users.h" +#include "eeprom.h" +#include "eeconfig.h" +#include + +#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 +} diff --git a/users/drashna/eeconfig_users.h b/users/drashna/eeconfig_users.h new file mode 100644 index 0000000000..c9b230df9c --- /dev/null +++ b/users/drashna/eeconfig_users.h @@ -0,0 +1,12 @@ +// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +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); diff --git a/users/drashna/keyrecords/dynamic_macros.c b/users/drashna/keyrecords/dynamic_macros.c new file mode 100644 index 0000000000..43c2336cb6 --- /dev/null +++ b/users/drashna/keyrecords/dynamic_macros.c @@ -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) +// 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 + +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(); +} diff --git a/users/drashna/keyrecords/dynamic_macros.h b/users/drashna/keyrecords/dynamic_macros.h new file mode 100644 index 0000000000..5eefb9b268 --- /dev/null +++ b/users/drashna/keyrecords/dynamic_macros.h @@ -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) +// 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); diff --git a/users/drashna/keyrecords/process_records.c b/users/drashna/keyrecords/process_records.c index 99d95c3dff..d8d45dcac9 100644 --- a/users/drashna/keyrecords/process_records.c +++ b/users/drashna/keyrecords/process_records.c @@ -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); } diff --git a/users/drashna/keyrecords/process_records.h b/users/drashna/keyrecords/process_records.h index 8073b7adb0..0137976580 100644 --- a/users/drashna/keyrecords/process_records.h +++ b/users/drashna/keyrecords/process_records.h @@ -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 diff --git a/users/drashna/keyrecords/tapping.c b/users/drashna/keyrecords/tapping.c index 6a26a02aca..d4a0e16112 100644 --- a/users/drashna/keyrecords/tapping.c +++ b/users/drashna/keyrecords/tapping.c @@ -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; } diff --git a/users/drashna/keyrecords/unicode.c b/users/drashna/keyrecords/unicode.c index 16390074ca..a4687d3e59 100644 --- a/users/drashna/keyrecords/unicode.c +++ b/users/drashna/keyrecords/unicode.c @@ -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); +} diff --git a/users/drashna/keyrecords/unicode.h b/users/drashna/keyrecords/unicode.h index 43c2db89c0..fe95e78c3a 100644 --- a/users/drashna/keyrecords/unicode.h +++ b/users/drashna/keyrecords/unicode.h @@ -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); diff --git a/users/drashna/keyrecords/wrappers.h b/users/drashna/keyrecords/wrappers.h index 31efad5f6e..b298ef0628 100644 --- a/users/drashna/keyrecords/wrappers.h +++ b/users/drashna/keyrecords/wrappers.h @@ -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 diff --git a/users/drashna/oled/drashna_font.h b/users/drashna/oled/drashna_font.h index 7ba03c4c13..cef1fc4969 100644 --- a/users/drashna/oled/drashna_font.h +++ b/users/drashna/oled/drashna_font.h @@ -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,139 +916,27 @@ 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -#endif // First icon section 0xE0, 0xF0, 0xF0, 0xF0, 0xE0, 0xEC, @@ -1071,272 +952,49 @@ 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 - -// second icon section - 0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F, - 0x7F, 0x7F, 0x3F, 0x1E, 0x0C, 0x00, - 0x1F, 0x1F, 0x1F, 0x3F, 0x00, 0x3F, - 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00, - 0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20, - 0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00, - 0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F, - 0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00, - 0x00, 0x44, 0x28, 0xFF, 0x5A, 0x24, - 0xF0, 0xFE, 0xF1, 0x91, 0xF6, 0xF0, - 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, + +// second icon section + 0x0F, 0x1F, 0x3F, 0x7F, 0x7F, 0x7F, + 0x7F, 0x7F, 0x3F, 0x1E, 0x0C, 0x00, + 0x1F, 0x1F, 0x1F, 0x3F, 0x00, 0x3F, + 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x00, + 0x30, 0x7B, 0x7F, 0x78, 0x30, 0x20, + 0x20, 0x30, 0x78, 0x7F, 0x3B, 0x00, + 0x03, 0x00, 0x0F, 0x7F, 0x0F, 0x0F, + 0x0F, 0x7F, 0x0F, 0x00, 0x03, 0x00, + 0x00, 0x44, 0x28, 0xFF, 0x5A, 0x24, + 0xF0, 0xFE, 0xF1, 0x91, 0xF6, 0xF0, + 0xF0, 0xFC, 0xF2, 0x92, 0xFC, 0xF0, + +// bottom logo section + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 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 +1009,6 @@ 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 // 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 diff --git a/users/drashna/oled/oled_assets.h b/users/drashna/oled/oled_assets.h new file mode 100644 index 0000000000..36dfc7762c --- /dev/null +++ b/users/drashna/oled/oled_assets.h @@ -0,0 +1,207 @@ +// Copyright 2023 Christopher Courtney, aka Drashna Jael're (@drashna) +// 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 } + } +}; diff --git a/users/drashna/oled/oled_config.h b/users/drashna/oled/oled_config.h index c46c0c39ce..427764c4a7 100644 --- a/users/drashna/oled/oled_config.h +++ b/users/drashna/oled/oled_config.h @@ -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 diff --git a/users/drashna/oled/oled_stuff.c b/users/drashna/oled/oled_stuff.c index 98506247df..d232e90fb2 100644 --- a/users/drashna/oled/oled_stuff.c +++ b/users/drashna/oled/oled_stuff.c @@ -16,6 +16,10 @@ */ #include "drashna.h" +#include +#include +#include +#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 -bool is_oled_enabled = true, is_oled_locked = false; +#ifndef OLED_BRIGHTNESS_STEP +# define OLED_BRIGHTNESS_STEP 32 +#endif -extern bool host_driver_disabled; +bool is_oled_enabled = true, is_oled_locked = false, is_oled_force_off = false; -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}; -#endif +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,12 +456,51 @@ 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) { @@ -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); + } } diff --git a/users/drashna/oled/oled_stuff.h b/users/drashna/oled/oled_stuff.h index 419cdc11eb..414720ff2a 100644 --- a/users/drashna/oled/oled_stuff.h +++ b/users/drashna/oled/oled_stuff.h @@ -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 diff --git a/users/drashna/oled/rules.mk b/users/drashna/oled/rules.mk new file mode 100644 index 0000000000..95be67a9ef --- /dev/null +++ b/users/drashna/oled/rules.mk @@ -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 diff --git a/users/drashna/oled/sh110x.c b/users/drashna/oled/sh110x.c deleted file mode 100644 index f96a93a897..0000000000 --- a/users/drashna/oled/sh110x.c +++ /dev/null @@ -1,860 +0,0 @@ -/* -Copyright 2019 Ryan Caltabiano - -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 . -*/ -#include "i2c_master.h" -#include "oled_driver.h" -#include OLED_FONT_H -#include "timer.h" -#include "print.h" - -#include - -#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; -} diff --git a/users/drashna/pointing/pointing.c b/users/drashna/pointing/pointing.c index 18dad0da81..82cc5a3aa6 100644 --- a/users/drashna/pointing/pointing.c +++ b/users/drashna/pointing/pointing.c @@ -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; } diff --git a/users/drashna/pointing/pointing.h b/users/drashna/pointing/pointing.h index 28d8610148..c97ce5b2db 100644 --- a/users/drashna/pointing/pointing.h +++ b/users/drashna/pointing/pointing.h @@ -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); diff --git a/users/drashna/post_config.h b/users/drashna/post_config.h index 85ce0e3108..5a2dfb6637 100644 --- a/users/drashna/post_config.h +++ b/users/drashna/post_config.h @@ -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__) diff --git a/users/drashna/rgb/rgb_matrix_config.h b/users/drashna/rgb/rgb_matrix_config.h index 86f238f392..bc2c04d981 100644 --- a/users/drashna/rgb/rgb_matrix_config.h +++ b/users/drashna/rgb/rgb_matrix_config.h @@ -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 diff --git a/users/drashna/rgb/rgb_matrix_stuff.c b/users/drashna/rgb/rgb_matrix_stuff.c index eff9191eb7..588e51daf9 100644 --- a/users/drashna/rgb/rgb_matrix_stuff.c +++ b/users/drashna/rgb/rgb_matrix_stuff.c @@ -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 + +#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"; + } +} diff --git a/users/drashna/rgb/rgb_matrix_stuff.h b/users/drashna/rgb/rgb_matrix_stuff.h index 9559134c8c..80770bf40f 100644 --- a/users/drashna/rgb/rgb_matrix_stuff.h +++ b/users/drashna/rgb/rgb_matrix_stuff.h @@ -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); diff --git a/users/drashna/rgb/rgb_stuff.c b/users/drashna/rgb/rgb_stuff.c index c283e58d26..cc85425aff 100644 --- a/users/drashna/rgb/rgb_stuff.c +++ b/users/drashna/rgb/rgb_stuff.c @@ -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"; + } +} diff --git a/users/drashna/rgb/rgb_stuff.h b/users/drashna/rgb/rgb_stuff.h index d720275b60..f76c591e03 100644 --- a/users/drashna/rgb/rgb_stuff.h +++ b/users/drashna/rgb/rgb_stuff.h @@ -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); diff --git a/users/drashna/rules.mk b/users/drashna/rules.mk index 43186b024a..6287d6e78c 100644 --- a/users/drashna/rules.mk +++ b/users/drashna/rules.mk @@ -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 diff --git a/users/drashna/split/split_config.h b/users/drashna/split/split_config.h index 17daa4f808..fd8bf95515 100644 --- a/users/drashna/split/split_config.h +++ b/users/drashna/split/split_config.h @@ -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 diff --git a/users/drashna/split/transport_sync.c b/users/drashna/split/transport_sync.c index bd6f7c5688..d5a1241586 100644 --- a/users/drashna/split/transport_sync.c +++ b/users/drashna/split/transport_sync.c @@ -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; diff --git a/users/drashna/split/transport_sync.h b/users/drashna/split/transport_sync.h index e27e598f83..d241e5446f 100644 --- a/users/drashna/split/transport_sync.h +++ b/users/drashna/split/transport_sync.h @@ -6,7 +6,6 @@ #include "drashna.h" #ifdef OLED_ENABLE # include "oled/oled_stuff.h" -extern char keylog_str[]; #endif typedef union { -- cgit v1.2.3