fix(box): routine bravo without full-screen layer

The end-of-routine "Bravo !" screen wedged the LVGL render task
(task_wdt loop) on this RAM-tight box. Root cause via decoded
backtrace: LV_SCR_LOAD_ANIM_FADE_IN applies opacity to the whole
screen and the star's transform_scale animation both force a
320x240 intermediate layer that the 16-line flush buffer cannot
allocate, hanging lv_draw_layer_alloc_buf.

Use a MOVE_LEFT slide like every other screen and a static star.
This commit is contained in:
L'électron rare
2026-06-21 12:41:51 +02:00
parent 2d17283c5f
commit 3a23c0660f
+10 -24
View File
@@ -385,15 +385,6 @@ static void bravo_auto_return_cb(lv_timer_t *t)
bravo_go_home();
}
// "Pop-in" scale animation for the star. Uses the style transform approach
// (pattern from balloons.c pop_scale_cb) — NOT lv_image_set_scale, which
// leaves the layout box at full size and overflows its cell (see histoires.c).
static void bravo_scale_cb(void *var, int32_t scale)
{
lv_obj_set_style_transform_scale_x((lv_obj_t *)var, scale, 0);
lv_obj_set_style_transform_scale_y((lv_obj_t *)var, scale, 0);
}
static void show_bravo(void)
{
lv_obj_t *scr = lv_obj_create(NULL);
@@ -407,18 +398,11 @@ static void show_bravo(void)
lv_obj_set_size(star, 140, 140);
lv_image_set_inner_align(star, LV_IMAGE_ALIGN_CONTAIN);
lv_obj_align(star, LV_ALIGN_CENTER, 0, -40);
// Pivot at centre so the scale grows in-place.
lv_obj_set_style_transform_pivot_x(star, 70, 0);
lv_obj_set_style_transform_pivot_y(star, 70, 0);
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, star);
lv_anim_set_exec_cb(&a, bravo_scale_cb);
lv_anim_set_values(&a, LV_SCALE_NONE / 3, LV_SCALE_NONE); // 0.33x → 1x
lv_anim_set_duration(&a, 400);
lv_anim_set_path_cb(&a, lv_anim_path_overshoot);
lv_anim_start(&a);
// NB: deliberately NO transform/scale animation. A style transform_scale
// forces LVGL to render the star into an intermediate layer; on this
// RAM-tight BOX-3 (16-line flush buffer) that layer allocation wedges the
// render task → task_wdt (the "crash at end of routine"). The screen-load
// slide is the entrance instead.
// "Bravo !" label (Fredoka large, centred below the star).
lv_obj_t *txt = lv_label_create(scr);
@@ -443,9 +427,11 @@ static void show_bravo(void)
// provided by Tower routine seed
lisael_aac_play_file("/sdcard/routines/bravo.mp3");
// Load with fade; auto_del=true here deletes the outgoing STEP screen,
// which LVGL was already tracking as the active screen.
lv_screen_load_anim(scr, LV_SCR_LOAD_ANIM_FADE_IN, 250, 0, true);
// Slide in (MOVE_LEFT, like every other screen) — NOT FADE_IN: a fade
// applies opacity to the whole screen, forcing a full-screen 320x240 layer
// that wedges the render task on this box. auto_del=true deletes the
// outgoing step screen, which LVGL was already tracking as active.
lv_screen_load_anim(scr, LV_SCR_LOAD_ANIM_MOVE_LEFT, 250, 0, true);
s_step_screen = scr; // track the bravo screen for explicit cleanup on return
// Auto-return after 2.2 s (one-shot timer). The tap handler deletes it.