~toykeeper/flashlight-firmware/fsm

« back to all changes in this revision

Viewing changes to ToyKeeper/spaghetti-monster/anduril/tint-ramping.c

  • Committer: Selene ToyKeeper
  • Date: 2023-11-04 15:09:10 UTC
  • mfrom: (483.1.175 anduril2)
  • Revision ID: bzr@toykeeper.net-20231104150910-ddd3afw4nhfvof2l
merged anduril2 branch -> fsm, with *years* of changes
(this also means this code is now Anduril 2 instead of Anduril 1)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// tint-ramping.c: Tint ramping functions for Anduril.
 
2
// Copyright (C) 2017-2023 Selene ToyKeeper
 
3
// SPDX-License-Identifier: GPL-3.0-or-later
 
4
 
 
5
#pragma once
 
6
 
 
7
#include "tint-ramping.h"
 
8
 
 
9
uint8_t tint_ramping_state(Event event, uint16_t arg) {
 
10
    static int8_t tint_ramp_direction = 1;
 
11
    static uint8_t prev_tint = 0;
 
12
    // don't activate auto-tint modes unless the user hits the edge
 
13
    // and keeps pressing for a while
 
14
    static uint8_t past_edge_counter = 0;
 
15
    // bugfix: click-click-hold from off to strobes would invoke tint ramping
 
16
    // in addition to changing state...  so ignore any tint-ramp events which
 
17
    // don't look like they were meant to be here
 
18
    static uint8_t active = 0;
 
19
 
 
20
    // click, click, hold: change the tint
 
21
    if (event == EV_click3_hold) {
 
22
        ///// tint-toggle mode
 
23
        // toggle once on first frame; ignore other frames
 
24
        if (tint_style) {
 
25
            // only respond on first frame
 
26
            if (arg) return EVENT_NOT_HANDLED;
 
27
 
 
28
            // force tint to be 1 or 254
 
29
            if (tint != 254) { tint = 1; }
 
30
            // invert between 1 and 254
 
31
            tint = tint ^ 0xFF;
 
32
            set_level(actual_level);
 
33
            return EVENT_HANDLED;
 
34
        }
 
35
 
 
36
        ///// smooth tint-ramp mode
 
37
        // reset at beginning of movement
 
38
        if (! arg) {
 
39
            active = 1;  // first frame means this is for us
 
40
            past_edge_counter = 0;  // doesn't start until user hits the edge
 
41
        }
 
42
        // ignore event if we weren't the ones who handled the first frame
 
43
        if (! active) return EVENT_HANDLED;
 
44
 
 
45
        // change normal tints
 
46
        if ((tint_ramp_direction > 0) && (tint < 254)) {
 
47
            tint += 1;
 
48
        }
 
49
        else if ((tint_ramp_direction < 0) && (tint > 1)) {
 
50
            tint -= 1;
 
51
        }
 
52
        // if the user kept pressing long enough, go the final step
 
53
        if (past_edge_counter == 64) {
 
54
            past_edge_counter ++;
 
55
            tint ^= 1;  // 0 -> 1, 254 -> 255
 
56
            blip();
 
57
        }
 
58
        // if tint change stalled, let user know we hit the edge
 
59
        else if (prev_tint == tint) {
 
60
            if (past_edge_counter == 0) blip();
 
61
            // count up but don't wrap back to zero
 
62
            if (past_edge_counter < 255) past_edge_counter ++;
 
63
        }
 
64
        prev_tint = tint;
 
65
        set_level(actual_level);
 
66
        return EVENT_HANDLED;
 
67
    }
 
68
 
 
69
    // click, click, hold, release: reverse direction for next ramp
 
70
    else if (event == EV_click3_hold_release) {
 
71
        active = 0;  // ignore next hold if it wasn't meant for us
 
72
        // reverse
 
73
        tint_ramp_direction = -tint_ramp_direction;
 
74
        if (tint <= 1) tint_ramp_direction = 1;
 
75
        else if (tint >= 254) tint_ramp_direction = -1;
 
76
        // remember tint after battery change
 
77
        save_config();
 
78
        // bug?: for some reason, brightness can seemingly change
 
79
        // from 1/150 to 2/150 without this next line... not sure why
 
80
        set_level(actual_level);
 
81
        return EVENT_HANDLED;
 
82
    }
 
83
 
 
84
    return EVENT_NOT_HANDLED;
 
85
}
 
86