Compare commits

..

No commits in common. "b66e3c2878df619d24b05aa22312085828bb1625" and "a903500b4ef101956d89f162a3fe8235e114d32b" have entirely different histories.

23 changed files with 1825 additions and 2660 deletions

17
README.md Normal file
View File

@ -0,0 +1,17 @@
# Lily58minh
## Compiling and flashing
### Compiling
1. Install `qmk`.
2. Go into the github repo of `qmk-firmware`.
3. Clone this repo into `keyboards/lily58/keymaps/lily58minh/`.
4. Go back to `qmk-firmware` root.
5. Run `make git-submodules && git pull` to get latest changes.
6. Run `make lily58:lily58minh` to compile the firmware.
### Flashing
1. Plug the USB-C cable into your right half, run `make lily58:lily58minh:dfu-split-right` and press the reset button your Elite C controller.
2. Vice versa for the left half with `make lily58:lily58minh:dfu-split-left`

309
boot.c
View File

@ -1,309 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
#include "boot.h"
#include "fast_random.h"
#include "draw_helper.h"
#include "gui_state.h"
// boot
#define ANIM_BOOT_FRAME_DURATION 8
uint16_t anim_boot_timer = 0;
uint8_t anim_boot_current_frame = 0;
#define NAVI_DURATION 55
// terminal stuff
#define TERMINAL_DURATION 25
#define TERMINAL_LINE_NUMBER 19
#define TERMINAL_LINE_MAX 14
#define LILY_DURATION 50
// halt
#define ANIM_HALT_FRAME_DURATION 55
uint16_t anim_halt_timer = 0;
void reset_boot(void) {
// frame zero
anim_boot_current_frame = 0;
}
static void draw_lily_key(uint8_t x, uint8_t y, uint8_t *key_number, unsigned long key_state, uint8_t color) {
uint8_t v = *key_number;
unsigned long mask = 1;
mask = mask << v;
// ligth the key according to the mask
if (((key_state & mask) == mask)) {
color = !color;
}
draw_rectangle_fill(x, y, 3, 3, color);
*key_number = v + 1;
}
static void draw_lily_key_row(uint8_t x, uint8_t y, int w, uint8_t *key_number, unsigned long key_state, uint8_t color) {
// row of rectangle
for (uint8_t i = 0; i < w; i++) {
draw_lily_key(x + (i * 4), y, key_number, key_state, color);
}
}
static void draw_lily_render(unsigned long key_state) {
// different orientation base on side
#if IS_LEFT
uint8_t x = 0;
uint8_t y = 56;
uint8_t x_ref = 10 + x;
uint8_t y_ref = 2 + y;
uint8_t i_key_number = 0;
for (uint8_t i = 0; i < 4; i++) {
draw_lily_key_row(x_ref, y_ref + (i * 4), 4, &i_key_number, key_state, true);
draw_lily_key_row(x_ref - 8, y_ref + 2 + (i * 4), 2, &i_key_number, key_state, true);
}
draw_lily_key_row(x_ref + 2, y_ref + (4 * 4), 3, &i_key_number, key_state, true);
uint8_t x_side = x_ref + (4 * 4);
draw_lily_key(x_side, y_ref + (2 * 4) + 2, &i_key_number, key_state, true);
draw_lily_key(x_side, y_ref + (4 * 4), &i_key_number, key_state, true);
// screen
draw_rectangle(x_side, y_ref, 4, 8, true);
// frame
drawline_hr(x + 1, y + 2, 8, true);
oled_write_pixel(x + 8, y + 1, true);
drawline_hr(x + 8, y, 23, true);
drawline_hr(x + 1, y + 20, 10, true);
oled_write_pixel(x + 10, y + 21, true);
drawline_hr(x + 10, y + 22, 16, true);
drawline_vb(x, y + 3, 17, true);
drawline_vb(x + 31, y + 1, 20, true);
oled_write_pixel(x + 30, y + 21, true);
oled_write_pixel(x + 29, y + 22, true);
oled_write_pixel(x + 28, y + 23, true);
oled_write_pixel(x + 27, y + 24, true);
oled_write_pixel(x + 26, y + 23, true);
#endif
#if IS_RIGHT
uint8_t i_key_number = 0;
for (uint8_t i = 0; i < 4; i++) {
draw_lily_key_row(7, 58 + (i * 4), 4, &i_key_number, key_state, true);
draw_lily_key_row(23, 60 + (i * 4), 2, &i_key_number, key_state, true);
}
draw_lily_key_row(9, 74, 3, &i_key_number, key_state, true);
draw_lily_key(3, 68, &i_key_number, key_state, true);
draw_lily_key(3, 74, &i_key_number, key_state, true);
// screen
draw_rectangle(2, 58, 4, 8, true);
// frame
drawline_hr(23, 58, 8, true);
oled_write_pixel(23, 57, true);
drawline_hr(1, 56, 23, true);
drawline_hr(21, 76, 10, true);
oled_write_pixel(21, 77, true);
drawline_hr(6, 78, 16, true);
drawline_vb(31, 59, 17, true);
drawline_vb(0, 57, 20, true);
oled_write_pixel(1, 77, true);
oled_write_pixel(2, 78, true);
oled_write_pixel(3, 79, true);
oled_write_pixel(4, 80, true);
oled_write_pixel(5, 79, true);
#endif
}
static void draw_lily(uint8_t f) {
// frame for the events
uint8_t tres_stroke = 10;
uint8_t tres_boom = 30;
uint8_t y_start = 56;
if (f == 0 || f == tres_stroke || f == tres_boom) {
// clean screen
oled_clear();
}
// simple lily58 with all the keys
if (f < tres_stroke) {
draw_lily_render(0);
}
// increase number of random keys pressed
if (f >= tres_stroke && f < tres_boom) {
int inter_f = interpo_pourcent(tres_stroke, tres_boom, f);
unsigned long key_state = fastrand_long();
for (int r = 100 - inter_f; r > 0; r = r - 10) {
key_state &= fastrand_long();
}
draw_lily_render(key_state);
}
// statir explosion
if (f >= tres_boom) {
oled_clear();
uint8_t density = (f - tres_boom);
if (density > 4) density = 4;
draw_static(0, y_start - 8, 32, 32, true, density);
}
}
static void draw_startup_navi(uint8_t f) {
// text
oled_write_cursor(0, 5, "HELL0", false);
oled_write_cursor(0, 7, "NAVI.", false);
// prompt
if ((f % 8) > 4) {
oled_write_cursor(0, 12, "> ", false);
} else {
oled_write_cursor(0, 12, ">_", false);
}
// frame threshold
uint8_t tres_shell = 15;
uint8_t tres_load = 35;
// rand text to init display
if (f > tres_shell) {
int inter_f = interpo_pourcent(tres_shell, tres_load, f);
draw_random_char(1, 12, 'i', 60 + inter_f, 0);
draw_random_char(2, 12, 'n', 20 + inter_f, 0);
draw_random_char(3, 12, 'i', inter_f, 0);
draw_random_char(4, 12, 't', 20 + inter_f, 0);
}
// loading propress bar
if (f > tres_load) {
int inter_f = interpo_pourcent(tres_load, 50, f);
// ease
float fv = inter_f / 100.00;
fv = fv * fv * fv * fv;
inter_f = fv * 100;
draw_rectangle(0, (15 * 8), 32, 8, 1);
draw_progress(0 + 3, (15 * 8) + 3, 26, 2, inter_f, 0, 1);
}
}
// text dispayed on terminal
static char *boot_ref[TERMINAL_LINE_NUMBER] = {"LT:", "RT:", "M :", " ", "cnx:", "A0:", "B0:", " ", "0x40", "0x60", "0x85", "0x0F", " ", "> run", "x ", "y ", " 100%", " ", "> key"};
// prompt style for char in the font
char scan_font[5] = {'>', 1, 1, 1, 1};
static char *get_terminal_line(uint8_t i) {
// display text
if (i < TERMINAL_LINE_NUMBER) {
return boot_ref[i];
}
// blank line every 3 lines
if (i % 3 == 0) {
return " ";
}
// display consecutive chars in the font
i = (i - TERMINAL_LINE_NUMBER) * 4;
scan_font[1] = i;
scan_font[2] = i + 1;
scan_font[3] = i + 2;
scan_font[4] = i + 3;
return scan_font;
}
static void draw_startup_terminal(uint8_t f) {
// ease for printing on screen
f = f * 2;
f += (f / 5);
// scroll text
uint8_t i_start = 0;
uint8_t i_nb_char = f;
if (f > TERMINAL_LINE_MAX) {
i_start = f - TERMINAL_LINE_MAX;
i_nb_char = TERMINAL_LINE_MAX;
}
// display lines
oled_clear();
for (uint8_t i = 0; i < i_nb_char; i++) {
char *s = get_terminal_line(i + i_start);
oled_write_cursor(0, i, s, false);
}
}
bool render_boot(void) {
// end of the boot sequence
if (anim_boot_current_frame >= NAVI_DURATION + TERMINAL_DURATION + LILY_DURATION) {
anim_boot_current_frame = 0;
oled_clear();
return true;
}
if (timer_elapsed(anim_boot_timer) > ANIM_BOOT_FRAME_DURATION) {
anim_boot_timer = timer_read();
if (anim_boot_current_frame < NAVI_DURATION) {
// 55 frames
draw_startup_navi(anim_boot_current_frame);
} else {
if (anim_boot_current_frame >= NAVI_DURATION && anim_boot_current_frame < NAVI_DURATION + TERMINAL_DURATION) {
// 25
draw_startup_terminal(anim_boot_current_frame - NAVI_DURATION);
} else {
if (anim_boot_current_frame >= NAVI_DURATION + TERMINAL_DURATION) {
// 25
draw_lily(anim_boot_current_frame - NAVI_DURATION - TERMINAL_DURATION);
}
}
}
anim_boot_current_frame++;
}
return false;
}
void render_halt(void) {
if (timer_elapsed(anim_halt_timer) > ANIM_HALT_FRAME_DURATION) {
anim_halt_timer = timer_read();
// comb glitch for all the screen
draw_glitch_comb(0, 0, 32, 128, 3, true);
// random moving blocks of pixels
for (uint8_t i = 0; i < 6; i++) {
int r = fastrand();
int rr = fastrand();
uint8_t x = 4 + r % 28;
uint8_t y = rr % 128;
uint8_t w = 7 + r % 20;
uint8_t h = 3 + rr % 10;
int s = (fastrand() % 20) - 10;
move_block(x, y, w, h, s);
}
}
}

9
boot.h
View File

@ -1,9 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
bool render_boot(void);
void render_halt(void);
void reset_boot(void);

252
burst.c
View File

