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`
This commit is contained in:
Dien-Nhung Nguyen 2024-09-17 20:18:37 +07:00 committed by GitHub
parent ea14dd8ac5
commit 2a730ef9f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 78 additions and 22 deletions

View File

@ -141,9 +141,11 @@ int ani_xbm_scrollup_inf(xbm_t *xbm, uint16_t *fb,
return ++i;
}
void ani_scroll_x(bm_t *bm, uint16_t *fb, int dir)
int ani_scroll_x(bm_t *bm, uint16_t *fb, int dir)
{
int x = mod(bm->anim_step, bm->width + LED_COLS) - LED_COLS;
int total_steps = bm->width + LED_COLS;
int step = mod(bm->anim_step, total_steps);
int x = step - LED_COLS;
bm->anim_step += (dir) ? -1 : 1;
for (int i = 0; i < LED_COLS; i++) {
@ -153,16 +155,17 @@ void ani_scroll_x(bm_t *bm, uint16_t *fb, int dir)
}
fb[i] = (i + x) >= 0 ? bm->buf[i + x] : 0;
}
return mod(bm->anim_step, total_steps); // How many steps left until restart again
}
void ani_scroll_left(bm_t *bm, uint16_t *fb)
int ani_scroll_left(bm_t *bm, uint16_t *fb)
{
ani_scroll_x(bm, fb, 0);
return ani_scroll_x(bm, fb, 0);
}
void ani_scroll_right(bm_t *bm, uint16_t *fb)
int ani_scroll_right(bm_t *bm, uint16_t *fb)
{
ani_scroll_x(bm, fb, 1);
return ani_scroll_x(bm, fb, 1);
}
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)
{
int frame_steps = LED_ROWS * 3; // in-still-out
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
int total_steps = frame_steps * frames;
int frame = mod(bm->anim_step, total_steps)/frame_steps;
int y = mod(bm->anim_step, frame_steps);
@ -197,16 +201,28 @@ void ani_scroll_y(bm_t *bm, uint16_t *fb)
}
}
void ani_scroll_up(bm_t *bm, uint16_t *fb)
int ani_scroll_up(bm_t *bm, uint16_t *fb)
{
ani_scroll_y(bm, fb);
int frame_steps = LED_ROWS * 3; // in-still-out
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
int total_steps = frame_steps * frames;
bm->anim_step++;
return mod(bm->anim_step, total_steps);
}
void ani_scroll_down(bm_t *bm, uint16_t *fb)
int ani_scroll_down(bm_t *bm, uint16_t *fb)
{
ani_scroll_y(bm, fb);
int frame_steps = LED_ROWS * 3; // in-still-out
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
int total_steps = frame_steps * frames;
bm->anim_step--;
return mod(bm->anim_step, total_steps);
}
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)
}
}
void ani_laser(bm_t *bm, uint16_t *fb)
int ani_laser(bm_t *bm, uint16_t *fb)
{
int frame_steps = LED_COLS * 3; // in-still-out
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
int total_steps = frame_steps * frames;
int frame = mod(bm->anim_step, total_steps)/frame_steps;
int c = mod(bm->anim_step, frame_steps);
bm->anim_step++;
@ -273,6 +290,8 @@ void ani_laser(bm_t *bm, uint16_t *fb)
still(bm, fb, frame);
else
laser_out(bm, fb, c - LED_COLS * 2, frame);
return mod(bm->anim_step, total_steps);
}
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)
}
}
void ani_snowflake(bm_t *bm, uint16_t *fb)
int ani_snowflake(bm_t *bm, uint16_t *fb)
{
int frame_steps = LED_ROWS * 6; // in-still-out, each costs 2xLED_ROWS step
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
int total_steps = frame_steps * frames;
int frame = mod(bm->anim_step, total_steps)/frame_steps;
int c = mod(bm->anim_step, frame_steps);
bm->anim_step++;
@ -348,27 +368,35 @@ void ani_snowflake(bm_t *bm, uint16_t *fb)
} else {
snowflake_out(bm, fb, -(c - LED_ROWS * 4), frame);
}
return mod(bm->anim_step, total_steps);
}
void ani_animation(bm_t *bm, uint16_t *fb)
int ani_animation(bm_t *bm, uint16_t *fb)
{
int frame_steps = ANI_ANIMATION_STEPS;
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
int total_steps = frame_steps * frames;
int frame = mod(bm->anim_step, total_steps)/frame_steps;
bm->anim_step++;
still(bm, fb, frame);
return mod(bm->anim_step, total_steps);
}
void ani_fixed(bm_t *bm, uint16_t *fb)
int ani_fixed(bm_t *bm, uint16_t *fb)
{
int frame_steps = ANI_FIXED_STEPS;
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS;
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
int total_steps = frame_steps * frames;
int frame = mod(bm->anim_step, total_steps)/frame_steps;
bm->anim_step++;
still(bm, fb, frame);
return mod(bm->anim_step, total_steps);
}
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)
fb[hc - i] = -1;
}
void ani_picture(bm_t *bm, uint16_t *fb)
int ani_picture(bm_t *bm, uint16_t *fb)
{
int last_steps = LED_COLS / 2;
int frame_steps = LED_COLS;
int frames = ALIGN(bm->width, LED_COLS) / LED_COLS + 1;
int total_steps = frame_steps * frames - last_steps;
int frame = mod(bm->anim_step, frame_steps*frames)/frame_steps;
bm->anim_step++;
@ -434,10 +463,13 @@ void ani_picture(bm_t *bm, uint16_t *fb)
/* picture_out() costs only half LED_COLS */
if (mod(bm->anim_step, LED_COLS) >= last_steps) {
bm->anim_step = 0;
return 0;
}
return;
return mod(bm->anim_step, total_steps);
}
picture(bm, fb, bm->anim_step, frame);
return mod(bm->anim_step, total_steps);
}
void ani_marque(bm_t *bm, uint16_t *fb, int step)

View File

@ -45,6 +45,11 @@ bm_t *bmlist_gohead()
return current;
}
bm_t *bmlist_head()
{
return head;
}
bm_t *bmlist_current()
{
return current;
@ -59,6 +64,10 @@ static void list_del(bm_t *prev, bm_t *next)
bm_t *bmlist_drop(bm_t *bm)
{
list_del(bm->prev, bm->next);
if (bm == head)
head = bm->next;
if (bm == tail)
tail = bm->prev;
return bm->next;
}

View File

@ -36,6 +36,8 @@ bm_t *bmlist_goprev() ;
bm_t *bmlist_gohead();
bm_t *bmlist_current();
bm_t *bmlist_head();
void bmlist_init(uint16_t first_bm_width);
#endif /* __BMLIST_H__ */

View File

@ -50,7 +50,7 @@ enum MODES {
static tmosTaskID common_taskid = INVALID_TASK_ID ;
volatile uint16_t fb[LED_COLS] = {0};
volatile int mode, brightness = 0;
volatile int mode, is_play_sequentially = 1, brightness = 0;
__HIGH_CODE
static void change_brightness()
@ -68,7 +68,17 @@ static void change_mode()
__HIGH_CODE
static void bm_transition()
{
if (is_play_sequentially) {
is_play_sequentially = 0;
bmlist_gohead();
return;
}
bmlist_gonext();
if (bmlist_current() == bmlist_head()) {
is_play_sequentially = 1;
return;
}
}
void play_splash(xbm_t *xbm, int col, int row)
{
@ -126,7 +136,7 @@ static uint16_t common_tasks(tmosTaskID task_id, uint16_t events)
if(events & ANI_NEXT_STEP) {
static void (*animations[])(bm_t *bm, uint16_t *fb) = {
static int (*animations[])(bm_t *bm, uint16_t *fb) = {
ani_scroll_left,
ani_scroll_right,
ani_scroll_up,
@ -140,7 +150,10 @@ static uint16_t common_tasks(tmosTaskID task_id, uint16_t events)
bm_t *bm = bmlist_current();
if (animations[LEGACY_GET_ANIMATION(bm->modes)])
animations[LEGACY_GET_ANIMATION(bm->modes)](bm, fb);
if (animations[LEGACY_GET_ANIMATION(bm->modes)](bm, fb) == 0
&& is_play_sequentially) {
bmlist_gonext();
}
if (bm->is_flash) {
ani_flash(bm, fb, flash_step);