Lamp-Da 0.1
A compact lantern project
Loading...
Searching...
No Matches
automaton.hpp
Go to the documentation of this file.
1#ifndef AUTOMATON_MODE_HPP
2#define AUTOMATON_MODE_HPP
3
5
6#include "src/modes/include/draw/grid_rule.hpp"
7
8#include "src/system/ext/random8.h"
9
12
17struct BubbleMode : public BasicMode
18{
21
22 struct StateTy
23 {
27 uint32_t algeaStart;
29 uint32_t algeaLifetime;
31 uint32_t algeaPos;
32 };
33
35 static constexpr int nbBubbles = 4;
37 static constexpr int bubbleFreq = 70;
39 static constexpr int minBubbleDist = 4;
41 static constexpr int eventFreq = 70;
43 static constexpr int algeaFreq = 60;
45 static constexpr int algeaLength = 3000;
47 static constexpr int algeaSwims = 400;
49 static constexpr int starFreq = 3;
50
51 // colors
52 static constexpr auto waterColor = colors::DarkBlue;
53 static constexpr auto algeaColor = colors::ForestGreen;
54 static constexpr auto starColor = colors::Gold;
55
56 static void on_enter_mode(auto& ctx)
57 {
58 // fill the initial automata with zeros +few colored pixels
59 GridTy::LineTy first {};
60 first.fill(waterColor);
61
62 // reset grid object & config
63 ctx.state.grid.reset(ctx.lamp, first);
64
65 // reset stateful events
66 ctx.state.algeaStart = 0;
67
69 ctx.template set_config_bool<ConfigKeys::rampSaturates>(true);
70 }
71
72 static void loop(auto& ctx)
73 {
74 // rng helper
75 uint8_t mini = ctx.get_active_custom_ramp() / 4;
76 uint8_t maxi = 255;
77 auto rng = [&](auto p) LMBD_INLINE {
78 return random8(mini, maxi) < p;
79 };
80
81 // st & lamp for brievty
82 auto& st = ctx.state;
83 auto& lamp = ctx.lamp;
84
85 // callback to update the automaton
86 auto cb = [&](const auto& before, auto& after) {
87 after.fill(waterColor);
88
89 // add randomly bubbles
90 for (size_t I = 0; I < nbBubbles; ++I)
91 {
92 if (rng(bubbleFreq))
93 after[random8(0, after.size())] = colors::fromGrey(0xff);
94 }
95
96 // one pass to remove too crowded stuff
97 int lastBubble = 255;
98 for (int I = 0; I < after.size(); ++I)
99 {
100 // if something above, cancel bubble
101 if (before[I] != waterColor)
102 lastBubble = I;
103
104 if (after[I] == waterColor)
105 continue;
106
107 // if other bubble too close, cancel bubble
108 if (abs(int(lastBubble - I)) < minBubbleDist)
109 {
110 after[I] = waterColor;
111 }
112
113 lastBubble = I;
114 }
115
116 // trigger events
117 if (rng(eventFreq) && rng(eventFreq))
118 {
119 if (rng(starFreq))
120 {
121 after[random8(0, after.size())] = starColor;
122 }
123
124 if (st.algeaStart == 0 && rng(algeaFreq))
125 {
126 st.algeaPos = random8(2, after.size() - 2);
127 st.algeaStart = lamp.now;
128 st.algeaLifetime = random16(algeaLength - 1000, algeaLength + 1000);
129 }
130 }
131
132 // draw oscillating algea if active
133 if (st.algeaStart && st.algeaStart + st.algeaLifetime > lamp.now)
134 {
135 int shift = abs(int(((lamp.now / algeaSwims) % 8) - 3)) - 2; // oscillate -2..+2
136 after[st.algeaPos + shift] = algeaColor;
137 }
138 else
139 {
140 st.algeaStart = 0;
141 }
142 };
143
144 // default grid loop
145 ctx.state.grid.template loop<false>(ctx, cb);
146 }
148 static constexpr bool hasCustomRamp = true;
149};
150
155{
157 {
159 static constexpr bool scrollSkewed = true;
161 static constexpr uint8_t renderBlurAmount = 128;
162 };
165
166 struct StateTy
167 {
170 };
171
172 static void on_enter_mode(auto& ctx)
173 {
174 // fill the initial automata with zeros +few colored pixels
175 GridTy::LineTy first {};
176 first[4] = colors::fromRGB(0x00, 0x00, 0x12);
177 first[5] = colors::fromRGB(0x00, 0x00, 0x23);
178 first[6] = colors::fromRGB(0x00, 0x20, 0x40);
179 first[7] = colors::fromRGB(0x80, 0x80, 0x80);
180 first[8] = colors::fromRGB(0x40, 0x40, 0x00);
181 first[9] = colors::fromRGB(0x23, 0x0c, 0x00);
182 first[10] = colors::fromRGB(0x12, 0x03, 0x00);
183
184 // reset grid object & config
185 ctx.state.grid.reset(ctx.lamp, first);
186 ctx.template set_config_bool<ConfigKeys::rampSaturates>(true);
187 }
188
189 static void loop(auto& ctx)
190 {
191 // setup a callback, use wolframRule's 1-d cellular automata
192 auto cb = [&](const auto& before, auto& after) {
193 draw::grid::wolframRule<90>(before, after);
194 };
195
196 // default grid loop
197 ctx.state.grid.template loop<hasCustomRamp>(ctx, cb);
198 }
199
201 static constexpr bool hasCustomRamp = true;
202};
203
206
207} // namespace lampda::modes::automaton
208
209#endif
Modes implementing cellular automaton using "grid" tools.
Definition: automaton.hpp:11
modes::GroupFor< BubbleMode, SierpinskiMode > AutomatonModes
Storage for the Automaton modes.
Definition: automaton.hpp:205
static constexpr LMBD_INLINE uint32_t fromGrey(uint32_t w)
Return color (w, w, w) as a single uint32_t integer.
Definition: utils.hpp:48
static constexpr LMBD_INLINE uint32_t fromRGB(uint8_t r, uint8_t g, uint8_t b)
Return color (r, g, b) as a single uint32_t integer.
Definition: utils.hpp:24
@ ForestGreen
Definition: palettes.hpp:136
@ DarkBlue
Definition: palettes.hpp:110
@ Gold
Definition: palettes.hpp:139
GroupTy< std::tuple< Modes... > > GroupFor
Group together many different modes::BasicMode.
Definition: group_type.hpp:335
static constexpr N abs(const N a)
absolute of a number
Definition: utils.h:46
Parent object for all custom user modes.
Definition: mode_type.hpp:53
uint32_t algeaStart
time of the latest algae start
Definition: automaton.hpp:27
uint32_t algeaPos
X index of the algae.
Definition: automaton.hpp:31
GridTy grid
cellular automaton
Definition: automaton.hpp:25
uint32_t algeaLifetime
duration of the algae
Definition: automaton.hpp:29
Bubbles rising in the sea. The user ramp control the random generation.
Definition: automaton.hpp:18
static constexpr int algeaLength
(ms) +/- 1s average algea size
Definition: automaton.hpp:45
static constexpr int algeaFreq
0-255 how likely event is algea?
Definition: automaton.hpp:43
static constexpr bool hasCustomRamp
hint manager that we have a custom ramp
Definition: automaton.hpp:148
static constexpr auto starColor
color of ???
Definition: automaton.hpp:54
static constexpr auto algeaColor
color of the algea
Definition: automaton.hpp:53
static constexpr int eventFreq
0-255 how likely are events?
Definition: automaton.hpp:41
static constexpr auto waterColor
color of the water
Definition: automaton.hpp:52
static constexpr int starFreq
0-255 how likely event is star?
Definition: automaton.hpp:49
static void on_enter_mode(auto &ctx)
Definition: automaton.hpp:56
static constexpr int bubbleFreq
0-255 the more the less bubbles
Definition: automaton.hpp:37
static constexpr int minBubbleDist
0-5 min distance of bubbles?
Definition: automaton.hpp:39
static constexpr int algeaSwims
(ms) how fast algea ondulates
Definition: automaton.hpp:47
static constexpr int nbBubbles
0-10 max number of bubble per turn
Definition: automaton.hpp:35
static constexpr uint8_t renderBlurAmount
add more blur
Definition: automaton.hpp:161
static constexpr bool scrollSkewed
scroll the grid skewed (no "bubble" effect
Definition: automaton.hpp:159
GridTy grid
celullar automaton
Definition: automaton.hpp:169
Draw the famous Sierpinski triangle, with an old CCTV effect.
Definition: automaton.hpp:155
static constexpr bool hasCustomRamp
Hint manager that we have a custom ramp.
Definition: automaton.hpp:201
Define the rules for a line.
Definition: grid_rule.hpp:16
Implement a line-based grid pattern, update line per line.
Definition: grid_rule.hpp:49
std::array< uint32_t, width > LineTy
Type of a line array.
Definition: grid_rule.hpp:58
void LMBD_INLINE fill(uint32_t color, uint16_t start, uint16_t end)
(indexable) Fill lamp with target color, from start to end
Definition: lamp_type.hpp:786
volatile const uint32_t now
(physical) The "now" on milliseconds, updated just before loop.
Definition: lamp_type.hpp:1075