@ -1,252 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// Copyright 2020 Richard Sutherland (rich@brickbots.com)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
#include "gui_state.h"
#include "fast_random.h"
#include "burst.h"
#include "draw_helper.h"
// burst stuff
static int current_burst = 0;
static uint16_t burst_timer = 0;
// WPM stuff
static int current_wpm = 0;
static uint16_t wpm_timer = 0;
// This smoothing is 40 keystrokes
static const float wpm_smoothing = WPM_SMOOTHING;
// store values
uint8_t burst_scope[SIZE_SCOPE] = {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};
uint8_t wpm_scope[SIZE_SCOPE] = {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};
// current max wpm
int max_wpm = MAX_WPM_INIT;
// scope animation stuff
#define ANIM_SCOPE_FRAME_DURATION 40
#define ANIM_SLEEP_SCOPE_FRAME_NUMBER 10
uint16_t anim_scope_timer = 0;
uint16_t anim_scope_idle_timer = 0;
uint16_t anim_sleep_scope_timer = 0;
uint8_t anim_sleep_scope_duration[ANIM_SLEEP_SCOPE_FRAME_NUMBER] = {30, 30, 30, 30, 20, 20, 30, 30, 32, 35};
uint8_t current_sleep_scope_frame = 0;
uint8_t sleep_scope_frame_destination = ANIM_SLEEP_SCOPE_FRAME_NUMBER - 1;
// glitch animation
int current_glitch_scope_time = 150;
uint32_t glitch_scope_timer = 0;
uint8_t current_glitch_scope_index = 0;
static void update_wpm(void) {
if (wpm_timer > 0) {
current_wpm += ((60000 / timer_elapsed(wpm_timer) / WPM_ESTIMATED_WORD_SIZE) - current_wpm) * wpm_smoothing;
if (current_wpm > LIMIT_MAX_WPM) {
current_wpm = LIMIT_MAX_WPM;
}
}
wpm_timer = timer_read();
}
void update_scope(void) {
update_wpm();
uint16_t temps_ecoule = timer_elapsed(burst_timer);
if (temps_ecoule > BURST_FENETRE) {
// 1er frappe après longtemps
current_burst = 40;
} else {
int time_pourcent = ((100 * (temps_ecoule)) / (BURST_FENETRE));
current_burst = 100 - time_pourcent;
}
burst_timer = timer_read();
}
static void update_scope_array(void) {
// shift array
for (uint8_t i = 0; i < SIZE_SCOPE - 1; i++) {
burst_scope[i] = burst_scope[i + 1];
wpm_scope[i] = wpm_scope[i + 1];
}
int burst = current_burst;
int wpm = current_wpm;
// compute max wpm
max_wpm = (wpm == 0) ? MAX_WPM_INIT : ((wpm > max_wpm) ? wpm : max_wpm);
// current wpm ratio VS max
wpm = (100 * wpm) / max_wpm;
if (wpm > 100) wpm = 100;
// update last slot of the arrays
burst_scope[SIZE_SCOPE - 1] = burst;
wpm_scope[SIZE_SCOPE - 1] = wpm;
// apply decay to burst chart
uint8_t pBaisse = 0;
for (uint8_t i = 0; i < SIZE_SCOPE - (SIZE_SCOPE / 4); i++) {
pBaisse = 2 + ((SIZE_SCOPE - 1 - i)) / 2;
burst_scope[i] -= ((burst_scope[i] * pBaisse) / 100);
}
}
static void RenderScopeBlack(void) {
// clean central zone
draw_rectangle_fill(3, 82, 28, 120, false);
// redraw some parts of the frame
drawline_hr(1, SCOPE_Y_BOTTOM, 32, 1);
drawline_vt(0, SCOPE_Y_BOTTOM - 1, 42, 1);
drawline_vt(31, SCOPE_Y_BOTTOM - 1, 47, 1);
}
static void render_scope_white(void) {
static const char PROGMEM raw_logo[] = {
240, 8, 4, 226, 241, 248, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 0, 0, 255, 255, 0, 0, 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, 0, 0, 255, 255, 0, 0, 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, 0, 0, 255, 255, 0, 0, 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, 0, 0, 255, 255, 0, 0, 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, 0, 0, 255, 127, 128, 128, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 128, 128, 127,
};
oled_write_raw_P_cursor(0, 10, raw_logo, sizeof(raw_logo));
}
static void render_scope_chart(void) {
// clean the frame
render_scope_white();
uint8_t y_offset = SCOPE_Y_BOTTOM - 3;
for (uint8_t i = 0; i < SIZE_SCOPE; i++) {
// offset
uint8_t x = 3 + i;
// new black vertical line for burst
uint8_t iCurrentBurst = burst_scope[i];
drawline_vt(x, y_offset, (iCurrentBurst * 4) / 10, 0);
// new black point for wpm, white if it's on the burst line
uint8_t iCurrentWpm = wpm_scope[i];
uint8_t yWpm = y_offset - ((iCurrentWpm * 4) / 10);
oled_write_pixel(x, yWpm, !(iCurrentWpm > iCurrentBurst));
}
}
void reset_scope(void) {
// scope need wakeup
anim_sleep_scope_timer = timer_read();
current_sleep_scope_frame = ANIM_SLEEP_SCOPE_FRAME_NUMBER - 1;
sleep_scope_frame_destination = 0;
}
static void render_glitch_square(void) {
if (timer_elapsed(anim_scope_idle_timer) > 60) {
anim_scope_idle_timer = timer_read();
RenderScopeBlack();
uint8_t color = 0;
uint8_t size = 0;
for (uint8_t i = 0; i < 4; i++) {
size = 4 + (fastrand() % 6);
draw_gradient(3 + (fastrand() % 19), 85 + (fastrand() % 20), size, size, 255, 255, 4);
size = (fastrand() % 6);
color = 100 + (fastrand() % 100);
draw_gradient(3 + (fastrand() % 19), 100 + (fastrand() % 20), size, size, color, color, 4);
}
}
}
void render_scope_idle(void) {
uint8_t glitch_prob = get_glitch_probability();
get_glitch_index(&glitch_scope_timer, &current_glitch_scope_time, &current_glitch_scope_index, 150, 350, glitch_prob, 2);
switch (current_glitch_scope_index) {
case 0:
RenderScopeBlack();
return;
case 1:
render_glitch_square();
return;
}
}
static void RenderScopeSleep(void) {
if (current_sleep_scope_frame == sleep_scope_frame_destination) {
// animation finished
render_scope_idle();
return;
}
if (timer_elapsed(anim_sleep_scope_timer) > anim_sleep_scope_duration[current_sleep_scope_frame]) {
anim_sleep_scope_timer = timer_read();
// clean scope
RenderScopeBlack();
// render animation
render_tv_animation(current_sleep_scope_frame, 3, 80, 25, 48);
// update frame number
if (sleep_scope_frame_destination > current_sleep_scope_frame) {
current_sleep_scope_frame++;
} else {
current_sleep_scope_frame--;
}
}
}
void render_scope(gui_state_t t) {
if (timer_elapsed(anim_scope_timer) > ANIM_SCOPE_FRAME_DURATION) {
anim_scope_timer = timer_read();
// shift arrays
update_scope_array();
// oled_set_cursor(0, 10);
if (t == _WAKINGUP) {
RenderScopeSleep();
return;
}
if (t == _IDLE) {
sleep_scope_frame_destination = ANIM_SLEEP_SCOPE_FRAME_NUMBER - 1;
RenderScopeSleep();
return;
}
render_scope_chart();
}
}
static void decay_burst(void) {
uint16_t temps_ecoule = timer_elapsed(burst_timer);
int poucentageEcoule = 100;
if (temps_ecoule <= BURST_FENETRE * 4) {
poucentageEcoule = ((100 * (temps_ecoule)) / (BURST_FENETRE * 4));
}
current_burst = current_burst - poucentageEcoule;
if (current_burst <= 0) current_burst = 0;
}
static void decay_wpm(void) {
if (timer_elapsed(wpm_timer) > 1000) {
wpm_timer = timer_read();
current_wpm += (-current_wpm) * wpm_smoothing;
}
}
void decay_scope(void) {
decay_burst();
decay_wpm();
}

24
burst.h
View File

@ -1,24 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// Copyright 2020 Richard Sutherland (rich@brickbots.com)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// burst
#define MAX_WPM_INIT 40
#define BURST_FENETRE 500
// wpm
#define LIMIT_MAX_WPM 150
#define WPM_ESTIMATED_WORD_SIZE 5
#define WPM_SMOOTHING 0.0487
// scope
#define SIZE_SCOPE 26
#define SCOPE_Y_BOTTOM 127
void update_scope(void);
void render_scope(gui_state_t t);
void reset_scope(void);
void decay_scope(void);

View File

@ -1,53 +1,37 @@
// Copyright 2021 Nicolas Druoton (druotoni) /*
// Copyright 2012 Jun Wako <wakojun@gmail.com> This is the c configuration file for the keymap
// Copyright 2015 Jack Humbert
// SPDX-License-Identifier: GPL-2.0-or-later Copyright 2012 Jun Wako <wakojun@gmail.com>
Copyright 2015 Jack Humbert
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
#define MASTER_LEFT
#define OLED_DRIVER_ENABLE
// tapping toggle for my layers
#define TAPPING_TOGGLE 2
// choose IS_LEFT or IS_RIGHT for compilation and flash firmware
// #define IS_LEFT 1
#define IS_RIGHT 1
// logo glitch
#define WITH_GLITCH
// boot sequence
#define WITH_BOOT
// custom transport for displaying on both side
#define SPLIT_TRANSACTION_IDS_USER USER_SYNC_A
// custom font
#ifdef OLED_FONT_H
# undef OLED_FONT_H
#endif
#define OLED_FONT_H "navi_font.c"
#undef OLED_FONT_END
#define OLED_FONT_END 125
// more space
#define NO_ACTION_MACRO #define NO_ACTION_MACRO
#define NO_ACTION_FUNCTION #define NO_ACTION_FUNCTION
#define NO_ACTION_ONESHOT
#define DISABLE_LEADER #define DISABLE_LEADER
#define MASTER_LEFT
#define EE_HANDS
#define SPLIT_USB_DETECT
// ??? #define TAPPING_FORCE_HOLD
#undef LOCKING_SUPPORT_ENABLE #define TAPPING_TERM 100
#undef LOCKING_RESYNC_ENABLE
// small layer state #define NO_ACTION_ONESHOT
#define LAYER_STATE_8BIT
// no debug or trace #define SPLIT_LAYER_STATE_ENABLE
#ifndef NO_DEBUG #define SPLIT_WPM_ENABLE
# define NO_DEBUG #define SPLIT_OLED_ENABLE
#endif
#if !defined(NO_PRINT) && !defined(CONSOLE_ENABLE)
# define NO_PRINT
#endif

View File

