Skip to content

Commit 2a730ef

Browse files
authored
feat: play all available bitmap slots sequentially (#49)
Resovles: #40 Changes: - Add return step state to animation functions - Add method to get head node from bitmap list - Add auto change to next bitmap depend on `is_play_sequentially`
1 parent ea14dd8 commit 2a730ef

File tree

4 files changed

+78
-22
lines changed

4 files changed

+78
-22
lines changed

src/animation.c

+51-19
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,11 @@ int ani_xbm_scrollup_inf(xbm_t *xbm, uint16_t *fb,
141141
return ++i;
142142
}
143143

144-
void ani_scroll_x(bm_t *bm, uint16_t *fb, int dir)
144+
int ani_scroll_x(bm_t *bm, uint16_t *fb, int dir)
145145
{
146-
int x = mod(bm->anim_step, bm->width + LED_COLS) - LED_COLS;
146+
int total_steps = bm->width + LED_COLS;
147+
int step = mod(bm->anim_step, total_steps);
148+
int x = step - LED_COLS;
147149
bm->anim_step += (dir) ? -1 : 1;
148150

149151
for (int i = 0; i < LED_COLS; i++) {
@@ -153,16 +155,17 @@ void ani_scroll_x(bm_t *bm, uint16_t *fb, int dir)
153155
}
154156
fb[i] = (i + x) >= 0 ? bm->buf[i + x] : 0;
155157
}
158+
return mod(bm->anim_step, total_steps); // How many steps left until restart again
156159
}
157160

158-
void ani_scroll_left(bm_t *bm, uint16_t *fb)
161+
int ani_scroll_left(bm_t *bm, uint16_t *fb)
159162
{
160-
ani_scroll_x(bm, fb, 0);
163+
return ani_scroll_x(bm, fb, 0);
161164
}
162165

163-
void ani_scroll_right(bm_t *bm, uint16_t *fb)
166+
int ani_scroll_right(bm_t *bm, uint16_t *fb)
164167
{
165-
ani_scroll_x(bm, fb, 1);
168+
return ani_scroll_x(bm, fb, 1);
166169
}
167170

168171
void ani_shift_y(bm_t *bm, uint16_t *fb, int y, int frame)
@@ -184,7 +187,8 @@ void ani_scroll_y(bm_t *bm, uint16_t *fb)
184187
{
185188
int frame_steps = LED_ROWS * 3; // in-still-out
186189
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
187-
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
190+
int total_steps = frame_steps * frames;
191+
int frame = mod(bm->anim_step, total_steps)/frame_steps;
188192

189193
int y = mod(bm->anim_step, frame_steps);
190194

@@ -197,16 +201,28 @@ void ani_scroll_y(bm_t *bm, uint16_t *fb)
197201
}
198202
}
199203

200-
void ani_scroll_up(bm_t *bm, uint16_t *fb)
204+
int ani_scroll_up(bm_t *bm, uint16_t *fb)
201205
{
202206
ani_scroll_y(bm, fb);
207+
208+
int frame_steps = LED_ROWS * 3; // in-still-out
209+
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
210+
int total_steps = frame_steps * frames;
203211
bm->anim_step++;
212+
213+
return mod(bm->anim_step, total_steps);
204214
}
205215

206-
void ani_scroll_down(bm_t *bm, uint16_t *fb)
216+
int ani_scroll_down(bm_t *bm, uint16_t *fb)
207217
{
208218
ani_scroll_y(bm, fb);
219+
220+
int frame_steps = LED_ROWS * 3; // in-still-out
221+
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
222+
int total_steps = frame_steps * frames;
209223
bm->anim_step--;
224+
225+
return mod(bm->anim_step, total_steps);
210226
}
211227

212228
static void laser_in(bm_t *bm, uint16_t *fb, int step, int frame)
@@ -258,11 +274,12 @@ static void still(bm_t *bm, uint16_t *fb, int frame)
258274
}
259275
}
260276

261-
void ani_laser(bm_t *bm, uint16_t *fb)
277+
int ani_laser(bm_t *bm, uint16_t *fb)
262278
{
263279
int frame_steps = LED_COLS * 3; // in-still-out
264280
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
265-
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
281+
int total_steps = frame_steps * frames;
282+
int frame = mod(bm->anim_step, total_steps)/frame_steps;
266283

267284
int c = mod(bm->anim_step, frame_steps);
268285
bm->anim_step++;
@@ -273,6 +290,8 @@ void ani_laser(bm_t *bm, uint16_t *fb)
273290
still(bm, fb, frame);
274291
else
275292
laser_out(bm, fb, c - LED_COLS * 2, frame);
293+
294+
return mod(bm->anim_step, total_steps);
276295
}
277296

278297
static uint32_t b16dialate(uint16_t w, int from, int to)
@@ -332,11 +351,12 @@ static void snowflake_out(bm_t *bm, uint16_t *fb, int step, int frame)
332351
}
333352
}
334353

335-
void ani_snowflake(bm_t *bm, uint16_t *fb)
354+
int ani_snowflake(bm_t *bm, uint16_t *fb)
336355
{
337356
int frame_steps = LED_ROWS * 6; // in-still-out, each costs 2xLED_ROWS step
338357
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
339-
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
358+
int total_steps = frame_steps * frames;
359+
int frame = mod(bm->anim_step, total_steps)/frame_steps;
340360

341361
int c = mod(bm->anim_step, frame_steps);
342362
bm->anim_step++;
@@ -348,27 +368,35 @@ void ani_snowflake(bm_t *bm, uint16_t *fb)
348368
} else {
349369
snowflake_out(bm, fb, -(c - LED_ROWS * 4), frame);
350370
}
371+
372+
return mod(bm->anim_step, total_steps);
351373
}
352374

