-
Notifications
You must be signed in to change notification settings - Fork 0
/
animation-utils.c
99 lines (81 loc) · 2.78 KB
/
animation-utils.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/**
* Utilities for QMK oled animations
*
* Copyright (c) Marek Piechut
* MIT License
*/
#pragma once
//-------- CONFIGURATION START --------
#ifndef ANIM_RENDER_WPM
#define ANIM_RENDER_WPM true
#endif
#ifndef FAST_TYPE_WPM
#define FAST_TYPE_WPM 45 //Switch to fast animation when over words per minute
#endif
#ifndef ANIM_INVERT
#define ANIM_INVERT false //Invert animation color and background
#endif
#ifndef ANIM_BG
#define ANIM_BG 0x00
#endif
#ifndef ANIM_FRAME_TIME
#define ANIM_FRAME_TIME 250
#endif
//-------- CONFIGURATION END--------
#define ANIM_WPM_WIDTH 22
#define OLED_ROWS OLED_DISPLAY_HEIGHT / 4
static void oled_render_wpm(void) {
static char wpm_str[4];
sprintf(wpm_str, "%03d", get_current_wpm());
oled_set_cursor(0, 1);
oled_write_P(PSTR("WPM"), false);
oled_set_cursor(0, 2);
oled_write(wpm_str, false);
}
static void oled_render_anim_frame(const char **fast_frames, const char **slow_frames, uint8_t frames_len) {
static uint32_t anim_timer = 0;
static uint8_t current_frame = 0;
static int16_t frame_offset = ANIM_RENDER_WPM ? ANIM_WPM_WIDTH : 0;
static int8_t step = 8;
const uint8_t speed = get_current_wpm();
if (timer_elapsed32(anim_timer) > ANIM_FRAME_TIME && speed > 0) {
oled_set_cursor(0, 0);
anim_timer = timer_read32();
const bool is_fast = speed > FAST_TYPE_WPM;
const char *frame = is_fast ? fast_frames[current_frame] : slow_frames[current_frame];
const int8_t bg = ANIM_BG;
uint8_t frame_start_offset = ANIM_RENDER_WPM ? ANIM_WPM_WIDTH : 0;
current_frame = (current_frame + 1) % frames_len;
for(int offset = 0; offset <= OLED_MATRIX_SIZE; offset++) {
uint16_t col = offset % OLED_DISPLAY_WIDTH;
if(col < frame_start_offset) {
continue;
} else if (col < frame_offset || col > frame_offset + ANIM_FRAME_WIDTH) {
oled_write_raw_byte((ANIM_INVERT ? ~bg : bg), offset);
} else if (col <= OLED_DISPLAY_WIDTH) {
uint8_t row = offset / OLED_DISPLAY_WIDTH;
int frame_data_offset = ANIM_FRAME_WIDTH * row + col - frame_offset;
uint8_t col_data = pgm_read_byte(frame + frame_data_offset);
oled_write_raw_byte(ANIM_INVERT ? ~col_data : col_data, offset );
}
}
#ifdef ANIM_SCROLL
if(is_fast) {
#ifdef ANIM_BOUNCE
if(frame_offset + ANIM_FRAME_WIDTH > OLED_DISPLAY_WIDTH || frame_offset < frame_start_offset) {
step = -step;
}
#endif
frame_offset += step;
if(frame_offset >= OLED_DISPLAY_WIDTH) {
frame_offset = frame_start_offset - ANIM_FRAME_WIDTH + step;
}
} else if (frame_offset > (OLED_DISPLAY_WIDTH - ANIM_FRAME_WIDTH) || frame_offset < frame_start_offset) {
frame_offset = frame_start_offset;
}
#endif
}
if(ANIM_RENDER_WPM) {
oled_render_wpm();
}
}