@ -1,768 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// Copyright 2021 ugfx
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
#include "draw_helper.h"
#include "fast_random.h"
void drawline(uint8_t x, uint8_t y, uint8_t width, bool bHorizontal, bool bPositiveDirection, bool color) {
if (width <= 0) return;
uint8_t yPlus = 0;
uint8_t yMois = 0;
uint8_t nbtour = 0;
if (!bPositiveDirection) {
if (bHorizontal) {
x -= width;
} else {
y -= width;
}
}
yMois = (width / 2) - 1 + (width % 2);
yPlus = (width / 2);
nbtour = (width / 4) + 1;
bool bWhite = color;
if (bHorizontal) {
for (uint8_t i = 0; i < nbtour; i++) {
oled_write_pixel(x + yPlus + i, y, bWhite);
oled_write_pixel(x + yMois - i, y, bWhite);
oled_write_pixel(x + i, y, bWhite);
oled_write_pixel(x + width - 1 - i, y, bWhite);
}
} else {
for (uint8_t i = 0; i < nbtour; i++) {
oled_write_pixel(x, y + yPlus + i, bWhite);
oled_write_pixel(x, y + yMois - i, bWhite);
oled_write_pixel(x, y + i, bWhite);
oled_write_pixel(x, y + width - 1 - i, bWhite);
}
}
}
void drawline_vb(uint8_t x, uint8_t y, uint8_t width, bool color) { drawline(x, y, width, false, true, color); }
void drawline_vt(uint8_t x, uint8_t y, uint8_t width, bool color) { drawline(x, y, width, false, false, color); }
void drawline_hr(uint8_t x, uint8_t y, uint8_t width, bool color) { drawline(x, y, width, true, true, color); }
void drawline_hl(uint8_t x, uint8_t y, uint8_t width, bool color) { drawline(x, y, width, true, false, color); }
void draw_rectangle(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, bool color) {
drawline_hr(x, y, width, color);
drawline_hr(x, y + heigth - 1, width, color);
drawline_vb(x, y, heigth, color);
drawline_vb(x + width - 1, y, heigth, color);
}
void draw_rectangle_fill(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, bool color) {
for (uint8_t i = 0; i < heigth; i++) {
drawline_hr(x, y + i, width, color);
}
}
void drawline_hr_heigth(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, bool color) {
for (int i = 0; i < heigth; i++) {
drawline_hr(x, y - i, width, color);
drawline_hr(x, y + i, width, color);
}
}
void drawline_point_hr(short x, short y, short x1, bool color) {
if (y < 0 || y > 127) return;
if (x1 < x) {
short iTemp = x;
x = x1;
x1 = iTemp;
}
if (x1 > 31) x1 = 31;
if (x < 0) x = 0;
if (x > 31) x = 31;
drawline(x, y, x1 - x, true, true, color);
}
void flip_flap_x(short px, short py, uint8_t val, bool color) {
oled_write_pixel(px + val, py, color);
oled_write_pixel(px - val, py, color);
}
void draw_circle(uint8_t x, uint8_t y, uint8_t radius, bool color) {
short a, b, P;
// Calculate intermediates
a = 1;
b = radius;
P = 4 - radius;
short py, px;
// Away we go using Bresenham's circle algorithm
// Optimized to prevent double drawing
px = x;
py = y + b;
oled_write_pixel(px, py, color);
px = x;
py = y - b;
oled_write_pixel(px, py, color);
flip_flap_x(x, y, b, color);
do {
flip_flap_x(x, y + b, a, color);
flip_flap_x(x, y - b, a, color);
flip_flap_x(x, y + a, b, color);
flip_flap_x(x, y - a, b, color);
if (P < 0)
P += 3 + 2 * a++;
else
P += 5 + 2 * (a++ - b--);
} while (a < b);
flip_flap_x(x, y + b, a, color);
flip_flap_x(x, y - b, a, color);
}
void draw_ellipse(uint8_t x, uint8_t y, uint8_t a, uint8_t b, bool color) {
int dx, dy;
int a2, b2;
int err, e2;
// short py, px;
// Calculate intermediates
dx = 0;
dy = b;
a2 = a * a;
b2 = b * b;
err = b2 - (2 * b - 1) * a2;
// Away we go using Bresenham's ellipse algorithm
do {
flip_flap_x(x, y + dy, dx, color);
flip_flap_x(x, y - dy, dx, color);
e2 = 2 * err;
if (e2 < (2 * dx + 1) * b2) {
dx++;
err += (2 * dx + 1) * b2;
}
if (e2 > -(2 * dy - 1) * a2) {
dy--;
err -= (2 * dy - 1) * a2;
}
} while (dy >= 0);
}
void draw_ellipse_fill(uint8_t x, uint8_t y, uint8_t a, uint8_t b, bool color) { return; }
// void draw_ellipse_fill(uint8_t x, uint8_t y, uint8_t a, uint8_t b, uint8_t color) {
// int dx, dy;
// int a2, b2;
// int err, e2;
// // Calculate intermediates
// dx = 0;
// dy = b;
// a2 = a * a;
// b2 = b * b;
// err = b2 - (2 * b - 1) * a2;
// short py, px, px1;
// // Away we go using Bresenham's ellipse algorithm
// // This is optimized to prevent overdrawing by drawing a line only when a y is about to change value
// do {
// e2 = 2 * err;
// if (e2 < (2 * dx + 1) * b2) {
// dx++;
// err += (2 * dx + 1) * b2;
// }
// if (e2 > -(2 * dy - 1) * a2) {
// py = y + dy;
// px = x - dx;
// px1 = x + dx;
// drawline_point_hr(px, py, px1, color);
// if (y) {
// py = y - dy;
// px = x - dx;
// px1 = x + dx;
// drawline_point_hr(px, py, px1, color);
// }
// dy--;
// err -= (2 * dy - 1) * a2;
// }
// } while (dy >= 0);
// }
bool test_limit(short x, short y) { return !(y < 0 || y > 127 || x < 0 || x > 31); }
void flip_flap_y_point(short px, short py, short px1, uint8_t val, bool color) {
// firmware size optimisation : one fonction for 2 lines of code
drawline_point_hr(px, py + val, px1, color);
drawline_point_hr(px, py - val, px1, color);
}
void draw_fill_circle(short x, short y, uint8_t radius, bool color) {
short a, b, P;
// Calculate intermediates
a = 1;
b = radius;
P = 4 - radius;
// Away we go using Bresenham's circle algorithm
// This is optimized to prevent overdrawing by drawing a line only when a variable is about to change value
short py, px, px1;
py = y;
px = x - b;
px1 = x + b;
drawline_point_hr(px, py, px1, color);
py = y + b;
px = x;
if (test_limit(px, py)) oled_write_pixel(px, py, color);
py = y - b;
px = x;
if (test_limit(px, py)) oled_write_pixel(px, py, color);
do {
flip_flap_y_point(x - b, y, x + b, a, color);
if (P < 0) {
P += 3 + 2 * a++;
} else {
flip_flap_y_point(x - a, y, x + a, b, color);
P += 5 + 2 * (a++ - b--);
}
} while (a < b);
flip_flap_y_point(x - b, y, x + b, a, color);
}
bool apres_moitie(int a, int b) { return (a > b / 2); }
bool arrive_moitie(int a, int b) { return (a > b / 2); }
bool avant_moitie(int a, int b) { return (a <= b / 2 && !apres_moitie(a, b)); }
void draw_arc_sector(uint8_t x, uint8_t y, uint8_t radius, unsigned char sectors, unsigned char half, bool color) {
short a, b, P;
short py, px;
// Calculate intermediates
a = 1; // x in many explanations
b = radius; // y in many explanations
P = 4 - radius;
if (half != 2) {
// Away we go using Bresenham's circle algorithm
// Optimized to prevent double drawing
if (sectors & 0x06) {
px = x;
py = y - b;
oled_write_pixel(px, py, color);
} // Upper upper
if (sectors & 0x60) {
px = x;
py = y + b;
oled_write_pixel(px, py, color);
} // Lower lower
if (sectors & 0x81) {
px = x + b;
py = y;
oled_write_pixel(px, py, color);
} // Right right
if (sectors & 0x18) {
px = x - b;
py = y;
oled_write_pixel(px, py, color);
} // Left left
}
bool dessiner = false;
do {
if (half == 1 && arrive_moitie(a, b)) break;
if (half == 2 && avant_moitie(a, b)) {
dessiner = false;
} else {
dessiner = true;
}
if (dessiner) {
if (sectors & 0x01) {
px = x + b;
py = y - a;
oled_write_pixel(px, py, color);
} // Upper right right
if (sectors & 0x02) {
px = x + a;
py = y - b;
oled_write_pixel(px, py, color);
} // Upper upper right
if (sectors & 0x04) {
px = x - a;
py = y - b;
oled_write_pixel(px, py, color);
} // Upper upper left
if (sectors & 0x08) {
px = x - b;
py = y - a;
oled_write_pixel(px, py, color);
} // Upper left left
if (sectors & 0x10) {
px = x - b;
py = y + a;
oled_write_pixel(px, py, color);
} // Lower left left
if (sectors & 0x20) {
px = x - a;
py = y + b;
oled_write_pixel(px, py, color);
} // Lower lower left
if (sectors & 0x40) {
px = x + a;
py = y + b;
oled_write_pixel(px, py, color);
} // Lower lower right
if (sectors & 0x80) {
px = x + b;
py = y + a;
oled_write_pixel(px, py, color);
} // Lower right right
}
if (P < 0)
P += 3 + 2 * a++;
else
P += 5 + 2 * (a++ - b--);
} while (a < b);
if (half != 1) {
if (sectors & 0xC0) {
px = x + a;
py = y + b;
oled_write_pixel(px, py, color);
} // Lower right
if (sectors & 0x03) {
px = x + a;
py = y - b;
oled_write_pixel(px, py, color);
} // Upper right
if (sectors & 0x30) {
px = x - a;
py = y + b;
oled_write_pixel(px, py, color);
} // Lower left
if (sectors & 0x0C) {
px = x - a;
py = y - b;
oled_write_pixel(px, py, color);
} // Upper left
}
}
void draw_static(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, int color, uint8_t density) {
unsigned long rx = fastrand_long();
unsigned long ry = fastrand_long();
unsigned long maskx = 1;
unsigned long masky = 1;
unsigned long mask_base = 1;
// more 1 in the octet
for (int r = 0; r < density; r++) {
rx &= fastrand_long();
ry &= fastrand_long();
}
color = ((rx >> 1) % 2) == 0;
for (uint8_t i = 0; i < width; i++) {
for (uint8_t j = 0; j < heigth; j++) {
// new mask based on ij loop
maskx = (mask_base << i);
masky = (mask_base << j);
// logic AND with the masks
if (((rx & maskx) == maskx) && ((ry & masky) == masky)) {
oled_write_pixel(x + i, y + j, color);
}
}
}
}
void copy_pixel(int from, int shift, unsigned char mask) {
if (shift == 0) return;
// pixel cluster from
char c_from = get_oled_char(from);
char extract = c_from & mask;
// pixel cluster shift
char c_from_shift = get_oled_char(from + shift);
c_from_shift &= ~(mask);
c_from_shift |= extract;
oled_write_raw_byte(c_from_shift, from + shift);
// fill blank with black
c_from &= ~(mask);
oled_write_raw_byte(c_from, from);
}
void draw_glitch_comb(uint8_t x, uint8_t y, uint8_t width, uint16_t height, uint8_t iSize, bool odd) {
// work only on row
uint16_t y_start = (y / 8) * 32;
uint8_t nb_h = height / 8;
uint8_t w_max = width;
uint16_t index = y_start + x;
// shift pair even pixel
int mask_1 = 85;
int mask_2 = 170;
if (!odd) {
// shift odd pixel
mask_1 = 170;
mask_2 = 85;
}
// wobble
uint16_t pos = 0;
for (uint16_t j = 0; j < nb_h; j++) {
// next line
index = (y_start + x) + (j * 32);
for (uint16_t i = 0; i < w_max; i++) {
if (i + iSize < w_max) {
pos = index + i;
copy_pixel(pos + iSize, iSize * -1, mask_1);
}
if (w_max - 1 - i - iSize >= 0) {
pos = (index + w_max - 1) - i;
copy_pixel(pos - iSize, iSize, mask_2);
}
}
}
}
void draw_random_char(uint8_t column, uint8_t row, char final_char, int value, uint8_t style) {
if (value < 0) return;
char c = final_char;
if (value < 100) {
c = ((fastrand() % 15) + 1);
}
oled_set_cursor(column, row);
oled_write_char(c, false);
}
void get_glitch_index_new(uint16_t *glitch_timer, uint8_t *current_glitch_scope_time, uint8_t *glitch_index, uint8_t min_time, uint16_t max_time, uint8_t glitch_probobility, uint8_t glitch_frame_number) {
if (timer_elapsed(*glitch_timer) > *current_glitch_scope_time) {
// end of the last glitch period
*glitch_timer = timer_read();
// new random glich period
*current_glitch_scope_time = min_time + fastrand() % (max_time - min_time);
bool bGenerateGlitch = (fastrand() % 100) < glitch_probobility;
if (!bGenerateGlitch) {
// no glitch
*glitch_index = 0;
return;
}
// get a new glitch index
*glitch_index = fastrand() % glitch_frame_number;
}
}
uint8_t get_glitch_frame_index(uint8_t glitch_probobility, uint8_t glitch_frame_number) {
bool bGenerateGlitch = (fastrand() % 100) < glitch_probobility;
if (!bGenerateGlitch) {
// no glitch
return 0;
}
// get a new glitch index
return fastrand() % glitch_frame_number;
}
uint8_t get_glitch_duration(uint8_t min_time, uint16_t max_time) { return min_time + fastrand() % (max_time - min_time); }
void get_glitch_index(uint32_t *glitch_timer, int *current_glitch_scope_time, uint8_t *glitch_index, uint8_t min_time, uint16_t max_time, uint8_t glitch_probobility, uint8_t glitch_frame_number) {
if (timer_elapsed32(*glitch_timer) > *current_glitch_scope_time) {
// end of the last glitch period
*glitch_timer = timer_read32();
// new random glich period
*current_glitch_scope_time = min_time + fastrand() % (max_time - min_time);
bool bGenerateGlitch = (fastrand() % 100) < glitch_probobility;
if (!bGenerateGlitch) {
// no glitch
*glitch_index = 0;
return;
}
// get a new glitch index
*glitch_index = fastrand() % glitch_frame_number;
}
}
void draw_progress(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, int value, uint8_t style, bool color) {
if (value > 100) {
value = 100;
}
int lenght = (width * value) / 100;
for (uint8_t i = 0; i < lenght; i++) {
switch (style) {
case 0:
drawline_vb(x + i, y, heigth - 1, color);
break;
// case 1:
// drawline_vb(x + i, y + 1, heigth - 3, ((i % 3) < 2));
// break;
// case 2:
// // . . . . .
// drawline_vb(x + i, y + 3, 2, ((i % 2) == 0));
// break;
}
}
}
void oled_write_raw_P_cursor(uint8_t col, uint8_t line, const char *data, uint16_t size) {
// raw_P at cursor position
oled_set_cursor(col, line);
oled_write_raw_P(data, size);
}
void oled_write_cursor(uint8_t col, uint8_t line, const char *data, bool invert) {
// write at cursor position
oled_set_cursor(col, line);
oled_write(data, invert);
}
void draw_label(const char *data, uint8_t len, uint8_t row, int value) {
if (value < 0) return;
if (row >= 16 || row < 0) return;
oled_write_cursor(0, row, data, false);
}
void draw_box(const char *data, uint8_t len, uint8_t row, long value, uint8_t style) {
if (value < 0) return;
if (row >= 16 || row < 0) return;
oled_write_cursor(0, row, data, false);
uint8_t y = row * 8;
uint8_t x = 6 * len;
uint8_t w = 32 - x;
if (value < 0) value = 0;
if (value > 100) value = 100;
draw_progress(x, y, w, 7, value, style, 1);
}
char get_oled_char(uint16_t start_index) {
oled_buffer_reader_t reader;
reader = oled_read_raw(start_index);
return *reader.current_element;
}
static int get_index_first_block(uint8_t y) { return ((y / 8) * 32); }
void move_block(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, int shift) {
// clip
if (x >= 31) return;
if (y >= 127) return;
int max_screen = 32 - 1;
if ((width + x) > max_screen + 1) width = max_screen + 1 - x;
if (width <= 1) return;
if ((heigth + y) > 127) heigth = 127 - y;
if (heigth <= 1) return;
// [-32 & +32]
if (shift > max_screen) shift = max_screen;
if (shift < -1 * max_screen) shift = -1 * max_screen;
if ((width + x + shift) > max_screen) width = width - shift;
int pixelTop = 8 - (y % 8);
int pixelBottom = (y + heigth) % 8;
unsigned char cMastTop = ~((unsigned)255 >> (pixelTop));
unsigned char cMastBottom = ~((unsigned)255 << (pixelBottom));
int indexFirstBloc = get_index_first_block(y) + x;
int indexFirstBlocFull = get_index_first_block(y + pixelTop) + x;
int indexFirstBlocEnd = get_index_first_block(y + heigth) + x;
int nbBlockHeigth = (heigth - pixelTop - pixelBottom) / 8;
if (nbBlockHeigth < 0) {
// just single row
nbBlockHeigth = 0;
cMastBottom = 0;
}
if (shift < 0) {
for (uint16_t i = 0; i < width; i++) {
copy_pixel(indexFirstBloc + i, shift, cMastTop);
copy_pixel(indexFirstBlocEnd + i, shift, cMastBottom);
for (uint16_t j = 0; j < nbBlockHeigth; j++) {
copy_pixel(indexFirstBlocFull + i + (j * 32), shift, 255);
}
}
} else {
for (int i = width - 1; i >= 0; i--) {
copy_pixel(indexFirstBloc + i, shift, cMastTop);
copy_pixel(indexFirstBlocEnd + i, shift, cMastBottom);
for (uint16_t j = 0; j < nbBlockHeigth; j++) {
copy_pixel(indexFirstBlocFull + i + (j * 32), shift, 255);
}
}
}
}
int interpo_pourcent(int min, int max, int v) {
// interpolation
float x0 = min;
float x1 = max;
float y0 = 0;
float y1 = 100;
float xp = v;
float yp = y0 + ((y1 - y0) / (x1 - x0)) * (xp - x0);
return (int)yp;
}
uint8_t BAYER_PATTERN_4[4][4] = {{15, 135, 45, 165}, {195, 75, 225, 105}, {60, 180, 30, 150}, {240, 120, 210, 90}};
void draw_gradient(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, uint8_t color_start, uint8_t color_end, uint8_t tres) {
bool invert = color_start > color_end;
if (invert) {
color_start = 255 - color_start;
color_end = 255 - color_end;
}
int step = (100 / tres);
int step_minus = (100 / (tres - 1));
int distance = color_end - color_start;
for (uint8_t i = 0; i < width; i++) {
int position = interpo_pourcent(0, width, i);
float color = position;
color = ((int)(color / step)) * step_minus;
color = color_start + ((distance * color) / 100);
for (uint8_t j = 0; j < heigth; j++) {
uint8_t m = BAYER_PATTERN_4[i % 4][j % 4];
unsigned char color_d = (color > m) ? !invert : invert;
oled_write_pixel(x + i, y + j, color_d);
}
}
}
void render_tv_animation(uint8_t frame_number, uint8_t x, uint8_t y, uint8_t width, uint8_t heigth) {
uint8_t xCenter = x + (width / 2);
uint8_t yCenter = y + (heigth / 2);
switch (frame_number) {
case 0:
// a fond : allume
drawline_hr_heigth(x, yCenter, width, 17, true);
break;
case 1:
drawline_hr_heigth(x, yCenter, width, 12, true);
draw_ellipse_fill(xCenter, yCenter, 7, 15, true);
break;
case 2:
drawline_hr_heigth(x, yCenter, width, 5, true);
draw_ellipse_fill(xCenter, yCenter, 5, 8, true);
break;
case 3:
drawline_hr_heigth(x, yCenter, width, 3, true);
draw_ellipse_fill(xCenter, yCenter, 3, 4, true);
break;
case 4:
drawline_hr_heigth(x, yCenter, width, 2, true);
draw_fill_circle(xCenter, yCenter, 3, true);
break;
case 5:
// central line
drawline_hr(x, yCenter, width, true);
draw_fill_circle(xCenter, yCenter, 2, true);
break;
case 6:
// cross
drawline_hr(xCenter, yCenter + 1, 2, true);
drawline_hr(xCenter, yCenter - 1, 2, true);
// central line
drawline_hr(x, yCenter, width, true);
break;
case 7:
// cross
drawline_hr(xCenter, yCenter + 1, 2, true);
drawline_hr(xCenter, yCenter - 1, 2, true);
// central line
drawline_hr(xCenter - 8, yCenter, 18, true);
// static
oled_write_pixel(xCenter - 11, yCenter, true);
oled_write_pixel(xCenter + 12, yCenter, true);
break;
case 8:
// cross
drawline_hr(xCenter, yCenter + 1, 2, true);
drawline_hr(xCenter, yCenter - 1, 2, true);
// central line
drawline_hr(xCenter - 2, yCenter, 4, true);
// static
drawline_hr(xCenter - 7, yCenter, 2, true);
drawline_hr(xCenter + 6, yCenter, 3, true);
// oled_write_pixel(xCenter - 11, yCenter, true);
oled_write_pixel(xCenter - 9, yCenter, true);
oled_write_pixel(xCenter + 12, yCenter, true);
oled_write_pixel(xCenter + 14, yCenter, true);
break;
case 9:
// central line
drawline_hr(xCenter, yCenter, 2, true);
break;
}
}