353-
void ani_animation(bm_t *bm, uint16_t *fb)
375+
int ani_animation(bm_t *bm, uint16_t *fb)
354376
{
355377
int frame_steps = ANI_ANIMATION_STEPS;
356378
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
357-
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
379+
int total_steps = frame_steps * frames;
380+
int frame = mod(bm->anim_step, total_steps)/frame_steps;
358381

359382
bm->anim_step++;
360383

361384
still(bm, fb, frame);
385+
386+
return mod(bm->anim_step, total_steps);
362387
}
363388

364-
void ani_fixed(bm_t *bm, uint16_t *fb)
389+
int ani_fixed(bm_t *bm, uint16_t *fb)
365390
{
366391
int frame_steps = ANI_FIXED_STEPS;
367392
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
368-
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
393+
int total_steps = frame_steps * frames;
394+
int frame = mod(bm->anim_step, total_steps)/frame_steps;
369395

370396
bm->anim_step++;
371397
still(bm, fb, frame);
398+
399+
return mod(bm->anim_step, total_steps);
372400
}
373401

374402
static void picture(bm_t *bm, uint16_t *fb, int step, int frame)
@@ -420,11 +448,12 @@ static void picture_out(bm_t *bm, uint16_t *fb, int step)
420448
fb[hc - i] = -1;
421449
}
422450

423-
void ani_picture(bm_t *bm, uint16_t *fb)
451+
int ani_picture(bm_t *bm, uint16_t *fb)
424452
{
425453
int last_steps = LED_COLS / 2;
426454
int frame_steps = LED_COLS;
427455
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS + 1;
456+
int total_steps = frame_steps * frames - last_steps;
428457
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
429458
bm->anim_step++;
430459

@@ -434,10 +463,13 @@ void ani_picture(bm_t *bm, uint16_t *fb)
434463
/* picture_out() costs only half LED_COLS */
435464
if (mod(bm->anim_step, LED_COLS) >= last_steps) {
436465
bm->anim_step = 0;
466+
return 0;
437467
}
438-
return;
468+
return mod(bm->anim_step, total_steps);
439469
}
440470
picture(bm, fb, bm->anim_step, frame);
471+
472+
return mod(bm->anim_step, total_steps);
441473
}
442474

443475
void ani_marque(bm_t *bm, uint16_t *fb, int step)

src/bmlist.c

+9
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,11 @@ bm_t *bmlist_gohead()
4545
return current;
4646
}
4747

48+
bm_t *bmlist_head()
49+
{
50+
return head;
51+
}
52+
4853
bm_t *bmlist_current()
4954
{
5055
return current;
@@ -59,6 +64,10 @@ static void list_del(bm_t *prev, bm_t *next)
5964
bm_t *bmlist_drop(bm_t *bm)
6065
{
6166
list_del(bm->prev, bm->next);
67+
if (bm == head)
68+
head = bm->next;
69+
if (bm == tail)
70+
tail = bm->prev;
6271
return bm->next;
6372
}
6473

src/bmlist.h

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ bm_t *bmlist_goprev() ;
3636
bm_t *bmlist_gohead();
3737
bm_t *bmlist_current();
3838

39+
bm_t *bmlist_head();
40+
3941
void bmlist_init(uint16_t first_bm_width);
4042

4143
#endif /* __BMLIST_H__ */

src/main.c

+16-3
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ enum MODES {
5050
static tmosTaskID common_taskid = INVALID_TASK_ID ;
5151

5252
volatile uint16_t fb[LED_COLS] = {0};
53-
volatile int mode, brightness = 0;
53+
volatile int mode, is_play_sequentially = 1, brightness = 0;
5454

5555
__HIGH_CODE
5656
static void change_brightness()
@@ -68,7 +68,17 @@ static void change_mode()
6868
__HIGH_CODE
6969
static void bm_transition()
7070
{
71+
if (is_play_sequentially) {
72+
is_play_sequentially = 0;
73+
bmlist_gohead();
74+
return;
75+
}
76+
7177
bmlist_gonext();
78+
if (bmlist_current() == bmlist_head()) {
79+
is_play_sequentially = 1;
80+
return;
81+
}
7282
}
7383
void play_splash(xbm_t *xbm, int col, int row)
7484
{
@@ -126,7 +136,7 @@ static uint16_t common_tasks(tmosTaskID task_id, uint16_t events)
126136

127137
if(events & ANI_NEXT_STEP) {
128138

129-
static void (*animations[])(bm_t *bm, uint16_t *fb) = {
139+
static int (*animations[])(bm_t *bm, uint16_t *fb) = {
130140
ani_scroll_left,
131141
ani_scroll_right,
132142
ani_scroll_up,
@@ -140,7 +150,10 @@ static uint16_t common_tasks(tmosTaskID task_id, uint16_t events)
140150

141151
bm_t *bm = bmlist_current();
142152
if (animations[LEGACY_GET_ANIMATION(bm->modes)])
143-
animations[LEGACY_GET_ANIMATION(bm->modes)](bm, fb);
153+
if (animations[LEGACY_GET_ANIMATION(bm->modes)](bm, fb) == 0
154+
&& is_play_sequentially) {
155+
bmlist_gonext();
156+
}
144157

145158
if (bm->is_flash) {
146159
ani_flash(bm, fb, flash_step);

0 commit comments

Comments
 (0)