diff options
Diffstat (limited to 'keyboards/adpenrose/akemipad/keymaps/oled_bongocat/animation_process.h')
-rw-r--r-- | keyboards/adpenrose/akemipad/keymaps/oled_bongocat/animation_process.h | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/keyboards/adpenrose/akemipad/keymaps/oled_bongocat/animation_process.h b/keyboards/adpenrose/akemipad/keymaps/oled_bongocat/animation_process.h new file mode 100644 index 0000000000..4280574a46 --- /dev/null +++ b/keyboards/adpenrose/akemipad/keymaps/oled_bongocat/animation_process.h @@ -0,0 +1,97 @@ +// Copyright 2022 Arturo Avila (@ADPenrose) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H +#include "animation_frames.h" + +#ifdef OLED_ENABLE +#define IDLE_FRAME_DURATION 200 // Idle animation iteration rate in ms + +oled_rotation_t oled_init_user(oled_rotation_t rotation) { return OLED_ROTATION_270; } + +uint32_t anim_timer = 0; +uint32_t anim_sleep = 0; +uint8_t current_idle_frame = 0; + +bool tap_anim = false; +bool tap_anim_toggle = false; + + +// Decompress and write a precompressed bitmap frame to the OLED. +// Documentation and python compression script available at: +// https://github.com/nullbitsco/squeez-o +#ifdef USE_OLED_BITMAP_COMPRESSION +static void oled_write_compressed_P(const char* input_block_map, const char* input_block_list) { + uint16_t block_index = 0; + for (uint16_t i=0; i<NUM_OLED_BYTES; i++) { + uint8_t bit = i%8; + uint8_t map_index = i/8; + uint8_t _block_map = (uint8_t)pgm_read_byte_near(input_block_map + map_index); + uint8_t nonzero_byte = (_block_map & (1 << bit)); + if (nonzero_byte) { + const char data = (const char)pgm_read_byte_near(input_block_list + block_index++); + oled_write_raw_byte(data, i); + } else { + const char data = (const char)0x00; + oled_write_raw_byte(data, i); + } + } +} +#endif + +static void render_anim(void) { + // Idle animation + void animation_phase(void) { + if (!tap_anim) { + current_idle_frame = (current_idle_frame + 1) % NUM_IDLE_FRAMES; + uint8_t idx = abs((NUM_IDLE_FRAMES - 1) - current_idle_frame); + #ifdef USE_OLED_BITMAP_COMPRESSION + oled_write_compressed_P(idle_block_map[idx], idle_frames[idx]); + #else + oled_write_raw_P(idle_frames[idx], NUM_OLED_BYTES); + #endif + } + } + + // Idle behaviour + if (get_current_wpm() != 000) { // prevent sleep + oled_on(); + if (timer_elapsed32(anim_timer) > IDLE_FRAME_DURATION) { + anim_timer = timer_read32(); + animation_phase(); + } + anim_sleep = timer_read32(); + } else { // Turn off screen when timer threshold elapsed or reset time since last input + if (timer_elapsed32(anim_sleep) > OLED_TIMEOUT) { + oled_off(); + } else { + if (timer_elapsed32(anim_timer) > IDLE_FRAME_DURATION) { + anim_timer = timer_read32(); + animation_phase(); + } + } + } +} +#endif + +// Animate tap +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + #ifdef OLED_ENABLE + // Check if non-mod + if ((keycode >= KC_TAB && keycode <= KC_SLASH) || // Tab - Slash (Symbols, Punctuation, Space) + (keycode >= KC_KP_SLASH && keycode <= KC_KP_COMMA) || // Keypad slash - Keypad Dot + (keycode >= KC_F1 && keycode <= KC_F12)) { // F1 - F12 + if (record->event.pressed) { + // Display tap frames + tap_anim_toggle = !tap_anim_toggle; + #ifdef USE_OLED_BITMAP_COMPRESSION + oled_write_compressed_P(tap_block_map[tap_anim_toggle], tap_frames[tap_anim_toggle]); + #else + oled_write_raw_P(tap_frames[tap_anim_toggle], NUM_OLED_BYTES); + #endif + } + } + #endif + + return true; +} |