View File

@ -1,47 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// Copyright 2021 ugfx
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// line
void drawline_vb(uint8_t x, uint8_t y, uint8_t width, bool color);
void drawline_vt(uint8_t x, uint8_t y, uint8_t width, bool color);
void drawline_hr(uint8_t x, uint8_t y, uint8_t width, bool color);
void drawline_hl(uint8_t x, uint8_t y, uint8_t width, bool color);
void drawline_hr_heigth(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, bool color);
// rectangle
void draw_rectangle(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, bool color);
void draw_rectangle_fill(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, bool color);
void draw_gradient(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, uint8_t color_start, uint8_t color_end, uint8_t tres);
// circle
void draw_fill_circle(short x, short y, uint8_t radius, bool color);
void draw_circle(uint8_t x, uint8_t y, uint8_t radius, bool color);
void draw_ellipse(uint8_t x, uint8_t y, uint8_t a, uint8_t b, bool color);
void draw_ellipse_fill(uint8_t x, uint8_t y, uint8_t a, uint8_t b, bool color);
void draw_arc_sector(uint8_t x, uint8_t y, uint8_t radius, unsigned char sectors, unsigned char half, bool color);
void draw_static(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, int color, uint8_t density);
// text
void draw_random_char(uint8_t column, uint8_t row, char final_char, int value, uint8_t style);
void draw_label(const char *data, uint8_t len, uint8_t row, int value);
void draw_box(const char *data, uint8_t len, uint8_t row, long value, uint8_t style);
void draw_progress(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, int value, uint8_t style, bool color);
// oled drivers stuff
char get_oled_char(uint16_t start_index);
void oled_write_cursor(uint8_t col, uint8_t line, const char *data, bool invert);
void oled_write_raw_P_cursor(uint8_t col, uint8_t line, const char *data, uint16_t size);
// pixel manipulation
void copy_pixel(int from, int shift, unsigned char mask);
void move_block(uint8_t x, uint8_t y, uint8_t width, uint8_t heigth, int shift);
void draw_glitch_comb(uint8_t x, uint8_t y, uint8_t width, uint16_t height, uint8_t iSize, bool odd);
// misc
void render_tv_animation(uint8_t frame_number, uint8_t x, uint8_t y, uint8_t width, uint8_t heigth);
int interpo_pourcent(int min, int max, int v);
void get_glitch_index(uint32_t *glitch_timer, int *current_glitch_scope_time, uint8_t *glitch_index, uint8_t min_time, uint16_t max_time, uint8_t glitch_probobility, uint8_t glitch_frame_number);
void get_glitch_index_new(uint16_t *glitch_timer, uint8_t *current_glitch_scope_time, uint8_t *glitch_index, uint8_t min_time, uint16_t max_time, uint8_t glitch_probobility, uint8_t glitch_frame_number);

View File

@ -1,17 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#include "fast_random.h"
// seed for random
static unsigned long g_seed = 0;
int fastrand(void) {
// todo : try with random16();
g_seed = (214013 * g_seed + 2531011);
return (g_seed >> 16) & 0x7FFF;
}
unsigned long fastrand_long(void) {
g_seed = (214013 * g_seed + 2531011);
return g_seed;
}

View File

@ -1,7 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
int fastrand(void);
unsigned long fastrand_long(void);

View File

@ -1,71 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
#include "gui_state.h"
#include "draw_helper.h"
// timer for the gui state
uint32_t global_sleep_timer = 0;
uint32_t global_waking_up_timer = 0;
uint32_t global_booting_timer = 0;
// timers test for states
#ifdef WITH_BOOT
static bool IsBooting(void) { return (timer_elapsed32(global_booting_timer) < BOOTING_TIME_TRESHOLD); }
#else
static bool IsBooting(void) { return false; }
#endif
// state test
static bool IsWakingUp(void) { return (timer_elapsed32(global_waking_up_timer) < WAKING_UP_TIME_TRESHOLD); }
static bool IsIdle(void) { return (timer_elapsed32(global_sleep_timer) > IDLE_TIME_TRESHOLD && timer_elapsed32(global_sleep_timer) < HALTING_TIME_TRESHOLD); }
static bool IsSleep(void) { return (timer_elapsed32(global_sleep_timer) >= SLEEP_TIME_TRESHOLD); }
static bool IsHalting(void) { return (timer_elapsed32(global_sleep_timer) >= HALTING_TIME_TRESHOLD && timer_elapsed32(global_sleep_timer) < SLEEP_TIME_TRESHOLD); }
gui_state_t get_gui_state(void) {
// get gui states by testing timers
if (IsBooting()) return _BOOTING;
if (IsWakingUp()) return _WAKINGUP;
if (IsIdle()) return _IDLE;
if (IsHalting()) return _HALTING;
if (IsSleep()) return _SLEEP;
return _UP;
}
void update_gui_state(void) {
// what to do when a key is pressed
gui_state_t t = get_gui_state();
#ifdef WITH_BOOT
if (t == _SLEEP) {
// booting
global_booting_timer = timer_read32();
}
if (t == _BOOTING) {
// cancel booting
global_booting_timer = 1000000;
}
#else
if (t == _SLEEP) {
// waking up
global_waking_up_timer = timer_read32();
}
#endif
if (t == _IDLE || t == _HALTING || t == _BOOTING) {
// waking up
global_waking_up_timer = timer_read32();
}
// no sleep
global_sleep_timer = timer_read32();
}
uint8_t get_glitch_probability(void) {
// more gliches could occur when halting time is near
return interpo_pourcent(IDLE_TIME_TRESHOLD, HALTING_TIME_TRESHOLD, timer_elapsed32(global_sleep_timer));
}

View File

@ -1,18 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// states timing
#define BOOTING_TIME_TRESHOLD 7000
#define WAKING_UP_TIME_TRESHOLD 300
#define IDLE_TIME_TRESHOLD 4000
#define HALTING_TIME_TRESHOLD IDLE_TIME_TRESHOLD + 6000
#define SLEEP_TIME_TRESHOLD HALTING_TIME_TRESHOLD + 8000
typedef uint8_t gui_state_t;
enum gui_state { _WAKINGUP = 0, _IDLE, _SLEEP, _UP, _BOOTING, _HALTING };
gui_state_t get_gui_state(void);
void update_gui_state(void);
uint8_t get_glitch_probability(void);

283
keymap.c
View File

