From 9f1a2f2d99a46ee88cea84ac882ae063081a29e8 Mon Sep 17 00:00:00 2001 From: Albert Kharisov Date: Mon, 31 Jan 2022 17:09:15 +0400 Subject: [PATCH] [FL-2237] Fix animation frame order, increase its max size (#976) * [FL-2237] Fix animation frame order, increase its max size * Make frame_order variable sized --- .../desktop/animations/animation_manager.h | 2 +- .../desktop/animations/animation_storage.c | 41 +++++++++++++------ assets/compiled/assets_dolphin_blocking.c | 20 ++++++--- assets/compiled/assets_dolphin_internal.c | 12 ++++-- .../flipper/assets/templates/dolphin.c.tmpl | 4 +- 5 files changed, 57 insertions(+), 22 deletions(-) diff --git a/applications/desktop/animations/animation_manager.h b/applications/desktop/animations/animation_manager.h index d86a162c..74f31b8a 100644 --- a/applications/desktop/animations/animation_manager.h +++ b/applications/desktop/animations/animation_manager.h @@ -26,7 +26,7 @@ typedef struct { const FrameBubble* const* frame_bubble_sequences; uint8_t frame_bubble_sequences_count; const Icon icon_animation; - uint8_t frame_order[20]; + const uint8_t* frame_order; uint8_t passive_frames; uint8_t active_frames; uint8_t active_cycles; diff --git a/applications/desktop/animations/animation_storage.c b/applications/desktop/animations/animation_storage.c index 94b23be6..f9a76959 100644 --- a/applications/desktop/animations/animation_storage.c +++ b/applications/desktop/animations/animation_storage.c @@ -209,6 +209,9 @@ static void animation_storage_free_animation(BubbleAnimation** animation) { if(*animation) { animation_storage_free_bubbles(*animation); animation_storage_free_frames(*animation); + if((*animation)->frame_order) { + free((void*)(*animation)->frame_order); + } free(*animation); *animation = NULL; } @@ -268,7 +271,24 @@ static bool animation_storage_load_frames( uint32_t* frame_order, uint8_t width, uint8_t height) { - uint16_t frame_order_size = animation->passive_frames + animation->active_frames; + uint16_t frame_order_count = animation->passive_frames + animation->active_frames; + + /* The frames should go in order (0...N), without omissions */ + size_t max_frame_count = 0; + for(int i = 0; i < frame_order_count; ++i) { + max_frame_count = MAX(max_frame_count, frame_order[i]); + } + + if((max_frame_count >= frame_order_count) || (max_frame_count >= 256 /* max uint8_t */)) { + return false; + } + + Icon* icon = (Icon*)&animation->icon_animation; + FURI_CONST_ASSIGN(icon->frame_count, max_frame_count + 1); + FURI_CONST_ASSIGN(icon->frame_rate, 0); + FURI_CONST_ASSIGN(icon->height, height); + FURI_CONST_ASSIGN(icon->width, width); + icon->frames = furi_alloc(sizeof(const uint8_t*) * icon->frame_count); bool frames_ok = false; File* file = storage_file_alloc(storage); @@ -276,17 +296,10 @@ static bool animation_storage_load_frames( string_t filename; string_init(filename); size_t max_filesize = ROUND_UP_TO(width, 8) * height + 1; - Icon* icon = (Icon*)&animation->icon_animation; - FURI_CONST_ASSIGN(icon->frame_count, frame_order_size); - FURI_CONST_ASSIGN(icon->frame_rate, 0); - FURI_CONST_ASSIGN(icon->height, height); - FURI_CONST_ASSIGN(icon->width, width); - icon->frames = furi_alloc(sizeof(const uint8_t*) * frame_order_size); - - for(int i = 0; i < frame_order_size; ++i) { + for(int i = 0; i < icon->frame_count; ++i) { frames_ok = false; - string_printf(filename, ANIMATION_DIR "/%s/frame_%d.bm", name, frame_order[i]); + string_printf(filename, ANIMATION_DIR "/%s/frame_%d.bm", name, i); if(storage_common_stat(storage, string_get_cstr(filename), &file_info) != FSE_OK) break; if(file_info.size > max_filesize) { @@ -453,14 +466,15 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { uint8_t frames = animation->passive_frames + animation->active_frames; uint32_t count = 0; if(!flipper_file_get_value_count(ff, "Frames order", &count)) break; - if((count != frames) || (frames > COUNT_OF(animation->frame_order))) { + if(count != frames) { FURI_LOG_E(TAG, "Error loading animation: frames order"); break; } u32array = furi_alloc(sizeof(uint32_t) * frames); if(!flipper_file_read_uint32(ff, "Frames order", u32array, frames)) break; + animation->frame_order = furi_alloc(sizeof(uint8_t) * frames); for(int i = 0; i < frames; ++i) { - animation->frame_order[i] = u32array[i]; + FURI_CONST_ASSIGN(animation->frame_order[i], u32array[i]); } /* passive and active frames must be loaded up to this point */ @@ -488,6 +502,9 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { } if(!success) { + if(animation->frame_order) { + free((void*)animation->frame_order); + } free(animation); animation = NULL; } diff --git a/assets/compiled/assets_dolphin_blocking.c b/assets/compiled/assets_dolphin_blocking.c index a14b8c5f..9ea09e2f 100644 --- a/assets/compiled/assets_dolphin_blocking.c +++ b/assets/compiled/assets_dolphin_blocking.c @@ -36,6 +36,8 @@ const uint8_t *_A_L0_NoDb_128x51[] = { +const uint8_t L0_NoDb_128x51_frame_order[] = { 0, 1, 2, 3 }; + const BubbleAnimation BA_L0_NoDb_128x51 = { .icon_animation = { .width = 128, @@ -44,7 +46,7 @@ const BubbleAnimation BA_L0_NoDb_128x51 = { .frame_rate = 2, .frames = _A_L0_NoDb_128x51 }, - .frame_order = { 0, 1, 2, 3 }, + .frame_order = L0_NoDb_128x51_frame_order, .passive_frames = 4, .active_frames = 0, .active_cooldown = 0, @@ -76,6 +78,8 @@ const uint8_t *_A_L0_SdBad_128x51[] = { +const uint8_t L0_SdBad_128x51_frame_order[] = { 0, 1 }; + const BubbleAnimation BA_L0_SdBad_128x51 = { .icon_animation = { .width = 128, @@ -84,7 +88,7 @@ const BubbleAnimation BA_L0_SdBad_128x51 = { .frame_rate = 2, .frames = _A_L0_SdBad_128x51 }, - .frame_order = { 0, 1 }, + .frame_order = L0_SdBad_128x51_frame_order, .passive_frames = 2, .active_frames = 0, .active_cooldown = 0, @@ -128,6 +132,8 @@ const uint8_t *_A_L0_SdOk_128x51[] = { +const uint8_t L0_SdOk_128x51_frame_order[] = { 0, 1, 2, 3 }; + const BubbleAnimation BA_L0_SdOk_128x51 = { .icon_animation = { .width = 128, @@ -136,7 +142,7 @@ const BubbleAnimation BA_L0_SdOk_128x51 = { .frame_rate = 2, .frames = _A_L0_SdOk_128x51 }, - .frame_order = { 0, 1, 2, 3 }, + .frame_order = L0_SdOk_128x51_frame_order, .passive_frames = 4, .active_frames = 0, .active_cooldown = 0, @@ -180,6 +186,8 @@ const uint8_t *_A_L0_Url_128x51[] = { +const uint8_t L0_Url_128x51_frame_order[] = { 0, 1, 2, 3 }; + const BubbleAnimation BA_L0_Url_128x51 = { .icon_animation = { .width = 128, @@ -188,7 +196,7 @@ const BubbleAnimation BA_L0_Url_128x51 = { .frame_rate = 2, .frames = _A_L0_Url_128x51 }, - .frame_order = { 0, 1, 2, 3 }, + .frame_order = L0_Url_128x51_frame_order, .passive_frames = 4, .active_frames = 0, .active_cooldown = 0, @@ -232,6 +240,8 @@ const uint8_t *_A_L0_NewMail_128x51[] = { +const uint8_t L0_NewMail_128x51_frame_order[] = { 0, 1, 2, 3, 2, 1 }; + const BubbleAnimation BA_L0_NewMail_128x51 = { .icon_animation = { .width = 128, @@ -240,7 +250,7 @@ const BubbleAnimation BA_L0_NewMail_128x51 = { .frame_rate = 2, .frames = _A_L0_NewMail_128x51 }, - .frame_order = { 0, 1, 2, 3, 2, 1 }, + .frame_order = L0_NewMail_128x51_frame_order, .passive_frames = 6, .active_frames = 0, .active_cooldown = 0, diff --git a/assets/compiled/assets_dolphin_internal.c b/assets/compiled/assets_dolphin_internal.c index 99cab819..373a2873 100644 --- a/assets/compiled/assets_dolphin_internal.c +++ b/assets/compiled/assets_dolphin_internal.c @@ -104,6 +104,8 @@ const FrameBubble L1_Tv_128x47_bubble_1_0 = { +const uint8_t L1_Tv_128x47_frame_order[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + const BubbleAnimation BA_L1_Tv_128x47 = { .icon_animation = { .width = 128, @@ -112,7 +114,7 @@ const BubbleAnimation BA_L1_Tv_128x47 = { .frame_rate = 2, .frames = _A_L1_Tv_128x47 }, - .frame_order = { 0, 1, 2, 3, 4, 5, 6, 7 }, + .frame_order = L1_Tv_128x47_frame_order, .passive_frames = 6, .active_frames = 2, .active_cooldown = 5, @@ -170,6 +172,8 @@ const FrameBubble L1_BadBattery_128x47_bubble_0_0 = { +const uint8_t L1_BadBattery_128x47_frame_order[] = { 0, 1 }; + const BubbleAnimation BA_L1_BadBattery_128x47 = { .icon_animation = { .width = 128, @@ -178,7 +182,7 @@ const BubbleAnimation BA_L1_BadBattery_128x47 = { .frame_rate = 2, .frames = _A_L1_BadBattery_128x47 }, - .frame_order = { 0, 1 }, + .frame_order = L1_BadBattery_128x47_frame_order, .passive_frames = 2, .active_frames = 0, .active_cooldown = 0, @@ -260,6 +264,8 @@ const FrameBubble L1_NoSd_128x49_bubble_0_0 = { +const uint8_t L1_NoSd_128x49_frame_order[] = { 0, 1, 0, 1, 0, 2, 3, 4, 3, 5 }; + const BubbleAnimation BA_L1_NoSd_128x49 = { .icon_animation = { .width = 128, @@ -268,7 +274,7 @@ const BubbleAnimation BA_L1_NoSd_128x49 = { .frame_rate = 2, .frames = _A_L1_NoSd_128x49 }, - .frame_order = { 0, 1, 0, 1, 0, 2, 3, 4, 3, 5 }, + .frame_order = L1_NoSd_128x49_frame_order, .passive_frames = 10, .active_frames = 0, .active_cooldown = 0, diff --git a/scripts/flipper/assets/templates/dolphin.c.tmpl b/scripts/flipper/assets/templates/dolphin.c.tmpl index d085678d..633a374e 100644 --- a/scripts/flipper/assets/templates/dolphin.c.tmpl +++ b/scripts/flipper/assets/templates/dolphin.c.tmpl @@ -49,6 +49,8 @@ const FrameBubble {{animation.name}}_bubble_{{bubble["Slot"]}}_{{bubble["_Bubble {% :endfor %} {% :endif %} +const uint8_t {{animation.name}}_frame_order[] = { {{ "%s" % ", ".join(str(i) for i in animation.meta['Frames order']) }} }; + const BubbleAnimation BA_{{animation.name}} = { .icon_animation = { .width = {{ animation.meta['Width'] }}, @@ -57,7 +59,7 @@ const BubbleAnimation BA_{{animation.name}} = { .frame_rate = {{ animation.meta['Frame rate'] }}, .frames = _A_{{ animation.name }} }, - .frame_order = { {{ "%s" % ", ".join(str(i) for i in animation.meta['Frames order']) }} }, + .frame_order = {{animation.name}}_frame_order, .passive_frames = {{ animation.meta['Passive frames'] }}, .active_frames = {{ animation.meta['Active frames'] }}, .active_cooldown = {{ animation.meta['Active cooldown'] }},