summaryrefslogtreecommitdiffstats
path: root/keyboards/lily58/keymaps/druotoni/ring.c
blob: e3b7472872ee526fa00baa1b6c26a8eba754fc95 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
// 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;
    }
}