@ -1,192 +1,143 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
#include "transactions.h"
// global // this is for oled bongo cat
#include "boot.h" char wpm_str[16];
#include "gui_state.h"
#include "navi_logo.h"
#include "draw_helper.h" enum layer_number {
#include "fast_random.h" _QWERTY = 0,
_LOWER,
// left side _RAISE,
#include "burst.h" _BLANK,
#include "layer_frame.h"
// right side
#include "ring.h"
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[0] = LAYOUT(KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_QUOT, KC_LSFT, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT, KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC, KC_RBRC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_BSLS, KC_LGUI, KC_LALT, MO(1), KC_SPC, KC_SPC, MO(2), KC_RALT, KC_RCTL),
[1] = LAYOUT(KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_GRV, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_BRID, KC_BRIU, KC_MPRV, KC_MNXT, KC_NO, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_NO, KC_NO, KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_MSTP, KC_LPRN, KC_NO, KC_NO, KC_RPRN, KC_EQL, KC_MINS, KC_NO, KC_DEL, KC_BSLS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS),
[2] = LAYOUT(KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_7, KC_8, KC_9, KC_NO, KC_F11, KC_F12, KC_TRNS, KC_NO, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_4, KC_5, KC_6, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_1, KC_2, KC_3, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_0, KC_TRNS)
}; };
// clang-format on
// sync transport const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {[0] = LAYOUT(KC_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_QUOT, KC_LSFT, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT, KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_LBRC, KC_RBRC, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_BSLS, KC_LGUI, KC_LAPO, MO(1), KC_SPC, KC_SPC, MO(2), KC_RAPC, KC_RCTL),
typedef struct _sync_keycode_t { [1] = LAYOUT(KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_GRV, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_BRID, KC_BRIU, KC_MPRV, KC_MNXT, KC_NO, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_NO, KC_NO, KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_MSTP, KC_LPRN, KC_NO, KC_NO, KC_RPRN, KC_EQL, KC_MINS, KC_NO, KC_DEL, KC_BSLS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS),
uint16_t keycode; [2] = LAYOUT(KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_F11, KC_F12, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_NO, KC_TRNS, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS)};
} sync_keycode_t;
// force rigth side to update layer_state_t layer_state_set_user(layer_state_t state) {
bool b_sync_need_send = false; return update_tri_layer_state(state, _LOWER, _RAISE, _BLANK);
}
// last keycode typed // SSD1306 OLED update loop, make sure to enable OLED_DRIVER_ENABLE=yes in
sync_keycode_t last_keycode; // rules.mk
#ifdef OLED_ENABLE
oled_rotation_t oled_init_user(oled_rotation_t rotation) { oled_rotation_t oled_init_user(oled_rotation_t rotation) {
// vertical orientation if (!is_keyboard_master()) return OLED_ROTATION_180; // flips the display 180 degrees if offhand
return OLED_ROTATION_270; return rotation;
} }
void render(gui_state_t t) { // When you add source files to SRC in rules.mk, you can use functions.
// logo const char *read_layer_state(void);
render_logo(t);
#if IS_LEFT // WPM-responsive animation stuff here
// left side # define IDLE_FRAMES 5
render_layer_frame(t); # define IDLE_SPEED 40 // below this wpm value your animation will idle
render_gears();
decay_scope(); // #define PREP_FRAMES 1 // uncomment if >1
render_scope(t);
#endif
#if IS_RIGHT # define TAP_FRAMES 2
// right side # define TAP_SPEED 40 // above this wpm value typing animation to trigger
render_circle(t);
#endif
}
void update(uint16_t keycode) { # define ANIM_FRAME_DURATION 200 // how long each frame lasts in ms
#if IS_LEFT # define SLEEP_TIMER 60000 // should sleep after this period of 0 wpm, needs
update_scope(); // fixing
#endif # define ANIM_SIZE \
640 // number of bytes in array, minimize for adequate firmware size, max is
// 1024
#if IS_RIGHT uint32_t anim_timer = 0;
update_circle(keycode); uint32_t anim_sleep = 0;
#endif uint8_t current_idle_frame = 0;
} uint8_t current_tap_frame = 0;
void reset(void) { static void render_anim(void) {
#if IS_LEFT // Idle animation
reset_scope(); static const char PROGMEM idle[IDLE_FRAMES][ANIM_SIZE] = {{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, 128, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 4, 4, 4, 8, 48, 64, 128, 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, 128, 128, 128, 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, 24, 100, 130, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 48, 48, 0, 192, 193, 193, 194, 4, 8, 16, 32, 64, 128, 0, 0, 0, 128, 128, 128, 128, 64, 64, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0,
#endif 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, 192, 56, 4, 3, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 13, 1, 0, 64, 160, 33, 34, 18, 17, 17, 17, 9, 8, 8, 8, 8, 4, 4, 8, 8, 16, 16, 16, 16, 16, 17, 15, 1, 1, 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, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 4, 4, 8, 8, 8, 8, 8, 7, 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},
#if IS_RIGHT {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, 128, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 4, 4, 4, 8, 48, 64, 128, 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, 128, 128, 128, 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, 24, 100, 130, 2, 2, 2, 2, 2, 1, 0, 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 48, 48, 0, 192, 193, 193, 194, 4, 8, 16, 32, 64, 128, 0, 0, 0, 128, 128, 128, 128, 64, 64, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 0, 0, 0,
reset_ring(); 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, 192, 56, 4, 3, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 13, 1, 0, 64, 160, 33, 34, 18, 17, 17, 17, 9, 8, 8, 8, 8, 4, 4, 8, 8, 16, 16, 16, 16, 16, 17, 15, 1, 1, 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, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 4, 4, 8, 8, 8, 8, 8, 7, 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},
#endif
}
void set_wackingup_mode_clean(void) { {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, 128, 128, 64, 64, 64, 64, 32, 32, 32, 32, 16, 8, 4, 2, 2, 4, 24, 96, 128, 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, 128, 128, 128, 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, 60, 194, 1, 1, 2, 2, 4, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 96, 0, 129, 130, 130, 132, 8, 16, 32, 64, 128, 0, 0, 0, 0, 128, 128, 128, 128, 64, 64, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 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, 128, 112, 25, 6, 0, 0, 0, 0, 0, 0, 0, 24, 24, 24, 27, 3, 0, 64, 160, 34, 36, 20, 18, 18, 18, 11, 8, 8, 8, 8, 5, 5, 9, 9, 16, 16, 16, 16, 16, 17, 15, 1, 1, 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, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 4, 4, 8, 8, 8, 8, 8, 7, 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, 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, 128, 128, 0, 0, 0, 0, 0, 128, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 4, 2, 1, 1, 2, 12, 48, 64, 128, 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, 128, 128, 128, 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, 30, 225, 0, 0, 1, 1, 2, 2, 1, 0, 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 48, 48, 0, 192, 193, 193, 194, 4, 8, 16, 32, 64, 128, 0, 0, 0, 128, 128, 128, 128, 64, 64, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 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, 128, 112, 12, 3, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 13, 1, 0, 64, 160, 33, 34, 18, 17, 17, 17, 9, 8, 8, 8, 8, 4, 4, 8, 8, 16, 16, 16, 16, 16, 17, 15, 1, 1, 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, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 4, 4, 8, 8, 8, 8, 8, 7, 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, 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, 128, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 8, 4, 2, 2, 2, 4, 56, 64, 128, 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, 128, 128, 128, 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, 28, 226, 1, 1, 2, 2, 2, 2, 1, 0, 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 48, 48, 0, 192, 193, 193, 194, 4, 8, 16, 32, 64, 128, 0, 0, 0, 128, 128, 128, 128, 64, 64, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 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, 128, 112, 12, 3, 0, 0, 0, 0, 0, 0, 0, 12, 12, 12, 13, 1, 0, 64, 160, 33, 34, 18, 17, 17, 17, 9, 8, 8, 8, 8, 4, 4, 8, 8, 16, 16, 16, 16, 16, 17, 15, 1, 1, 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, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 4, 4, 8, 8, 8, 8, 8, 7, 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}};
// Prep animation
static const char PROGMEM prep[][ANIM_SIZE] = {
{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, 128, 128, 0, 0, 0, 0, 0, 128, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 4, 2, 1, 1, 2, 12, 48, 64, 128, 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, 128, 128, 128, 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, 30, 225, 0, 0, 1, 1, 2, 2, 129, 128, 128, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 48, 48, 0, 0, 1, 225, 26, 6, 9, 49, 53, 1, 138, 124, 0, 0, 128, 128, 128, 128, 64, 64, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 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, 128, 112, 12, 3, 0, 0, 24, 6, 5, 152, 153, 132, 195, 124, 65, 65, 64, 64, 32, 33, 34, 18, 17, 17, 17, 9, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 2, 2, 2, 1, 1, 1, 1, 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, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 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}
};
// Typing animation
static const char PROGMEM tap[TAP_FRAMES][ANIM_SIZE] = {
{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, 128, 128, 0, 0, 0, 0, 0, 128, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 4, 2, 1, 1, 2, 12, 48, 64, 128, 0, 0, 0, 0, 0, 0, 0, 248, 248, 248, 248, 0, 0, 0, 0, 0, 128, 128, 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, 128, 128, 128, 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, 30, 225, 0, 0, 1, 1, 2, 2, 129, 128, 128, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 48, 48, 0, 0, 1, 1, 2, 4, 8, 16, 32, 67, 135, 7, 1, 0, 184, 188, 190, 159, 95, 95, 79, 76, 32, 32, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 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, 128, 112, 12, 3, 0, 0, 24, 6, 5, 152, 153, 132, 67, 124, 65, 65, 64, 64, 32, 33, 34, 18, 17, 17, 17, 9, 8, 8, 8, 8, 4, 4, 8, 8, 16, 16, 16, 16, 16, 17, 15, 1, 61, 124, 252, 252, 252, 252, 252, 60, 12, 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, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 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, 1, 3, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 128, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 4, 2, 1, 1, 2, 12, 48, 64, 128, 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, 128, 128, 128, 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, 30, 225, 0, 0, 1, 1, 2, 2, 1, 0, 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 48, 48, 0, 0, 1, 225, 26, 6, 9, 49, 53, 1, 138, 124, 0, 0, 128, 128, 128, 128, 64, 64, 64, 64, 32, 32, 32, 32, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 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, 128, 112, 12, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 64, 160, 33, 34, 18, 17, 17, 17, 9, 8, 8, 8, 8, 4, 4, 4, 4, 4, 4, 2, 2, 2, 1, 1, 1, 1, 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, 128, 128, 128, 128, 128, 64, 64, 64, 64, 64, 32, 32, 32, 32, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 3, 122, 122, 121, 121, 121, 121, 57, 49, 2, 2, 4, 4, 8, 8, 8, 136, 136, 135, 128, 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}
};
// assumes 1 frame prep stage
void animation_phase(void) {
if (get_current_wpm() <= IDLE_SPEED) {
current_idle_frame = (current_idle_frame + 1) % IDLE_FRAMES;
oled_clear(); oled_clear();
reset(); oled_write_raw_P(idle[abs((IDLE_FRAMES - 1) - current_idle_frame)], ANIM_SIZE);
}
if (get_current_wpm() > IDLE_SPEED && get_current_wpm() < TAP_SPEED) {
oled_clear();
// oled_write_raw_P(prep[abs((PREP_FRAMES-1)-current_prep_frame)], ANIM_SIZE); // uncomment if IDLE_FRAMES >1
oled_write_raw_P(prep[0], ANIM_SIZE); // remove if IDLE_FRAMES >1
}
if (get_current_wpm() >= TAP_SPEED) {
current_tap_frame = (current_tap_frame + 1) % TAP_FRAMES;
oled_clear();
oled_write_raw_P(tap[abs((TAP_FRAMES - 1) - current_tap_frame)], ANIM_SIZE);
}
}
if (get_current_wpm() != 0) {
if (timer_elapsed(anim_timer) > ANIM_FRAME_DURATION) {
anim_timer = timer_read();
animation_phase();
}
anim_sleep = timer_read();
} else {
if (timer_elapsed(anim_timer) > ANIM_FRAME_DURATION) {
anim_timer = timer_read();
animation_phase();
}
if (timer_elapsed(anim_sleep) > SLEEP_TIMER) {
// oled_off();
}
}
} }
bool oled_task_user(void) { bool oled_task_user(void) {
gui_state_t t = get_gui_state(); if (is_keyboard_master()) {
oled_set_cursor(0, 1);
// in sleep mode => turn display off uint8_t n = get_current_wpm();
if (t == _SLEEP) { char wpm_counter[4];
oled_off(); wpm_counter[3] = '\0';
return false; wpm_counter[2] = '0' + n % 10;
} wpm_counter[1] = (n /= 10) % 10 ? '0' + (n) % 10 : (n / 10) % 10 ? '0' : ' ';
wpm_counter[0] = n / 10 ? '0' + n / 10 : ' ';
// not in sleep mode => screen is on oled_write_P(PSTR("WPM: "), false);
oled_on(); oled_write(wpm_counter, false);
oled_set_cursor(0, 3);
#ifdef WITH_BOOT { oled_write_ln(read_layer_state(), false); }
// in booting mode => display booting animation } else {
if (t == _BOOTING) { render_anim();
bool boot_finished = render_boot();
if (boot_finished) {
// end of the boot : wacking up
set_wackingup_mode_clean();
update_gui_state();
} }
return false; return false;
}
#endif
// in halting mode => display booting animation
if (t == _HALTING) {
render_halt();
return false;
}
render(t);
return false;
} }
#endif // OLED_DRIVER_ENABLE
void process_key(uint16_t keycode) {
// update screen with the new key
update(keycode);
gui_state_t t = get_gui_state();
if (t == _IDLE) {
// wake up animation
reset();
}
if (t == _BOOTING || t == _HALTING) {
// cancel booting or halting : waking_up
set_wackingup_mode_clean();
}
if (t == _SLEEP) {
// boot sequence
set_wackingup_mode_clean();
reset_boot();
}
update_gui_state();
}
void user_sync_a_slave_handler(uint8_t in_buflen, const void *in_data, uint8_t out_buflen, void *out_data) {
const sync_keycode_t *m2s = (const sync_keycode_t *)in_data;
// get the last char typed on left side and update the right side
process_key(m2s->keycode);
}
void keyboard_post_init_user(void) {
// callback for tranport sync data
transaction_register_rpc(USER_SYNC_A, user_sync_a_slave_handler);
}
void housekeeping_task_user(void) {
// only for master side
if (!is_keyboard_master()) return;
// only if a new char was typed
if (!b_sync_need_send) return;
// send the char to the slave side : sync is done
if (transaction_rpc_send(USER_SYNC_A, sizeof(last_keycode), &last_keycode)) {
b_sync_need_send = false;
}
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
if (record->event.pressed) {
// master : store keycode to sent to the other side to be process_key
last_keycode.keycode = keycode;
b_sync_need_send = true;
// gui process the input
process_key(keycode);
}
return true;
}
#if IS_LEFT
layer_state_t layer_state_set_user(layer_state_t state) {
// update the frame with the layer name
update_layer_frame(state);
return state;
}
#endif

View File

