From 15abca894949f5e0b80416ed72697b8a529de9d4 Mon Sep 17 00:00:00 2001 From: Leeroy <135471162+LeeroysHub@users.noreply.github.com> Date: Wed, 29 Nov 2023 23:45:59 +1100 Subject: [PATCH] Animations Menu: Create list from SD Card, no more hard coded menu! any manifest_XXX.txt file will be added to the list for user selection, XXX is name in menu. --- .../desktop/animations/animation_storage.c | 47 +++-------- .../scenes/cfw_app_scene_interface_desktop.c | 78 ++++++++++++++++--- lib/cfw/cfw.h | 2 +- lib/cfw/settings.c | 13 +++- 4 files changed, 89 insertions(+), 51 deletions(-) diff --git a/applications/services/desktop/animations/animation_storage.c b/applications/services/desktop/animations/animation_storage.c index 183388dac8c..7d7ebb5d904 100644 --- a/applications/services/desktop/animations/animation_storage.c +++ b/applications/services/desktop/animations/animation_storage.c @@ -17,27 +17,6 @@ #define ANIMATION_DIR EXT_PATH("dolphin") #define TAG "AnimationStorage" -//Animation Theme Filenames must match the menu! -const char* const anim_style_filenames[AnimStyleCount] = { - "%s/manifest_None.txt", "%s/manifest.txt", - "%s/manifest_Minimal.txt", "%s/manifest_420.txt", - "%s/manifest_42018.txt", "%s/manifest_ALL.txt", - "%s/manifest_Anime.txt", "%s/manifest_Anime420.txt", - "%s/manifest_Anime42018.txt", "%s/manifest_BMO.txt", - "%s/manifest_Cherry.txt", "%s/manifest_CorpLogos.txt", - "%s/manifest_Custom1.txt", "%s/manifest_Custom2.txt", - "%s/manifest_DBZ.txt", "%s/manifest_Digim0n.txt", - "%s/manifest_Dolphin.txt", "%s/manifest_Hackz.txt", - "%s/manifest_Mario.txt", "%s/manifest_Marvel.txt", - "%s/manifest_NYAN.txt", "%s/manifest_OnePiece.txt", - "%s/manifest_P0kemon.txt", "%s/manifest_RM18.txt", - "%s/manifest_RMSelect.txt", "%s/manifest_RMSelect18.txt", - "%s/manifest_SAO.txt", "%s/manifest_Science.txt", - "%s/manifest_SJUMP.txt", "%s/manifest_Squatch.txt", - "%s/manifest_Stock.txt", "%s/manifest_Virus.txt", - "%s/manifest_WatchDogs.txt", "%s/manifest_Leeroy.txt", -}; - static void animation_storage_free_bubbles(BubbleAnimation* animation); static void animation_storage_free_frames(BubbleAnimation* animation); static void animation_storage_free_animation(BubbleAnimation** storage_animation); @@ -57,19 +36,17 @@ static bool animation_storage_load_single_manifest_info( FuriString* anim_manifest; anim_manifest = furi_string_alloc(); - AnimStyle my_anim_style = CFW_SETTINGS()->anim_style; + char* my_manifest_name = CFW_SETTINGS()->manifest_name; //Get the filename to process. - if(my_anim_style < AnimStyleCount) - furi_string_printf(anim_manifest, anim_style_filenames[my_anim_style], ANIMATION_DIR); - else - furi_string_printf(anim_manifest, "%s/manifest.txt", ANIMATION_DIR); + furi_string_printf(anim_manifest, "%s/%s", EXT_PATH("dolphin"), my_manifest_name); //Process the manifest file do { uint32_t u32value; if(FSE_OK != storage_sd_status(storage)) break; - if(!flipper_format_file_open_existing(file, furi_string_get_cstr(anim_manifest))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(anim_manifest))) + if(!flipper_format_file_open_existing(file, "manifest.txt")) break; if(!flipper_format_read_header(file, read_string, &u32value)) break; if(furi_string_cmp_str(read_string, "Flipper Animation Manifest")) break; @@ -122,16 +99,14 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis flipper_format_set_strict_mode(file, true); FuriString* read_string; read_string = furi_string_alloc(); + CfwSettings* cfw_settings = CFW_SETTINGS(); FuriString* anim_manifest; anim_manifest = furi_string_alloc(); - AnimStyle my_anim_style = CFW_SETTINGS()->anim_style; + char* my_manifest_name = cfw_settings->manifest_name; //Get the filename to process. - if(my_anim_style < AnimStyleCount) - furi_string_printf(anim_manifest, anim_style_filenames[my_anim_style], ANIMATION_DIR); - else - furi_string_printf(anim_manifest, "%s/manifest.txt", ANIMATION_DIR); + furi_string_printf(anim_manifest, "%s/%s", EXT_PATH("dolphin"), my_manifest_name); //Process the manifest file. do { @@ -139,7 +114,9 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis StorageAnimation* storage_animation = NULL; if(FSE_OK != storage_sd_status(storage)) break; - if(!flipper_format_file_open_existing(file, furi_string_get_cstr(anim_manifest))) break; + if(!flipper_format_file_open_existing(file, furi_string_get_cstr(anim_manifest))) + if(!flipper_format_file_open_existing(file, "manifest.txt")) break; + if(!flipper_format_read_header(file, read_string, &u32value)) break; if(furi_string_cmp_str(read_string, "Flipper Animation Manifest")) break; do { @@ -342,7 +319,7 @@ static bool animation_storage_load_frames( for(int i = 0; i < icon->frame_count; ++i) { frames_ok = false; - furi_string_printf(filename, ANIMATION_DIR "/%s/frame_%d.bm", name, i); + furi_string_printf(filename, EXT_PATH("dolphin") "/%s/frame_%d.bm", name, i); if(storage_common_stat(storage, furi_string_get_cstr(filename), &file_info) != FSE_OK) break; @@ -494,7 +471,7 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { if(FSE_OK != storage_sd_status(storage)) break; - furi_string_printf(str, ANIMATION_DIR "/%s/" ANIMATION_META_FILE, name); + furi_string_printf(str, EXT_PATH("dolphin") "/%s/" ANIMATION_META_FILE, name); if(!flipper_format_file_open_existing(ff, furi_string_get_cstr(str))) break; if(!flipper_format_read_header(ff, str, &u32value)) break; if(furi_string_cmp_str(str, "Flipper Animation")) break; diff --git a/applications/settings/cfw_app/scenes/cfw_app_scene_interface_desktop.c b/applications/settings/cfw_app/scenes/cfw_app_scene_interface_desktop.c index 781ab68ddcf..8d83d9e51b1 100644 --- a/applications/settings/cfw_app/scenes/cfw_app_scene_interface_desktop.c +++ b/applications/settings/cfw_app/scenes/cfw_app_scene_interface_desktop.c @@ -12,13 +12,7 @@ #define CFW_DESKTOP_SELECT_STEALTH_ICON 9 #define CFW_DESKTOP_SELECT_TOP_BAR 10 -const char* const anim_style_names[AnimStyleCount] = { - "None", "Default", "Minimal", "420", "420+18", "ALL", "Anime", - "Anime+420", "Anime+420+18", "BMO", "Cherry 18+", "Corp Logos", "Custom 1", "Custom 2", - "DBZ", "Digim0n", "Dolphin", "Hackz", "Mario", "Marvel", "NYAN", - "One Piece", "P0kemon", "RM 18+", "RM Select", "RM Select 18+", "SAO", "Science", - "SJUMP", "Squatch", "Stock", "Virus", "WatchDogs", "Leeroy", -}; +#define FILE_NAME_LEN_MAX 256 #define BATTERY_VIEW_COUNT 7 const char* const battery_view_count_text[BATTERY_VIEW_COUNT] = @@ -35,6 +29,11 @@ const uint32_t displayBatteryPercentage_value[BATTERY_VIEW_COUNT] = { uint8_t origBattDisp_value = 0; +//This can move to the model later if needed, but ^^ Battery gets away with it and I dont see the problem with a "global" in a FAP (except for convention) +uint8_t ManifestFileCount; +CharList_t ManifestFileNames; +CharList_t ManifestMenuNames; + #define CFW_DESKTOP_ICON_STYLE_COUNT 2 const char* const icon_style_count_text[CFW_DESKTOP_ICON_STYLE_COUNT] = {"Stock", "Slim"}; @@ -73,8 +72,8 @@ static void cfw_app_scene_interface_desktop_var_item_list_callback(void* context static void cfw_app_scene_interface_desktop_anim_style_changed(VariableItem* item) { CfwApp* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); - variable_item_set_current_value_text(item, anim_style_names[index]); - CFW_SETTINGS()->anim_style = index; + variable_item_set_current_value_text(item, *CharList_get(ManifestMenuNames, index)); + CFW_SETTINGS()->manifest_name = *CharList_get(ManifestFileNames, index); app->save_settings = true; } @@ -169,14 +168,69 @@ void cfw_app_scene_interface_desktop_on_enter(void* context) { origIconStyle_value = app->desktop.icon_style; origBattDisp_value = app->desktop.displayBatteryPercentage; + //Initialization. + ManifestFileCount = 0; + CharList_init(ManifestFileNames); + CharList_init(ManifestMenuNames); + + //Open up Storage. + Storage* storage = furi_record_open(RECORD_STORAGE); + File* folder = storage_file_alloc(storage); + FileInfo info; + char* name = malloc(FILE_NAME_LEN_MAX); + uint8_t current_manifest = 0; + + //Lets walk the dolphin folder and get the filenamess. + if(storage_dir_open(folder, EXT_PATH("dolphin"))) { + while(storage_dir_read(folder, &info, name, FILE_NAME_LEN_MAX)) { + if(!(info.flags & FSF_DIRECTORY)) { + //Get a FuriString for all the string operations. + char* filenametmp = strdup(name); + + //Are we on a manifest> + if(strncasecmp(filenametmp, "manifest", 8) == 0) { + if(strlen(filenametmp) == 12) { + //Add to the list of names. + CharList_push_back(ManifestFileNames, filenametmp); + CharList_push_back(ManifestMenuNames, "Default"); + ManifestFileCount++; + } else { + //Allocate memory for the menuname + char* menuname = malloc(strlen(filenametmp) - 12); + snprintf(menuname, strlen(filenametmp) - 12, "%s", filenametmp + 9); + + //Sanity Check. + if(strcmp(menuname, "") != 0) { + //Add to the list of names. + CharList_push_at(ManifestFileNames, ManifestFileCount, filenametmp); + CharList_push_at(ManifestMenuNames, ManifestFileCount, menuname); + + //Select in menu if its our manifest. + if(strcmp(filenametmp, cfw_settings->manifest_name) == 0) + current_manifest = ManifestFileCount; + + //Count the added Files. + ManifestFileCount++; + } + } + } + } + } + } + + //Close up and free. + free(name); + storage_file_free(folder); + + //Add items to list. item = variable_item_list_add( var_item_list, "Animations", - AnimStyleCount, + ManifestFileCount, cfw_app_scene_interface_desktop_anim_style_changed, app); - variable_item_set_current_value_index(item, cfw_settings->anim_style); - variable_item_set_current_value_text(item, anim_style_names[cfw_settings->anim_style]); + variable_item_set_current_value_index(item, current_manifest); + variable_item_set_current_value_text(item, *CharList_get(ManifestMenuNames, current_manifest)); item = variable_item_list_add( var_item_list, diff --git a/lib/cfw/cfw.h b/lib/cfw/cfw.h index 7ca9cad6e72..4c09e7c51b4 100644 --- a/lib/cfw/cfw.h +++ b/lib/cfw/cfw.h @@ -81,7 +81,7 @@ typedef enum { } UARTChannel; typedef struct { - AnimStyle anim_style; + char* manifest_name; MenuStyle menu_style; MenuStyle game_menu_style; uint32_t start_point; diff --git a/lib/cfw/settings.c b/lib/cfw/settings.c index 131082d6cae..6159f273b49 100644 --- a/lib/cfw/settings.c +++ b/lib/cfw/settings.c @@ -7,7 +7,7 @@ #define TAG "CfwSettings" CfwSettings cfw_settings = { - .anim_style = AnimStyleDefault, // List + .manifest_name = "manifest.txt", // File Name of Manifest to use. .menu_style = MenuStyleList, // List .game_menu_style = MenuStyleWii, // List .start_point = 0, // First Item @@ -31,9 +31,12 @@ void CFW_SETTINGS_LOAD() { CfwSettings* x = &cfw_settings; Storage* storage = furi_record_open(RECORD_STORAGE); FlipperFormat* file = flipper_format_file_alloc(storage); + FuriString* manifest_name = furi_string_alloc(); + if(flipper_format_file_open_existing(file, CFW_SETTINGS_PATH)) { flipper_format_rewind(file); - flipper_format_read_uint32(file, "anim_style", (uint32_t*)&x->anim_style, 1); + flipper_format_read_string(file, "manifest_name", manifest_name); + x->manifest_name = strdup(furi_string_get_cstr(manifest_name)); flipper_format_rewind(file); flipper_format_read_uint32(file, "menu_style", (uint32_t*)&x->menu_style, 1); flipper_format_rewind(file); @@ -66,6 +69,7 @@ void CFW_SETTINGS_LOAD() { flipper_format_rewind(file); flipper_format_read_uint32(file, "lcd_style", (uint32_t*)&x->lcd_style, 1); } + furi_string_free(manifest_name); flipper_format_free(file); furi_record_close(RECORD_STORAGE); @@ -84,7 +88,9 @@ void CFW_SETTINGS_SAVE() { // uint32_t e; // u = x->menu_style; // e = CLAMP(u, MenuStyleCount - 1U, 0U); - flipper_format_write_uint32(file, "anim_style", (uint32_t*)&x->anim_style, 1); + FuriString* manifest_name; + manifest_name = furi_string_alloc_set_str(x->manifest_name); + flipper_format_write_string(file, "manifest_name", manifest_name); flipper_format_write_uint32(file, "menu_style", (uint32_t*)&x->menu_style, 1); flipper_format_write_uint32(file, "game_menu_style", (uint32_t*)&x->game_menu_style, 1); flipper_format_write_uint32(file, "start_point", &x->start_point, 1); @@ -103,6 +109,7 @@ void CFW_SETTINGS_SAVE() { file, "uart_general_channel", (uint32_t*)&x->uart_general_channel, 1); flipper_format_write_bool(file, "rgb_backlight", &x->rgb_backlight, 1); flipper_format_write_uint32(file, "lcd_style", (uint32_t*)&x->lcd_style, 1); + furi_string_free(manifest_name); } flipper_format_free(file); furi_record_close(RECORD_STORAGE);