@ -1,105 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
#include "gui_state.h"
#include "layer_frame.h"
#include "draw_helper.h"
#define ANIM_LAYER_FRAME_DURATION 2
#define ANIM_LAYER_FRAME_MAX 7
// current layer
uint8_t current_layer = _QWERTY;
// layer animation stuff
uint16_t anim_layer_frame_timer = 0;
uint8_t current_layer_frame = ANIM_LAYER_FRAME_MAX;
uint8_t layer_frame_destination = ANIM_LAYER_FRAME_MAX;
// layer name for display
const char* layer_name;
static const char* layer_ref[3] = {LAYER_NAME_0, LAYER_NAME_1, LAYER_NAME_2};
void update_layer_frame(layer_state_t state) {
// reset timer
anim_layer_frame_timer = timer_read();
// direction for animation base on layer selected
current_layer = get_highest_layer(state);
if (current_layer == _QWERTY) {
layer_frame_destination = 0;
} else {
layer_frame_destination = ANIM_LAYER_FRAME_MAX;
}
}
static void draw_black_screen(void) {
// clean frame center
draw_rectangle_fill(3, 42, 26, 20, false);
drawline_hr(17, 62, 12, false);
}
void render_gears(void) {
// 64 bytes, 8x8 font, 8 characters, 32x16 image, 4 columns, 2 rows
static const char PROGMEM raw_logo[] = {
0, 6, 6, 54, 118, 96, 230, 192, 192, 128, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 18, 226, 2, 18, 226, 2, 18, 226, 2, 1, 0, 0, 0, 0, 0, 128, 128, 128, 185, 187, 187, 131, 128, 184, 128, 128, 128, 128, 128, 128, 128, 128, 128, 191, 128, 128, 191, 128, 128, 191, 128, 0,
};
// extra line for complete the gui
oled_write_raw_P_cursor(0, 8, raw_logo, sizeof(raw_logo));
}
void render_layer_frame(gui_state_t t) {
// 96 bytes, 8x8 font, 12 characters, 32x24 image, 4 columns, 3 rows
static const char PROGMEM raw_logo[] = {
62, 1, 0, 56, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 124, 248, 241, 226, 4, 8, 240, 0, 28, 28, 28, 0, 0, 127, 4, 8, 16, 127, 0, 124, 18, 17, 18, 124, 0, 31, 32, 64, 32, 31, 0, 0, 0, 0, 255, 255, 0, 0, 255, 62, 64, 64, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 142, 30, 62, 126, 126, 70, 70, 126, 70, 70, 126, 70, 70, 127, 127, 0, 0, 255,
};
oled_write_raw_P_cursor(0, 5, raw_logo, sizeof(raw_logo));
// extra line for complete the gui
drawline_hr(2, 39, 25, 1);
if (current_layer_frame != layer_frame_destination) {
if (timer_elapsed(anim_layer_frame_timer) > ANIM_LAYER_FRAME_DURATION) {
anim_layer_frame_timer = timer_read();
if (layer_frame_destination > current_layer_frame) {
current_layer_frame++;
} else {
current_layer_frame--;
}
}
// black screen
draw_black_screen();
// gradient animation on layer selection
draw_gradient(3, 42, current_layer_frame * 4, 10, 0, 255, 7);
draw_gradient(3 + (27 - current_layer_frame * 4), 57, current_layer_frame * 4, 6, 255, 0, 7);
drawline_hr(3, 46, 22, false);
drawline_hr(3, 47, 23, false);
draw_rectangle_fill(3, 55, 24, 2, false);
draw_rectangle_fill(24, 48, 3, 7, false);
draw_rectangle_fill(3, 60, 12, 2, false);
oled_write_pixel(15, 61, false);
drawline_hr(14, 62, 3, false);
drawline_hr(14, 62, 3, false);
drawline_hr(3, 62, 11, true);
}
// get current layer name
layer_name = layer_ref[current_layer];
// gui on pause : no layer name on screen
if (t == _IDLE || t == _SLEEP || t == _WAKINGUP) {
layer_name = " ";
}
// display layer name in the frame
oled_write_cursor(1, 6, layer_name, false);
}

View File

@ -1,15 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
// layer name : must be 3 chars
#define LAYER_NAME_0 "ABC"
#define LAYER_NAME_1 "NAV"
#define LAYER_NAME_2 "SPE"
enum layer_number { _QWERTY = 0, _LOWER, _RAISE };
void render_gears(void);
void render_layer_frame(gui_state_t t);
void update_layer_frame(layer_state_t state);

1634
lily58_rev1_lily58minh.hex Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,139 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
// This is the 'classic' fixed-space bitmap font for Adafruit_GFX since 1.0.
// See gfxfont.h for newer custom bitmap font info.
#include "progmem.h"
// Standard ASCII 5x7 font
const unsigned char font[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x42, 0x3A, 0x12, 0x12, 0x0E, 0x00,
0x0C, 0x44, 0x47, 0x24, 0x1C, 0x00,
0x24, 0x24, 0x14, 0x7F, 0x04, 0x00,
0x42, 0x3F, 0x02, 0x22, 0x1E, 0x00,
0x0A, 0x0A, 0x7F, 0x0A, 0x0A, 0x00,
0x02, 0x47, 0x42, 0x22, 0x1F, 0x00,
0x21, 0x15, 0x09, 0x15, 0x63, 0x00,
0x44, 0x44, 0x3F, 0x04, 0x04, 0x00,
0x22, 0x1A, 0x02, 0x7F, 0x12, 0x00,
0x22, 0x22, 0x12, 0x0A, 0x06, 0x00,
0x08, 0x47, 0x42, 0x22, 0x1E, 0x00,
0x10, 0x52, 0x54, 0x30, 0x16, 0x00,
0x40, 0x3A, 0x02, 0x3E, 0x42, 0x00,
0x5E, 0x52, 0x52, 0x52, 0x5E, 0x00,
0x04, 0x27, 0x44, 0x44, 0x3C, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x77, 0x00, 0x77, 0x00, 0x77, 0x00,
0x14, 0x22, 0x7F, 0x22, 0x14, 0x00,
0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0x00,
0x06, 0x09, 0x7F, 0x01, 0x7F, 0x00,
0x00, 0x66, 0x89, 0x95, 0x6A, 0x00,
0x60, 0x60, 0x60, 0x60, 0x60, 0x00,
0x94, 0xA2, 0xFF, 0xA2, 0x94, 0x00,
0x08, 0x04, 0x7E, 0x04, 0x08, 0x00,
0x10, 0x20, 0x7E, 0x20, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x1C, 0x1C, 0x1C, 0x00, 0x00,
0x00, 0x08, 0x1C, 0x08, 0x00, 0x00,
0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x5F, 0x00, 0x00, 0x00,
0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
0x14, 0x7F, 0x14, 0x7F, 0x14, 0x00,
0x24, 0x2A, 0x7F, 0x2A, 0x12, 0x00,
0x23, 0x13, 0x08, 0x64, 0x62, 0x00,
0x36, 0x49, 0x56, 0x20, 0x50, 0x00,
0x00, 0x08, 0x07, 0x03, 0x00, 0x00,
0x00, 0x1C, 0x22, 0x41, 0x00, 0x00,
0x00, 0x41, 0x22, 0x1C, 0x00, 0x00,
0x2A, 0x1C, 0x7F, 0x1C, 0x2A, 0x00,
0x08, 0x08, 0x3E, 0x08, 0x08, 0x00,
0x00, 0x80, 0x70, 0x30, 0x00, 0x00,
0x08, 0x08, 0x08, 0x08, 0x08, 0x00,
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,
0x20, 0x10, 0x08, 0x04, 0x02, 0x00,
0x3E, 0x51, 0x49, 0x45, 0x3E, 0x00,
0x00, 0x42, 0x7F, 0x40, 0x00, 0x00,
0x72, 0x49, 0x49, 0x49, 0x46, 0x00,
0x21, 0x41, 0x49, 0x4D, 0x33, 0x00,
0x18, 0x14, 0x12, 0x7F, 0x10, 0x00,
0x27, 0x45, 0x45, 0x45, 0x39, 0x00,
0x3C, 0x4A, 0x49, 0x49, 0x31, 0x00,
0x41, 0x21, 0x11, 0x09, 0x07, 0x00,
0x36, 0x49, 0x49, 0x49, 0x36, 0x00,
0x46, 0x49, 0x49, 0x29, 0x1E, 0x00,
0x00, 0x00, 0x14, 0x00, 0x00, 0x00,
0x00, 0x40, 0x34, 0x00, 0x00, 0x00,
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,
0x14, 0x14, 0x14, 0x14, 0x14, 0x00,
0x00, 0x41, 0x22, 0x14, 0x08, 0x00,
0x02, 0x01, 0x59, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x5D, 0x59, 0x4E, 0x00,
0x7C, 0x12, 0x11, 0x12, 0x7C, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x36, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x22, 0x00,
0x7F, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x49, 0x49, 0x49, 0x41, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x01, 0x00,
0x3E, 0x41, 0x41, 0x51, 0x73, 0x00,
0x7F, 0x08, 0x08, 0x08, 0x7F, 0x00,
0x00, 0x41, 0x7F, 0x41, 0x00, 0x00,
0x20, 0x40, 0x41, 0x3F, 0x01, 0x00,
0x7F, 0x08, 0x14, 0x22, 0x41, 0x00,
0x7F, 0x40, 0x40, 0x40, 0x40, 0x00,
0x7F, 0x02, 0x1C, 0x02, 0x7F, 0x00,
0x7F, 0x04, 0x08, 0x10, 0x7F, 0x00,
0x3E, 0x41, 0x41, 0x41, 0x3E, 0x00,
0x7F, 0x09, 0x09, 0x09, 0x06, 0x00,
0x3E, 0x41, 0x51, 0x21, 0x5E, 0x00,
0x7F, 0x09, 0x19, 0x29, 0x46, 0x00,
0x26, 0x49, 0x49, 0x49, 0x32, 0x00,
0x03, 0x01, 0x7F, 0x01, 0x03, 0x00,
0x3F, 0x40, 0x40, 0x40, 0x3F, 0x00,
0x1F, 0x20, 0x40, 0x20, 0x1F, 0x00,
0x3F, 0x40, 0x38, 0x40, 0x3F, 0x00,
0x63, 0x14, 0x08, 0x14, 0x63, 0x00,
0x03, 0x04, 0x78, 0x04, 0x03, 0x00,
0x61, 0x59, 0x49, 0x4D, 0x43, 0x00,
0x00, 0x7F, 0x41, 0x41, 0x41, 0x00,
0x02, 0x04, 0x08, 0x10, 0x20, 0x00,
0x00, 0x41, 0x41, 0x41, 0x7F, 0x00,
0x04, 0x02, 0x01, 0x02, 0x04, 0x00,
0x40, 0x40, 0x40, 0x40, 0x40, 0x00,
0x00, 0x03, 0x07, 0x08, 0x00, 0x00,
0x20, 0x54, 0x54, 0x78, 0x40, 0x00,
0x7F, 0x28, 0x44, 0x44, 0x38, 0x00,
0x38, 0x44, 0x44, 0x44, 0x28, 0x00,
0x38, 0x44, 0x44, 0x28, 0x7F, 0x00,
0x38, 0x54, 0x54, 0x54, 0x18, 0x00,
0x00, 0x08, 0x7E, 0x09, 0x02, 0x00,
0x18, 0x24, 0x24, 0x1C, 0x78, 0x00,
0x7F, 0x08, 0x04, 0x04, 0x78, 0x00,
0x00, 0x44, 0x7D, 0x40, 0x00, 0x00,
0x20, 0x40, 0x40, 0x3D, 0x00, 0x00,
0x7F, 0x10, 0x28, 0x44, 0x00, 0x00,
0x00, 0x41, 0x7F, 0x40, 0x00, 0x00,
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,
0x7C, 0x08, 0x04, 0x04, 0x08, 0x00,
0x48, 0x54, 0x54, 0x54, 0x24, 0x00,
0x04, 0x04, 0x3F, 0x44, 0x24, 0x00,
0x3C, 0x40, 0x40, 0x20, 0x7C, 0x00,
0x1C, 0x20, 0x40, 0x20, 0x1C, 0x00,
0x3C, 0x40, 0x30, 0x40, 0x3C, 0x00,
0x44, 0x28, 0x10, 0x28, 0x44, 0x00,
0x4C, 0x90, 0x90, 0x90, 0x7C, 0x00,
0x44, 0x64, 0x54, 0x4C, 0x44, 0x00,
0x00, 0x08, 0x36, 0x41, 0x00, 0x00,
0x00, 0x00, 0x77, 0x00, 0x00, 0x00,
0x00, 0x41, 0x36, 0x08, 0x00, 0x00,
0x02, 0x01, 0x02, 0x04, 0x02, 0x00,
0x3C, 0x26, 0x23, 0x26, 0x3C, 0x00
};

View File

@ -1,117 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
#include "gui_state.h"
#include "navi_logo.h"
#include "fast_random.h"
#include "draw_helper.h"
#define LOGO_SIZE 128
// glitch stuff
#define GLITCH_FRAME_NUMBER 11
uint8_t current_glitch_index = 0;
int current_glitch_time = 150;
uint32_t glitch_timer = 0;
static void render_logo_clean(void) {
// your logo here
static const char PROGMEM raw_logo[] = {
0, 0, 0, 0, 0, 0, 128, 128, 0, 0, 128, 128, 192, 192, 204, 222, 222, 204, 192, 192, 128, 0, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 192, 240, 248, 28, 14, 7, 3, 249, 252, 255, 15, 7, 3, 225, 241, 241, 241, 241, 225, 3, 7, 15, 255, 252, 249, 3, 7, 14, 28, 248, 240, 192, 192, 227, 231, 206, 28, 56, 112, 99, 15, 31, 60, 120, 240, 225, 227, 3, 3, 227, 225, 240, 120, 60, 31, 15, 103, 112, 56, 28, 206, 231, 227, 192, 0, 1, 1, 0, 0, 0, 56, 120, 96, 192, 192, 192, 96, 127, 63, 0, 0, 63, 127, 96, 192, 192, 192, 96, 120, 56, 0, 0, 0, 1, 1, 0,
};
oled_write_raw_P(raw_logo, sizeof(raw_logo));
}
void render_glitch_bar(uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t iProb) {
// random horizontal scanlines
for (uint8_t i = 0; i < height; i++) {
bool bGenerateGlitch = (fastrand() % 100) < iProb;
if (bGenerateGlitch) {
drawline_hr(x, y + i, width, true);
}
}
}
void render_misc_glitch(uint8_t algo) {
char c = 0;
switch (algo) {
case 7:
// invert
for (uint8_t i = 0; i < LOGO_SIZE; i++) {
c = get_oled_char(i);
oled_write_raw_byte(~(c), i);
}
break;
case 8:
// wobble
for (uint8_t i = 0; i < LOGO_SIZE; i++) {
if (i < LOGO_SIZE - 1) {
copy_pixel(i + 1, -1, 85);
copy_pixel(LOGO_SIZE - 1 - 1 - i, 1, 170);
}
}
break;
}
}
static void render_logo_glitch(void) {
#ifdef WITH_GLITCH
// get a random glitch index
uint8_t glitch_prob = get_glitch_probability();
get_glitch_index(&glitch_timer, &current_glitch_time, &current_glitch_index, 0, 150, glitch_prob, GLITCH_FRAME_NUMBER);
// no glitch
if (current_glitch_index <= 3) {
render_logo_clean();
return;
}
// glitch time !
switch (current_glitch_index) {
case 4:
move_block(1, 11, 24, 3, 5);
move_block(2, 19, 14, 3, 4);
move_block(9, 22, 7, 4, 4);
return;
case 5:
move_block(6, 25, 20, 7, 4);
move_block(0, 8, 32, 8, 7);
return;
case 6:
move_block(3, 7, 27, 4, -3);
move_block(13, 23, 19, 4, -4);
return;
case 7:
case 8:
render_misc_glitch(current_glitch_index);
return;
case 9:
render_glitch_bar(0, 0, 32, 32, 25);
return;
case 10:
draw_static(0, 0, 32, 32, true, 0);
return;
}
#endif
}
void render_logo(gui_state_t t) {
if (t == _IDLE) {
// on idle : glitch time !
render_logo_glitch();
return;
}
// standart logo
render_logo_clean();
}

View File

@ -1,7 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
void render_logo(gui_state_t t);

34
nm.json
View File

@ -1,13 +1,13 @@
{ {
"version": 1, "version": 1,
"notes": "My awesome keymap", "notes": "",
"documentation": "\"This file is a QMK Configurator export. You can import this at <https://config.qmk.fm>. It can also be used directly with QMK's source code.\n\nTo setup your QMK environment check out the tutorial: <https://docs.qmk.fm/#/newbs>\n\nYou can convert this file to a keymap.c using this command: `qmk json2c {keymap}`\n\nYou can compile this keymap using this command: `qmk compile {keymap}`\"\n", "documentation": "\"This file is a QMK Configurator export. You can import this at <https://config.qmk.fm>. It can also be used directly with QMK's source code.\n\nTo setup your QMK environment check out the tutorial: <https://docs.qmk.fm/#/newbs>\n\nYou can convert this file to a keymap.c using this command: `qmk json2c {keymap}`\n\nYou can compile this keymap using this command: `qmk compile {keymap}`\"\n",
"keyboard": "lily58/rev1", "keyboard": "lily58/rev1",
"keymap": "lily58_rev1_layout_mine", "keymap": "minhtrannhat",
"layout": "LAYOUT", "layout": "LAYOUT",
"layers": [ "layers": [
[ [
"KC_ESC", "KC_GESC",
"KC_1", "KC_1",
"KC_2", "KC_2",
"KC_3", "KC_3",
@ -58,12 +58,12 @@
"KC_SLSH", "KC_SLSH",
"KC_BSLS", "KC_BSLS",
"KC_LGUI", "KC_LGUI",
"KC_LALT", "KC_LAPO",
"MO(1)", "MO(1)",
"KC_SPC", "KC_SPC",
"KC_SPC", "KC_SPC",
"MO(2)", "MO(2)",
"KC_RALT", "KC_RAPC",
"KC_RCTL" "KC_RCTL"
], ],
[ [
@ -145,22 +145,22 @@
"KC_NO", "KC_NO",
"KC_NO", "KC_NO",
"KC_NO", "KC_NO",
"KC_7", "KC_NO",
"KC_8", "KC_NO",
"KC_9", "KC_NO",
"KC_NO", "KC_NO",
"KC_F11", "KC_F11",
"KC_F12", "KC_F12",
"KC_TRNS", "KC_TRNS",
"KC_NO", "KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_NO",
"KC_LEFT", "KC_LEFT",
"KC_DOWN", "KC_DOWN",
"KC_UP", "KC_UP",
"KC_RGHT", "KC_RGHT",
"KC_4",
"KC_5",
"KC_6",
"KC_NO",
"KC_NO", "KC_NO",
"KC_TRNS", "KC_TRNS",
"KC_TRNS", "KC_TRNS",
@ -171,9 +171,9 @@
"KC_NO", "KC_NO",
"KC_NO", "KC_NO",
"KC_NO", "KC_NO",
"KC_1", "KC_NO",
"KC_2", "KC_NO",
"KC_3", "KC_NO",
"KC_NO", "KC_NO",
"KC_NO", "KC_NO",
"KC_NO", "KC_NO",
@ -183,9 +183,9 @@
"KC_TRNS", "KC_TRNS",
"KC_TRNS", "KC_TRNS",
"KC_TRNS", "KC_TRNS",
"KC_0", "KC_TRNS",
"KC_TRNS" "KC_TRNS"
] ]
], ],
"author": "lily58minh" "author": ""
} }

494
ring.c
View File

@ -1,494 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#include QMK_KEYBOARD_H
#include "gui_state.h"
#include "ring.h"
#include "fast_random.h"
#include "draw_helper.h"
char tListeTotal[SIZE_ARRAY_1] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'};
char tListeTotal2[SIZE_ARRAY_1] = {'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ',', '.', '/', '1', '2', '3'};
static char tRefArc[SIZE_ARRAY_1] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P'};
static char tRefArc2[SIZE_ARRAY_1] = {'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ',', '.', '/', '1', '2', '3'};
// ring target and previous char
char c_target = 'A';
char c_target2 = 'Q';
char c_last = ' ';
char c_previous = ' ';
static const char PROGMEM code_to_name[60] = {' ', ' ', ' ', ' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', 'R', 'E', 'B', 'T', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ';', '\'', ' ', ',', '.', '/', ' ', ' ', ' '};
// main circle
#define CIRCLE_ANIM_FRAME_DURATION 40
uint16_t circle_timer = 0;
// special animation for special keys
#define ANIM_CENTER_FRAME_NUMBER 5
#define ANIM_CENTER_FRAME_DURATION 40
uint16_t anim_center_timer = 0;
uint8_t anim_center_current_frame = 0;
// sleep animation
#define ANIM_SLEEP_RING_FRAME_NUMBER 9
#define ANIM_SLEEP_RING_FRAME_DURATION 20
uint16_t anim_sleep_ring_timer = 0;
uint8_t current_sleep_ring_frame = 0;
uint8_t sleep_ring_frame_destination = ANIM_SLEEP_RING_FRAME_NUMBER - 1;
// glitch animation
uint16_t anim_ring_idle_timer = 0;
int current_glitch_ring_time = 150;
uint32_t glitch_ring_timer = 0;
uint8_t current_glitch_ring_index = 0;
// central frame keylog animation
#define ANIM_KEYLOG_FRAME_NUMBER 8
#define ANIM_KEYLOG_FRAME_DURATION 20
uint8_t anim_keylog_current_frame = 0;
uint16_t anim_keylog_timer = 0;
static const char PROGMEM raw_ring_sleep[4][64] = {{
192, 32, 16, 8, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 8, 16, 32, 192, 3, 4, 8, 16, 32, 32, 32, 64, 64, 64, 64, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 64, 64, 64, 64, 32, 32, 32, 16, 8, 4, 3,
},
{
128, 64, 32, 32, 16, 16, 16, 16, 16, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 32, 32, 64, 128, 0, 1, 2, 2, 4, 4, 4, 4, 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 4, 2, 2, 1, 0,
},
{
248, 192, 128, 128, 128, 128, 128, 128, 128, 0, 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 0, 128, 128, 128, 128, 128, 128, 128, 192, 248, 15, 1, 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, 1, 15,
},
{
255, 240, 128, 128, 0, 128, 128, 0, 0, 128, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 0, 0, 128, 128, 0, 128, 128, 248, 255, 255, 7, 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, 7, 255,
}};
static const char PROGMEM raw_circle[4][128] = {{
0, 0, 0, 192, 32, 16, 8, 8, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 4, 8, 8, 16, 32, 192, 0, 0, 0, 240, 14, 1, 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, 129, 238, 240, 15, 112, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 192, 240, 255, 127, 15, 0, 0, 0, 3, 4, 8, 16, 16, 32, 64, 64, 64, 128, 128, 192, 192, 224, 224, 224, 240, 112, 120, 124, 60, 30, 30, 15, 7, 3, 0, 0, 0,
},
{
0, 0, 0, 192, 32, 16, 8, 8, 4, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 4, 8, 8, 48, 224, 192, 0, 0, 0, 240, 14, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 255, 255, 254, 240, 15, 112, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 192, 224, 240, 248, 248, 254, 255, 255, 127, 15, 0, 0, 0, 3, 7, 15, 31, 30, 62, 126, 126, 126, 254, 254, 254, 254, 254, 255, 255, 255, 127, 127, 127, 63, 31, 31, 15, 7, 3, 0, 0, 0,
},
{
0, 0, 0, 192, 32, 16, 8, 8, 4, 2, 2, 2, 1, 1, 1, 1, 3, 15, 255, 255, 254, 254, 254, 252, 248, 248, 240, 224, 192, 0, 0, 0, 240, 14, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 128, 192, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 254, 240, 15, 126, 252, 248, 248, 248, 248, 248, 252, 252, 254, 254, 255, 255, 255, 255, 255, 255, 255, 127, 63, 31, 15, 7, 7, 3, 3, 3, 7, 143, 127, 15, 0, 0, 0, 3, 7, 15, 31, 31, 63, 127, 127, 127, 255, 255, 255, 255, 255, 255, 195, 128, 64, 64, 64, 32, 16, 16, 8, 4, 3, 0, 0, 0,
},
{
0, 0, 0, 192, 224, 240, 248, 248, 124, 62, 30, 14, 15, 7, 7, 3, 3, 3, 1, 1, 2, 2, 2, 4, 8, 8, 16, 32, 192, 0, 0, 0, 240, 254, 255, 31, 15, 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 14, 240, 15, 115, 128, 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, 128, 112, 15, 0, 0, 0, 3, 4, 8, 16, 16, 32, 64, 64, 64, 128, 128, 128, 128, 128, 128, 128, 128, 64, 64, 64, 32, 16, 16, 8, 4, 3, 0, 0, 0,
}};
static const char PROGMEM raw_bottom[] = {
127, 192, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 192, 127,
};
static const char PROGMEM raw_middle[] = {
240, 8, 4, 226, 241, 248, 124, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 56, 0, 1, 62, 255, 0, 0, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 28, 28, 0, 255, 0, 0, 127, 127, 70, 70, 126, 70, 70, 126, 70, 70, 126, 126, 62, 30, 142, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 64, 64, 62, 1, 2, 114, 114, 2, 2, 114, 114, 2, 2, 114, 114, 2, 2, 2, 2, 1, 0, 0, 0, 128, 64, 64, 64, 64, 64, 64, 64, 64, 64, 128, 0, 0, 128, 131, 131, 132, 136, 179, 131, 132, 184, 131, 131, 188, 128, 128, 128, 128, 128, 128, 128, 143, 144, 149, 144, 149, 144, 149, 144, 149, 144, 143, 0,
};
static void rotate_right(char str[]) {
uint8_t iSize = SIZE_ARRAY_1;
char cFist = str[0];
// rotate array to the right
for (uint8_t i = 0; i < iSize - 1; i++) {
str[i] = str[i + 1];
}
str[iSize - 1] = cFist;
}
static void rotate_left(char str[]) {
uint8_t iSize = SIZE_ARRAY_1;
char cLast = str[iSize - 1];
// rotate array to the left
for (uint8_t i = iSize - 1; i > 0; i--) {
str[i] = str[i - 1];
}
str[0] = cLast;
}
static signed char GetPosition(char c, char tListe[]) {
uint8_t iSize = SIZE_ARRAY_1;
// find position of c in the array
for (uint8_t i = 0; i < iSize; i++) {
if (tListe[i] == c) return i;
}
// not found
return -1;
}
static signed char GetDistance(char cNew, char tListe[]) {
signed char iPositionNew = GetPosition(cNew, tListe);
if (iPositionNew == -1) {
// not found
return 0;
}
return iPositionNew - CURSOR_1;
}
static bool TesterEstDansListe(char c, char tListe[]) {
// char in the list ?
return GetPosition(c, tListe) != -1;
}
static void SmartRotation(char c, char tListe[]) {
signed char i = GetDistance(c, tListe);
if (i == 0) return;
// rotate in the shorter way
if (i < 0) {
rotate_left(tListe);
return;
}
if (i > 0) {
rotate_right(tListe);
return;
}
}
static void update_list(char cNouveau, char tListe[]) {
signed char iDistance = GetDistance(cNouveau, tListe);
if (iDistance != 0) {
// the new char is in the list : rotation
SmartRotation(cNouveau, tListe);
}
}
static void draw_arc_sector_16(uint8_t x, uint8_t y, uint8_t radius, int position, bool color) {
unsigned int s = 1;
s = s << (position / 2);
if (position % 4 == 0 || position % 4 == 3) {
draw_arc_sector(x, y, radius, s, 1, color);
} else {
draw_arc_sector(x, y, radius, s, 2, color);
}
}
static void render_set(uint8_t x, uint8_t y, uint8_t r, int p, bool color) {
// 2 pixels arc sector
draw_arc_sector_16(x, y, r, p, color);
draw_arc_sector_16(x, y, r - 1, p, color);
}
static void draw_letter_circle(char t[], char tRef[], char ct, uint8_t x, uint8_t y, uint8_t r, bool invert) {
char c = t[CURSOR_1];
signed char p = GetPosition(c, tRef);
signed char pt = GetPosition(ct, tRef);
if (!invert) {
draw_fill_circle(x, y, r, false);
draw_circle(x, y, r, false);
draw_circle(x, y, r - 1, false);
draw_circle(x, y, r - 2, false);
draw_circle(x, y, r - 4, true);
draw_circle(x, y, r - 5, true);
}
int pafter = (pt + 1) % SIZE_ARRAY_1;
int pbefore = (pt + SIZE_ARRAY_1 - 1) % SIZE_ARRAY_1;
render_set(x, y, r, pt, true);
render_set(x, y, r, pafter, true);
render_set(x, y, r, pbefore, true);
pafter = (pt + 2) % SIZE_ARRAY_1;
pbefore = (pt + SIZE_ARRAY_1 - 2) % SIZE_ARRAY_1;
render_set(x, y, r, pafter, true);
render_set(x, y, r, pbefore, true);
r -= 4;
pafter = (p + 1) % SIZE_ARRAY_1;
pbefore = (p + SIZE_ARRAY_1 - 1) % SIZE_ARRAY_1;
render_set(x, y, r, p, false);
render_set(x, y, r, pafter, false);
render_set(x, y, r, pbefore, false);
draw_circle(x, y, r - 6, true);
}
static void draw_center_circle_frame(uint8_t x, uint8_t y, uint8_t r, uint8_t f) {
draw_fill_circle(x, y, r, 0);
draw_circle(x, y, r, 0);
if (f == 0) {
draw_circle(x, y, r, 1);
} else {
// animation
oled_write_raw_P_cursor(0, 11, raw_circle[f - 1], sizeof(raw_circle[f - 1]));
}
}
static void render_anim_center_circle(uint8_t x, uint8_t y, uint8_t r) {
if (anim_center_current_frame == ANIM_CENTER_FRAME_NUMBER) {
// last frame : no animation
return;
}
if (timer_elapsed(anim_center_timer) > ANIM_CENTER_FRAME_DURATION) {
anim_center_timer = timer_read();
draw_center_circle_frame(x, y, r, anim_center_current_frame);
anim_center_current_frame++;
}
}
static void write_char(char c) {
// write keylog char in the frame then offset to center
oled_set_cursor(2, 6);
oled_write_char(c, false);
move_block(12, 48, 6, 8, 2);
}
static void render_keylog(gui_state_t t) {
if (anim_keylog_current_frame != ANIM_KEYLOG_FRAME_NUMBER) {
if (timer_elapsed(anim_keylog_timer) > ANIM_KEYLOG_FRAME_DURATION) {
// update frame number
anim_keylog_timer = timer_read();
anim_keylog_current_frame++;
}
// clean frame
draw_rectangle_fill(7, 46, 21, 11, false);
// comb motion to merge current and previous
if (anim_keylog_current_frame < ANIM_KEYLOG_FRAME_NUMBER / 2) {
// expand the previous char
write_char(c_previous);
draw_glitch_comb(9, 6 * 8, 18, 8, anim_keylog_current_frame + 1, true);
} else {
// shrink the current char
write_char(c_last);
draw_glitch_comb(9, 6 * 8, 18, 8, ANIM_KEYLOG_FRAME_NUMBER - anim_keylog_current_frame, false);
}
return;
}
write_char(c_last);
}
void reset_ring(void) {
// need to open
anim_sleep_ring_timer = timer_read();
current_sleep_ring_frame = ANIM_SLEEP_RING_FRAME_NUMBER - 1;
sleep_ring_frame_destination = 0;
}
static void render_tv_circle(uint8_t x, uint8_t y, uint8_t r, uint8_t f) {
// raw image
if (f == 2 || f == 3) {
oled_write_raw_P_cursor(0, 12, raw_ring_sleep[f - 2], sizeof(raw_ring_sleep[f - 2]));
return;
}
// raw image
if (f == 5 || f == 6) {
oled_write_raw_P_cursor(0, 12, raw_ring_sleep[f - 3], sizeof(raw_ring_sleep[f - 3]));
return;
}
// other frames : lighter to draw than using raw image
switch (f) {
case 1:
draw_circle(x, y, r, 1);
break;
case 4:
drawline_hr(1, y, 12, 1);
drawline_hr(19, y, 12, 1);
drawline_vb(0, y - 1, 3, true);
drawline_vb(31, y - 1, 3, true);
break;
case 7:
oled_write_pixel(1, y, true);
oled_write_pixel(3, y, true);
oled_write_pixel(28, y, true);
oled_write_pixel(30, y, true);
drawline_vb(0, y - 12, 26, true);
drawline_vb(31, y - 12, 26, true);
break;
case 8:
drawline_vb(0, 88, 32, true);
drawline_vb(31, 88, 32, true);
break;
}
}
static void render_circle_white(void) {
// top
oled_write_raw_P_cursor(0, 5, raw_middle, sizeof(raw_middle));
drawline_hr(5, 39, 25, 1);
// clean center
draw_rectangle_fill(0, 80, 32, 40, false);
// bottom
drawline_vb(0, 80, 8, 1);
drawline_vb(31, 80, 8, 1);
oled_write_pixel(1, 80, true);
oled_write_pixel(30, 80, true);
oled_write_raw_P_cursor(0, 15, raw_bottom, sizeof(raw_bottom));
}
static void render_ring_clean_close(void) {
render_circle_white();
drawline_vb(0, 88, 32, true);
drawline_vb(31, 88, 32, true);
}
static void render_glitch_square(void) {
if (timer_elapsed(anim_ring_idle_timer) > 60) {
anim_ring_idle_timer = timer_read();
render_ring_clean_close();
uint8_t size = 0;
for (uint8_t i = 0; i < 4; i++) {
size = 4 + (fastrand() % 6);
draw_rectangle_fill(3 + (fastrand() % 19), 85 + (fastrand() % 20), size, size, true);
size = (fastrand() % 6);
draw_rectangle_fill(3 + (fastrand() % 19), 100 + (fastrand() % 20), size, size, true);
}
}
}
static void render_ring_idle(void) {
uint8_t glitch_prob = get_glitch_probability();
get_glitch_index(&glitch_ring_timer, &current_glitch_ring_time, &current_glitch_ring_index, 150, 350, glitch_prob, 2);
switch (current_glitch_ring_index) {
case 0:
// no glitch
render_ring_clean_close();
return;
case 1:
// square gliches
render_glitch_square();
return;
}
}
static void render_ring_sleep(void) {
if (current_sleep_ring_frame == sleep_ring_frame_destination) {
// no more animation needes : render the idle animation
render_ring_idle();
return;
}
// display wacking up / sleep animation
if (timer_elapsed(anim_sleep_ring_timer) > ANIM_SLEEP_RING_FRAME_DURATION) {
anim_sleep_ring_timer = timer_read();
// clean + new frame
render_circle_white();
render_tv_circle(15, 103, 11, current_sleep_ring_frame);
// update frame number
if (sleep_ring_frame_destination > current_sleep_ring_frame) {
current_sleep_ring_frame++;
} else {
current_sleep_ring_frame--;
}
}
}
static void render_circle_middle(void) {
// clean
render_circle_white();
// center special animation
if (anim_center_current_frame < ANIM_CENTER_FRAME_NUMBER) {
render_anim_center_circle(15, 103, 15 - 4);
return;
}
// ring render
if (anim_center_current_frame == ANIM_CENTER_FRAME_NUMBER) {
draw_letter_circle(tListeTotal, tRefArc, c_target, 15, 103, 15, false);
draw_letter_circle(tListeTotal2, tRefArc2, c_target2, 15, 103, 15, true);
}
}
void render_circle(gui_state_t t) {
if (timer_elapsed(circle_timer) > CIRCLE_ANIM_FRAME_DURATION) {
// new frame
circle_timer = timer_read();
// shift rings
update_list(c_target, tListeTotal);
update_list(c_target2, tListeTotal2);
// waking up animation
if (t == _WAKINGUP) {
render_ring_sleep();
return;
}
// idle animation
if (t == _IDLE) {
sleep_ring_frame_destination = ANIM_SLEEP_RING_FRAME_NUMBER - 1;
render_ring_sleep();
return;
}
// render on display
render_circle_middle();
render_keylog(t);
}
}
void update_circle(uint16_t keycode) {
// special animation for special keys
if (keycode == KC_ESC || keycode == KC_SPACE || keycode == KC_ENTER) {
anim_center_timer = timer_read();
anim_center_current_frame = 0;
return;
}
// cancel special animation on a new key
anim_center_current_frame = ANIM_CENTER_FRAME_NUMBER;
// out of scope key
if (keycode >= 60) {
return;
}
// keycode to char
char c = pgm_read_byte(&code_to_name[keycode]);
// stock previous char
c_previous = c_last;
c_last = c;
// start keylog animation
anim_keylog_current_frame = 0;
// update target in ring #1 position
if (TesterEstDansListe(c, tListeTotal)) {
c_target = c;
return;
}
// update target in #2 position
if (TesterEstDansListe(c, tListeTotal2)) {
c_target2 = c;
return;
}
}

11
ring.h
View File

@ -1,11 +0,0 @@
// Copyright 2021 Nicolas Druoton (druotoni)
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#define SIZE_ARRAY_1 16
#define CURSOR_1 9
void update_circle(uint16_t);
void render_circle(gui_state_t t);
void reset_ring(void);

View File

@ -2,18 +2,6 @@
# change to "no" to disable the options, or define them in the Makefile in # change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically # the appropriate keymap folder that will get included automatically
# #
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight.
# Bootloader selection
BOOTLOADER = atmel-dfu
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
LTO_ENABLE = yes
SPACE_CADET_ENABLE = no
GRAVE_ESC_ENABLE = no
MAGIC_ENABLE = no
EXTRAKEY_ENABLE = yes
BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration BOOTMAGIC_ENABLE = no # Virtual DIP switch configuration
MOUSEKEY_ENABLE = no # Mouse keys MOUSEKEY_ENABLE = no # Mouse keys
CONSOLE_ENABLE = no # Console for debug CONSOLE_ENABLE = no # Console for debug
@ -26,16 +14,17 @@ UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight.
SWAP_HANDS_ENABLE = no # Enable one-hand typing SWAP_HANDS_ENABLE = no # Enable one-hand typing
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
DEBOUNCE_TYPE = sym_defer_g WPM_ENABLE = yes
SPLIT_KEYBOARD = yes
OLED_ENABLE= yes # OLED display
EXTRAKEY_ENABLE = yes
EXTRAFLAGS += -flto
BOOTLOADER = atmel-dfu
CONFIG_USB_ACM = yes
DEBOUNCE_TYPE = sym_eager_pk
# If you want to change the display of OLED, you need to change here # If you want to change the display of OLED, you need to change here
SRC += ./burst.c \ SRC += ./lib/layer_state_reader.c
./navi_logo.c \
./gui_state.c \
./fast_random.c \
./layer_frame.c \
./ring.c \
./boot.c \
./draw_helper.c \