diff --git a/applications/main/momentum_app/momentum_app.h b/applications/main/momentum_app/momentum_app.h index 8e5196f03..85e4dd318 100644 --- a/applications/main/momentum_app/momentum_app.h +++ b/applications/main/momentum_app/momentum_app.h @@ -1,35 +1,37 @@ #pragma once +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include +#include #include -#include -#include -#include +#include #include #include -#include -#include -#include -#include -#include "scenes/momentum_app_scene.h" -#include "dolphin/helpers/dolphin_state.h" -#include "dolphin/dolphin.h" -#include "dolphin/dolphin_i.h" +#include +#include +#include +#include #include #include -#include +#include +#include +#include +#include +#include +#include #include #include -#include #include -#include -#include -#include +#include +#include ARRAY_DEF(CharList, char*) diff --git a/applications/services/gui/canvas.c b/applications/services/gui/canvas.c index 60f90493a..778d894a7 100644 --- a/applications/services/gui/canvas.c +++ b/applications/services/gui/canvas.c @@ -5,7 +5,8 @@ #include #include #include -#include +#include +#include const CanvasFontParameters canvas_font_params[FontTotalNumber] = { [FontPrimary] = {.leading_default = 12, .leading_min = 11, .height = 8, .descender = 2}, @@ -137,8 +138,8 @@ size_t canvas_current_font_width(const Canvas* canvas) { const CanvasFontParameters* canvas_get_font_params(const Canvas* canvas, Font font) { furi_check(canvas); furi_check(font < FontTotalNumber); - if(asset_packs.font_params[font]) { - return asset_packs.font_params[font]; + if(asset_packs && asset_packs->font_params[font]) { + return asset_packs->font_params[font]; } return &canvas_font_params[font]; } @@ -176,8 +177,8 @@ void canvas_invert_color(Canvas* canvas) { void canvas_set_font(Canvas* canvas, Font font) { furi_check(canvas); u8g2_SetFontMode(&canvas->fb, 1); - if(asset_packs.fonts[font]) { - u8g2_SetFont(&canvas->fb, asset_packs.fonts[font]); + if(asset_packs && asset_packs->fonts[font]) { + u8g2_SetFont(&canvas->fb, asset_packs->fonts[font]); return; } switch(font) { @@ -424,6 +425,7 @@ void canvas_draw_icon_ex( x += canvas->offset_x; y += canvas->offset_y; uint8_t* icon_data = NULL; + icon = asset_packs_swap_icon(icon); compress_icon_decode(canvas->compress_icon, icon_get_frame_data(icon, 0), &icon_data); canvas_draw_u8g2_bitmap( &canvas->fb, x, y, icon_get_width(icon), icon_get_height(icon), icon_data, rotation); @@ -436,6 +438,7 @@ void canvas_draw_icon(Canvas* canvas, int32_t x, int32_t y, const Icon* icon) { x += canvas->offset_x; y += canvas->offset_y; uint8_t* icon_data = NULL; + icon = asset_packs_swap_icon(icon); compress_icon_decode(canvas->compress_icon, icon_get_frame_data(icon, 0), &icon_data); canvas_draw_u8g2_bitmap( &canvas->fb, x, y, icon_get_width(icon), icon_get_height(icon), icon_data, IconRotation0); diff --git a/applications/services/gui/icon_animation.c b/applications/services/gui/icon_animation.c index f456ba368..57beef7ae 100644 --- a/applications/services/gui/icon_animation.c +++ b/applications/services/gui/icon_animation.c @@ -2,11 +2,13 @@ #include "icon_i.h" // IWYU pragma: keep #include +#include IconAnimation* icon_animation_alloc(const Icon* icon) { furi_check(icon); IconAnimation* instance = malloc(sizeof(IconAnimation)); + icon = asset_packs_swap_icon(icon); instance->icon = icon; instance->timer = furi_timer_alloc(icon_animation_timer_callback, FuriTimerTypePeriodic, instance); diff --git a/applications/services/gui/icon_i.h b/applications/services/gui/icon_i.h index 050cf565a..46ceef327 100644 --- a/applications/services/gui/icon_i.h +++ b/applications/services/gui/icon_i.h @@ -14,6 +14,4 @@ struct Icon { const uint8_t frame_count; const uint8_t frame_rate; const uint8_t* const* frames; - - Icon* original; }; diff --git a/applications/services/loader/loader_menu.h b/applications/services/loader/loader_menu.h index 72a9b3cfa..cd0f311a7 100644 --- a/applications/services/loader/loader_menu.h +++ b/applications/services/loader/loader_menu.h @@ -5,6 +5,8 @@ extern "C" { #endif +#define MAINMENU_APPS_PATH CFG_PATH("mainmenu_apps.txt") + typedef struct LoaderMenu LoaderMenu; LoaderMenu* loader_menu_alloc(void (*closed_cb)(void*), void* context, bool settings_only); diff --git a/furi/flipper.c b/furi/flipper.c index 5dbc9d1cd..e5979ffd8 100644 --- a/furi/flipper.c +++ b/furi/flipper.c @@ -33,19 +33,21 @@ static void flipper_print_version(const char* target, const Version* version) { } #ifndef FURI_RAM_EXEC -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include void flipper_migrate_files() { Storage* storage = furi_record_open(RECORD_STORAGE); diff --git a/lib/momentum/asset_packs.c b/lib/momentum/asset_packs.c new file mode 100644 index 000000000..acb3710a4 --- /dev/null +++ b/lib/momentum/asset_packs.c @@ -0,0 +1,252 @@ +#include "asset_packs_i.h" + +#include "settings.h" + +#include +#include +#include +#include +#include + +#define TAG "AssetPacks" + +#define ICONS_FMT ASSET_PACKS_PATH "/%s/Icons/%s" +#define FONTS_FMT ASSET_PACKS_PATH "/%s/Fonts/%s.u8f" + +// See lib/u8g2/u8g2_font.c +#define U8G2_FONT_DATA_STRUCT_SIZE 23 + +AssetPacks* asset_packs = NULL; + +typedef struct { + Icon icon; + uint8_t* frames[]; +} AnimatedIconSwap; + +typedef struct { + int32_t width; + int32_t height; + int32_t frame_rate; + int32_t frame_count; +} FURI_PACKED AnimatedIconMetaFile; + +static void + load_icon_animated(const Icon* original, const char* name, FuriString* path, File* file) { + const char* pack = momentum_settings.asset_pack; + furi_string_printf(path, ICONS_FMT "/meta", pack, name); + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + AnimatedIconMetaFile meta; + bool ok = storage_file_read(file, &meta, sizeof(meta)) == sizeof(meta); + storage_file_close(file); + + if(ok) { + AnimatedIconSwap* swap = + malloc(sizeof(AnimatedIconSwap) + (sizeof(uint8_t*) * meta.frame_count)); + int i = 0; + for(; i < meta.frame_count; i++) { + furi_string_printf(path, ICONS_FMT "/frame_%02d.bm", pack, name, i); + if(storage_file_open( + file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + uint64_t frame_size = storage_file_size(file); + swap->frames[i] = malloc(frame_size); + ok = storage_file_read(file, swap->frames[i], frame_size) == frame_size; + storage_file_close(file); + if(ok) continue; + } else { + storage_file_close(file); + i--; + } + break; + } + + if(i == meta.frame_count) { + FURI_CONST_ASSIGN(swap->icon.width, meta.width); + FURI_CONST_ASSIGN(swap->icon.height, meta.height); + FURI_CONST_ASSIGN(swap->icon.frame_count, meta.frame_count); + FURI_CONST_ASSIGN(swap->icon.frame_rate, meta.frame_rate); + FURI_CONST_ASSIGN_PTR(swap->icon.frames, swap->frames); + + IconSwapList_push_back( + asset_packs->icons, + (IconSwap){ + .original = original, + .replaced = &swap->icon, + }); + } else { + for(; i >= 0; i--) { + free(swap->frames[i]); + } + free(swap); + } + } + } + storage_file_close(file); +} + +typedef struct { + Icon icon; + uint8_t* frames[1]; + uint8_t frame[]; +} StaticIconSwap; + +typedef struct { + int32_t width; + int32_t height; +} FURI_PACKED StaticIconBmxHeader; + +static void + load_icon_static(const Icon* original, const char* name, FuriString* path, File* file) { + furi_string_printf(path, ICONS_FMT ".bmx", momentum_settings.asset_pack, name); + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + StaticIconBmxHeader header; + uint64_t frame_size = storage_file_size(file) - sizeof(header); + StaticIconSwap* swap = malloc(sizeof(StaticIconSwap) + frame_size); + + if(storage_file_read(file, &header, sizeof(header)) == sizeof(header) && + storage_file_read(file, swap->frame, frame_size) == frame_size) { + FURI_CONST_ASSIGN(swap->icon.width, header.width); + FURI_CONST_ASSIGN(swap->icon.height, header.height); + FURI_CONST_ASSIGN(swap->icon.frame_count, 1); + FURI_CONST_ASSIGN(swap->icon.frame_rate, 0); + FURI_CONST_ASSIGN_PTR(swap->icon.frames, swap->frames); + swap->frames[0] = swap->frame; + + IconSwapList_push_back( + asset_packs->icons, + (IconSwap){ + .original = original, + .replaced = &swap->icon, + }); + } else { + free(swap); + } + } + storage_file_close(file); +} + +static void free_icon(const Icon* icon) { + StaticIconSwap* swap = (void*)icon; + // StaticIconSwap and AnimatedIconSwap have similar structure, but + // animated one has frames array of variable length, and frame data is + // in another allocation, while static includes frame in same allocation + // By checking if the first frame points to later in same allocation, we + // can tell if it is static or animated + if(swap->frames[0] != swap->frame) { + for(size_t i = 0; i < swap->icon.frame_count; i++) { + free(swap->frames[i]); + } + } + free(swap); +} + +static void load_font(Font font, const char* name, FuriString* path, File* file) { + furi_string_printf(path, FONTS_FMT, momentum_settings.asset_pack, name); + if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { + uint64_t size = storage_file_size(file); + uint8_t* swap = malloc(size); + + if(size > U8G2_FONT_DATA_STRUCT_SIZE && storage_file_read(file, swap, size) == size) { + asset_packs->fonts[font] = swap; + CanvasFontParameters* params = malloc(sizeof(CanvasFontParameters)); + // See lib/u8g2/u8g2_font.c + params->leading_default = swap[10]; // max_char_height + params->leading_min = params->leading_default - 2; // good enough + params->height = MAX((int8_t)swap[15], 0); // ascent_para + params->descender = MAX((int8_t)swap[16], 0); // descent_para + asset_packs->font_params[font] = params; + } else { + free(swap); + } + } + storage_file_close(file); +} + +static void free_font(Font font) { + free(asset_packs->fonts[font]); + asset_packs->fonts[font] = NULL; + free(asset_packs->font_params[font]); + asset_packs->font_params[font] = NULL; +} + +static const char* font_names[] = { + [FontPrimary] = "Primary", + [FontSecondary] = "Secondary", + [FontKeyboard] = "Keyboard", + [FontBigNumbers] = "BigNumbers", + [FontBatteryPercent] = "BatteryPercent", +}; + +void asset_packs_init(void) { + if(asset_packs) return; + + const char* pack = momentum_settings.asset_pack; + if(pack[0] == '\0') return; + + Storage* storage = furi_record_open(RECORD_STORAGE); + FuriString* p = furi_string_alloc_printf(ASSET_PACKS_PATH "/%s", pack); + FileInfo info; + if(storage_common_stat(storage, furi_string_get_cstr(p), &info) == FSE_OK && + info.flags & FSF_DIRECTORY) { + asset_packs = malloc(sizeof(AssetPacks)); + IconSwapList_init(asset_packs->icons); + + File* f = storage_file_alloc(storage); + + furi_string_printf(p, ASSET_PACKS_PATH "/%s/Icons", pack); + if(storage_common_stat(storage, furi_string_get_cstr(p), &info) == FSE_OK && + info.flags & FSF_DIRECTORY) { + for(size_t i = 0; i < ICON_PATHS_COUNT; i++) { + if(ICON_PATHS[i].icon->frame_count > 1) { + load_icon_animated(ICON_PATHS[i].icon, ICON_PATHS[i].path, p, f); + } else { + load_icon_static(ICON_PATHS[i].icon, ICON_PATHS[i].path, p, f); + } + } + } + + furi_string_printf(p, ASSET_PACKS_PATH "/%s/Fonts", pack); + if(storage_common_stat(storage, furi_string_get_cstr(p), &info) == FSE_OK && + info.flags & FSF_DIRECTORY) { + for(Font font = 0; font < FontTotalNumber; font++) { + load_font(font, font_names[font], p, f); + } + } + + storage_file_free(f); + } + furi_string_free(p); + furi_record_close(RECORD_STORAGE); +} + +void asset_packs_free(void) { + if(!asset_packs) return; + + for + M_EACH(icon_swap, asset_packs->icons, IconSwapList_t) { + free_icon(icon_swap->replaced); + } + IconSwapList_clear(asset_packs->icons); + + for(Font font = 0; font < FontTotalNumber; font++) { + if(asset_packs->fonts[font] != NULL) { + free_font(font); + } + } + + free(asset_packs); + asset_packs = NULL; +} + +const Icon* asset_packs_swap_icon(const Icon* requested) { + if(!asset_packs) return requested; + if((uint32_t)requested < FLASH_BASE || (uint32_t)requested > (FLASH_BASE + FLASH_SIZE)) { + return requested; + } + for + M_EACH(icon_swap, asset_packs->icons, IconSwapList_t) { + if(icon_swap->original == requested) { + return icon_swap->replaced; + } + } + return requested; +} diff --git a/lib/momentum/asset_packs.h b/lib/momentum/asset_packs.h new file mode 100644 index 000000000..76896eaf4 --- /dev/null +++ b/lib/momentum/asset_packs.h @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +#define ASSET_PACKS_PATH EXT_PATH("asset_packs") + +void asset_packs_init(void); +void asset_packs_free(void); diff --git a/lib/momentum/asset_packs_i.h b/lib/momentum/asset_packs_i.h new file mode 100644 index 000000000..2097f5876 --- /dev/null +++ b/lib/momentum/asset_packs_i.h @@ -0,0 +1,21 @@ +#include "asset_packs.h" + +#include + +typedef struct { + const Icon* original; + const Icon* replaced; +} IconSwap; + +LIST_DEF(IconSwapList, IconSwap, M_POD_OPLIST) +#define M_OPL_IconSwapList_t() LIST_OPLIST(IconSwapList) + +typedef struct { + IconSwapList_t icons; + uint8_t* fonts[FontTotalNumber]; + CanvasFontParameters* font_params[FontTotalNumber]; +} AssetPacks; + +extern AssetPacks* asset_packs; + +const Icon* asset_packs_swap_icon(const Icon* requested); diff --git a/lib/momentum/assets.c b/lib/momentum/assets.c deleted file mode 100644 index 8f67fcded..000000000 --- a/lib/momentum/assets.c +++ /dev/null @@ -1,195 +0,0 @@ -#include "momentum.h" -#include -#include -#include -#include -#include - -#define TAG "AssetPacks" - -#define ICONS_FMT ASSET_PACKS_PATH "/%s/Icons/%s" -#define FONTS_FMT ASSET_PACKS_PATH "/%s/Fonts/%s.u8f" - -// See lib/u8g2/u8g2_font.c -#define U8G2_FONT_DATA_STRUCT_SIZE 23 - -AssetPacks asset_packs = { - .fonts = {NULL}, - .font_params = {NULL}, -}; - -static void - load_icon_animated(const Icon* replace, const char* name, FuriString* path, File* file) { - const char* pack = momentum_settings.asset_pack; - furi_string_printf(path, ICONS_FMT "/meta", pack, name); - if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - int32_t icon_width, icon_height, frame_rate, frame_count; - bool ok = - (storage_file_read(file, &icon_width, 4) == 4 && - storage_file_read(file, &icon_height, 4) == 4 && - storage_file_read(file, &frame_rate, 4) == 4 && - storage_file_read(file, &frame_count, 4) == 4); - storage_file_close(file); - - if(ok) { - uint8_t** frames = malloc(sizeof(const uint8_t*) * frame_count); - int i = 0; - for(; i < frame_count; i++) { - furi_string_printf(path, ICONS_FMT "/frame_%02d.bm", pack, name, i); - if(storage_file_open( - file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - uint64_t size = storage_file_size(file); - frames[i] = malloc(size); - ok = storage_file_read(file, frames[i], size) == size; - storage_file_close(file); - if(ok) continue; - } else { - storage_file_close(file); - i--; - } - break; - } - - if(i == frame_count) { - Icon* original = malloc(sizeof(Icon)); - memcpy(original, replace, sizeof(Icon)); - FURI_CONST_ASSIGN_PTR(replace->original, original); - FURI_CONST_ASSIGN(replace->width, icon_width); - FURI_CONST_ASSIGN(replace->height, icon_height); - FURI_CONST_ASSIGN(replace->frame_rate, frame_rate); - FURI_CONST_ASSIGN(replace->frame_count, frame_count); - FURI_CONST_ASSIGN_PTR(replace->frames, frames); - } else { - for(; i >= 0; i--) { - free(frames[i]); - } - free(frames); - } - } - } - storage_file_close(file); -} - -static void load_icon_static(const Icon* replace, const char* name, FuriString* path, File* file) { - furi_string_printf(path, ICONS_FMT ".bmx", momentum_settings.asset_pack, name); - if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - uint64_t size = storage_file_size(file) - 8; - uint8_t* frame = malloc(size); - int32_t icon_width, icon_height; - - if(storage_file_read(file, &icon_width, 4) == 4 && - storage_file_read(file, &icon_height, 4) == 4 && - storage_file_read(file, frame, size) == size) { - Icon* original = malloc(sizeof(Icon)); - memcpy(original, replace, sizeof(Icon)); - FURI_CONST_ASSIGN_PTR(replace->original, original); - uint8_t** frames = malloc(sizeof(const uint8_t*)); - frames[0] = frame; - FURI_CONST_ASSIGN(replace->frame_rate, 0); - FURI_CONST_ASSIGN(replace->frame_count, 1); - FURI_CONST_ASSIGN(replace->width, icon_width); - FURI_CONST_ASSIGN(replace->height, icon_height); - FURI_CONST_ASSIGN_PTR(replace->frames, frames); - } else { - free(frame); - } - } - storage_file_close(file); -} - -static void free_icon(const Icon* icon) { - uint8_t** frames = (void*)icon->frames; - int32_t frame_count = icon->frame_count; - - Icon* original = icon->original; - memcpy((void*)icon, original, sizeof(Icon)); - - free(original); - for(int32_t i = 0; i < frame_count; i++) { - free(frames[i]); - } - free(frames); -} - -static void load_font(Font font, const char* name, FuriString* path, File* file) { - furi_string_printf(path, FONTS_FMT, momentum_settings.asset_pack, name); - if(storage_file_open(file, furi_string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) { - uint64_t size = storage_file_size(file); - uint8_t* swap = malloc(size); - - if(size > U8G2_FONT_DATA_STRUCT_SIZE && storage_file_read(file, swap, size) == size) { - asset_packs.fonts[font] = swap; - CanvasFontParameters* params = malloc(sizeof(CanvasFontParameters)); - // See lib/u8g2/u8g2_font.c - params->leading_default = swap[10]; // max_char_height - params->leading_min = params->leading_default - 2; // good enough - params->height = MAX((int8_t)swap[15], 0); // ascent_para - params->descender = MAX((int8_t)swap[16], 0); // descent_para - asset_packs.font_params[font] = params; - } else { - free(swap); - } - } - storage_file_close(file); -} - -static void free_font(Font font) { - free(asset_packs.fonts[font]); - asset_packs.fonts[font] = NULL; - free(asset_packs.font_params[font]); - asset_packs.font_params[font] = NULL; -} - -static const char* font_names[] = { - [FontPrimary] = "Primary", - [FontSecondary] = "Secondary", - [FontKeyboard] = "Keyboard", - [FontBigNumbers] = "BigNumbers", - [FontBatteryPercent] = "BatteryPercent", -}; - -void asset_packs_init(void) { - const char* pack = momentum_settings.asset_pack; - if(pack[0] == '\0') return; - - Storage* storage = furi_record_open(RECORD_STORAGE); - FuriString* p = furi_string_alloc(); - FileInfo info; - furi_string_printf(p, ASSET_PACKS_PATH "/%s", pack); - if(storage_common_stat(storage, furi_string_get_cstr(p), &info) == FSE_OK && - info.flags & FSF_DIRECTORY) { - File* f = storage_file_alloc(storage); - - for(size_t i = 0; i < ICON_PATHS_COUNT; i++) { - if(ICON_PATHS[i].icon->original == NULL) { - if(ICON_PATHS[i].icon->frame_count > 1) { - load_icon_animated(ICON_PATHS[i].icon, ICON_PATHS[i].path, p, f); - } else { - load_icon_static(ICON_PATHS[i].icon, ICON_PATHS[i].path, p, f); - } - } - } - - for(Font font = 0; font < FontTotalNumber; font++) { - load_font(font, font_names[font], p, f); - } - - storage_file_free(f); - } - furi_string_free(p); - furi_record_close(RECORD_STORAGE); -} - -void asset_packs_free(void) { - for(size_t i = 0; i < ICON_PATHS_COUNT; i++) { - if(ICON_PATHS[i].icon->original != NULL) { - free_icon(ICON_PATHS[i].icon); - } - } - - for(Font font = 0; font < FontTotalNumber; font++) { - if(asset_packs.fonts[font] != NULL) { - free_font(font); - } - } -} diff --git a/lib/momentum/momentum.h b/lib/momentum/momentum.h index 342110bea..754b9db1e 100644 --- a/lib/momentum/momentum.h +++ b/lib/momentum/momentum.h @@ -1,117 +1,13 @@ #pragma once -#include -#include -#include -#include -#include -#include +// Keep momentum.h for backwards compatibility and for SDK header #ifdef __cplusplus extern "C" { #endif -#define MOMENTUM_SETTINGS_PATH CFG_PATH("momentum_settings.txt") -#define ASSET_PACKS_PATH EXT_PATH("asset_packs") -#define MAINMENU_APPS_PATH CFG_PATH("mainmenu_apps.txt") -#define ASSET_PACKS_NAME_LEN 32 - -typedef enum { - BatteryIconOff, - BatteryIconBar, - BatteryIconPercent, - BatteryIconInvertedPercent, - BatteryIconRetro3, - BatteryIconRetro5, - BatteryIconBarPercent, - BatteryIconCount, -} BatteryIcon; - -typedef enum { - MenuStyleList, - MenuStyleWii, - MenuStyleDsi, - MenuStylePs4, - MenuStyleVertical, - MenuStyleC64, - MenuStyleCompact, - MenuStyleMNTM, - MenuStyleCount, -} MenuStyle; - -typedef enum { - SpiDefault, // cs on pa4 - SpiExtra, // cs on pc3 - SpiCount, -} SpiHandle; - -typedef enum { - ScreenColorModeDefault, - ScreenColorModeCustom, - ScreenColorModeRainbow, - ScreenColorModeRgbBacklight, - ScreenColorModeCount, -} ScreenColorMode; - -typedef union __attribute__((packed)) { - struct { - ScreenColorMode mode; - RgbColor rgb; - }; - uint32_t value; -} ScreenFrameColor; - -typedef struct { - char asset_pack[ASSET_PACKS_NAME_LEN]; - uint32_t anim_speed; - int32_t cycle_anims; - bool unlock_anims; - MenuStyle menu_style; - bool lock_on_boot; - bool bad_pins_format; - bool allow_locked_rpc_commands; - bool lockscreen_poweroff; - bool lockscreen_time; - bool lockscreen_seconds; - bool lockscreen_date; - bool lockscreen_statusbar; - bool lockscreen_prompt; - bool lockscreen_transparent; - BatteryIcon battery_icon; - bool statusbar_clock; - bool status_icons; - bool bar_borders; - bool bar_background; - bool sort_dirs_first; - bool show_hidden_files; - bool show_internal_tab; - uint32_t favorite_timeout; - bool dark_mode; - bool rgb_backlight; - uint32_t butthurt_timer; - uint32_t charge_cap; - SpiHandle spi_cc1101_handle; - SpiHandle spi_nrf24_handle; - FuriHalSerialId uart_esp_channel; - FuriHalSerialId uart_nmea_channel; - bool file_naming_prefix_after; - FuriHalVersionColor spoof_color; - ScreenFrameColor rpc_color_fg; - ScreenFrameColor rpc_color_bg; -} MomentumSettings; - -typedef struct { - uint8_t* fonts[FontTotalNumber]; - CanvasFontParameters* font_params[FontTotalNumber]; -} AssetPacks; - -void momentum_settings_load(void); -void momentum_settings_save(void); -extern MomentumSettings momentum_settings; - -void asset_packs_init(void); -void asset_packs_free(void); -extern AssetPacks asset_packs; +#include "asset_packs.h" +#include "settings.h" #ifdef __cplusplus } diff --git a/lib/momentum/namespoof.c b/lib/momentum/namespoof.c index 7798a19fb..74e87c7bb 100644 --- a/lib/momentum/namespoof.c +++ b/lib/momentum/namespoof.c @@ -1,6 +1,7 @@ #include "namespoof.h" -#include + #include +#include #define TAG "NameSpoof" diff --git a/lib/momentum/settings.c b/lib/momentum/settings.c index 3e4650140..413c38d0e 100644 --- a/lib/momentum/settings.c +++ b/lib/momentum/settings.c @@ -1,4 +1,5 @@ -#include "momentum.h" +#include "settings_i.h" + #include #include #include diff --git a/lib/momentum/settings.h b/lib/momentum/settings.h new file mode 100644 index 000000000..4d46700c1 --- /dev/null +++ b/lib/momentum/settings.h @@ -0,0 +1,97 @@ +#pragma once + +#include +#include +#include +#include + +#define MOMENTUM_SETTINGS_PATH CFG_PATH("momentum_settings.txt") + +#define ASSET_PACKS_NAME_LEN 32 + +typedef enum { + BatteryIconOff, + BatteryIconBar, + BatteryIconPercent, + BatteryIconInvertedPercent, + BatteryIconRetro3, + BatteryIconRetro5, + BatteryIconBarPercent, + BatteryIconCount, +} BatteryIcon; + +typedef enum { + MenuStyleList, + MenuStyleWii, + MenuStyleDsi, + MenuStylePs4, + MenuStyleVertical, + MenuStyleC64, + MenuStyleCompact, + MenuStyleMNTM, + MenuStyleCount, +} MenuStyle; + +typedef enum { + SpiDefault, // CS on pa4 + SpiExtra, // CS on pc3 + SpiCount, +} SpiHandle; + +typedef enum { + ScreenColorModeDefault, + ScreenColorModeCustom, + ScreenColorModeRainbow, + ScreenColorModeRgbBacklight, + ScreenColorModeCount, +} ScreenColorMode; + +typedef union __attribute__((packed)) { + struct { + ScreenColorMode mode; + RgbColor rgb; + }; + uint32_t value; +} ScreenFrameColor; + +typedef struct { + char asset_pack[ASSET_PACKS_NAME_LEN]; + uint32_t anim_speed; + int32_t cycle_anims; + bool unlock_anims; + MenuStyle menu_style; + bool lock_on_boot; + bool bad_pins_format; + bool allow_locked_rpc_commands; + bool lockscreen_poweroff; + bool lockscreen_time; + bool lockscreen_seconds; + bool lockscreen_date; + bool lockscreen_statusbar; + bool lockscreen_prompt; + bool lockscreen_transparent; + BatteryIcon battery_icon; + bool statusbar_clock; + bool status_icons; + bool bar_borders; + bool bar_background; + bool sort_dirs_first; + bool show_hidden_files; + bool show_internal_tab; + uint32_t favorite_timeout; + bool dark_mode; + bool rgb_backlight; + uint32_t butthurt_timer; + uint32_t charge_cap; + SpiHandle spi_cc1101_handle; + SpiHandle spi_nrf24_handle; + FuriHalSerialId uart_esp_channel; + FuriHalSerialId uart_nmea_channel; + bool file_naming_prefix_after; + FuriHalVersionColor spoof_color; + ScreenFrameColor rpc_color_fg; + ScreenFrameColor rpc_color_bg; +} MomentumSettings; + +void momentum_settings_save(void); +extern MomentumSettings momentum_settings; diff --git a/lib/momentum/settings_i.h b/lib/momentum/settings_i.h new file mode 100644 index 000000000..02f7e17ff --- /dev/null +++ b/lib/momentum/settings_i.h @@ -0,0 +1,3 @@ +#include "settings.h" + +void momentum_settings_load(void); diff --git a/scripts/assets.py b/scripts/assets.py index bb656551c..b314cb12a 100755 --- a/scripts/assets.py +++ b/scripts/assets.py @@ -15,7 +15,7 @@ ICONS_TEMPLATE_H_HEADER = """#pragma once #include """ -ICONS_TEMPLATE_H_ICON_NAME = "extern Icon {name};\n" +ICONS_TEMPLATE_H_ICON_NAME = "extern const Icon {name};\n" ICONS_TEMPLATE_C_HEADER = """#include "{assets_filename}.h" @@ -24,7 +24,7 @@ ICONS_TEMPLATE_C_HEADER = """#include "{assets_filename}.h" """ ICONS_TEMPLATE_C_FRAME = "const uint8_t {name}[] = {data};\n" ICONS_TEMPLATE_C_DATA = "const uint8_t* const {name}[] = {data};\n" -ICONS_TEMPLATE_C_ICONS = "Icon {name} = {{.width={width},.height={height},.frame_count={frame_count},.frame_rate={frame_rate},.frames=_{name}}};\n" +ICONS_TEMPLATE_C_ICONS = "const Icon {name} = {{.width={width},.height={height},.frame_count={frame_count},.frame_rate={frame_rate},.frames=_{name}}};\n" MAX_IMAGE_WIDTH = 2**16 - 1 MAX_IMAGE_HEIGHT = 2**16 - 1 @@ -143,7 +143,7 @@ class Main(App): if "UFBT_HOME" in os.environ: symbols /= "sdk_headers/f7_sdk" symbols = (symbols / "targets/f7/api_symbols.csv").read_text() - api_has_icon = lambda name: f"Variable,+,{name},Icon," in symbols + api_has_icon = lambda name: f"Variable,+,{name},const Icon," in symbols # Traverse icons tree, append image data to source file for dirpath, dirnames, filenames in os.walk(self.args.input_directory): self.logger.debug(f"Processing directory {dirpath}") diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index 56575f36d..e9408f3f9 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -2815,7 +2815,6 @@ Function,-,mktemp,char*,char* Function,-,modf,double,"double, double*" Function,-,modff,float,"float, float*" Function,-,modfl,long double,"long double, long double*" -Function,-,momentum_settings_load,void, Function,+,momentum_settings_save,void, Function,-,mrand48,long, Function,-,music_worker_alloc,MusicWorker*, @@ -3836,20 +3835,20 @@ Function,-,yn,double,"int, double" Function,-,ynf,float,"int, float" Variable,-,AHBPrescTable,const uint32_t[16], Variable,-,APBPrescTable,const uint32_t[8], -Variable,+,A_125khz_14,Icon, -Variable,+,A_BadKb_14,Icon, -Variable,+,A_GPIO_14,Icon, -Variable,+,A_Infrared_14,Icon, -Variable,+,A_Levelup_128x64,Icon, -Variable,+,A_Loading_24,Icon, -Variable,+,A_Momentum_14,Icon, -Variable,+,A_NFC_14,Icon, -Variable,+,A_Plugins_14,Icon, -Variable,+,A_Round_loader_8x8,Icon, -Variable,+,A_Settings_14,Icon, -Variable,+,A_Sub1ghz_14,Icon, -Variable,+,A_U2F_14,Icon, -Variable,+,A_iButton_14,Icon, +Variable,+,A_125khz_14,const Icon, +Variable,+,A_BadKb_14,const Icon, +Variable,+,A_GPIO_14,const Icon, +Variable,+,A_Infrared_14,const Icon, +Variable,+,A_Levelup_128x64,const Icon, +Variable,+,A_Loading_24,const Icon, +Variable,+,A_Momentum_14,const Icon, +Variable,+,A_NFC_14,const Icon, +Variable,+,A_Plugins_14,const Icon, +Variable,+,A_Round_loader_8x8,const Icon, +Variable,+,A_Settings_14,const Icon, +Variable,+,A_Sub1ghz_14,const Icon, +Variable,+,A_U2F_14,const Icon, +Variable,+,A_iButton_14,const Icon, Variable,+,DOLPHIN_LEVELS,const uint32_t[], Variable,+,DOLPHIN_LEVEL_COUNT,const size_t, Variable,+,FLIPPER_APPS,const FlipperInternalApplication[], @@ -3871,253 +3870,253 @@ Variable,-,FLIPPER_SYSTEM_APPS_COUNT,const size_t, Variable,+,ICON_PATHS,const IconPath[], Variable,+,ICON_PATHS_COUNT,const size_t, Variable,-,ITM_RxBuffer,volatile int32_t, -Variable,+,I_125_10px,Icon, -Variable,+,I_ActiveConnection_50x64,Icon, -Variable,+,I_Apps_10px,Icon, -Variable,+,I_ArrowC_1_36x36,Icon, -Variable,+,I_ArrowUpEmpty_14x15,Icon, -Variable,+,I_ArrowUpFilled_14x15,Icon, -Variable,+,I_Auth_62x31,Icon, -Variable,+,I_BLE_Pairing_128x64,Icon, -Variable,+,I_BLE_beacon_7x8,Icon, -Variable,+,I_Background_128x11,Icon, -Variable,+,I_BatteryBody_52x28,Icon, -Variable,+,I_Battery_16x16,Icon, -Variable,+,I_Battery_25x8,Icon, -Variable,+,I_Ble_connected_15x15,Icon, -Variable,+,I_Ble_disconnected_15x15,Icon, -Variable,+,I_Bluetooth_Connected_16x8,Icon, -Variable,+,I_Bluetooth_Idle_5x8,Icon, -Variable,+,I_ButtonCenter_7x7,Icon, -Variable,+,I_ButtonDown_7x4,Icon, -Variable,+,I_ButtonLeftSmall_3x5,Icon, -Variable,+,I_ButtonLeft_4x7,Icon, -Variable,+,I_ButtonRightSmall_3x5,Icon, -Variable,+,I_ButtonRight_4x7,Icon, -Variable,+,I_ButtonUp_7x4,Icon, -Variable,+,I_Button_18x18,Icon, -Variable,+,I_CC_Bluetooth_16x16,Icon, -Variable,+,I_CC_DarkMode_16x16,Icon, -Variable,+,I_CC_LefthandedMode_16x16,Icon, -Variable,+,I_CC_Lock_16x16,Icon, -Variable,+,I_CC_Momentum_16x16,Icon, -Variable,+,I_CC_Settings_16x16,Icon, -Variable,+,I_Certification1_103x56,Icon, -Variable,+,I_Certification2_46x33,Icon, -Variable,+,I_CertificationChina0_121x41,Icon, -Variable,+,I_CertificationChina1_124x47,Icon, -Variable,+,I_CertificationMexico_98x41,Icon, -Variable,+,I_CertificationTaiwan_33x32,Icon, -Variable,+,I_Charging_lightning_9x10,Icon, -Variable,+,I_Charging_lightning_mask_9x10,Icon, -Variable,+,I_Circles_47x47,Icon, -Variable,+,I_Clock_18x18,Icon, -Variable,+,I_Connect_me_62x31,Icon, -Variable,+,I_Connected_62x31,Icon, -Variable,+,I_Cos_9x7,Icon, -Variable,+,I_DFU_128x50,Icon, -Variable,+,I_DolphinDone_80x58,Icon, -Variable,+,I_DolphinMafia_119x62,Icon, -Variable,+,I_DolphinReadingSuccess_59x63,Icon, -Variable,+,I_DolphinSaved_92x58,Icon, -Variable,+,I_DolphinSuccess_91x55,Icon, -Variable,+,I_DolphinWait_59x54,Icon, -Variable,+,I_Drive_112x35,Icon, -Variable,+,I_Dynamic_9x7,Icon, -Variable,+,I_Erase_pin_128x64,Icon, -Variable,+,I_Error_18x18,Icon, -Variable,+,I_Error_62x31,Icon, -Variable,+,I_EviSmile1_18x21,Icon, -Variable,+,I_EviSmile2_18x21,Icon, -Variable,+,I_EviWaiting1_18x21,Icon, -Variable,+,I_EviWaiting2_18x21,Icon, -Variable,+,I_Exp_module_connected_12x8,Icon, -Variable,+,I_FaceCharging_29x14,Icon, -Variable,+,I_FaceConfused_29x14,Icon, -Variable,+,I_FaceNopower_29x14,Icon, -Variable,+,I_FaceNormal_29x14,Icon, -Variable,+,I_Fishing_123x52,Icon, -Variable,+,I_Hashmark_7x7,Icon, -Variable,+,I_Health_16x16,Icon, -Variable,+,I_Hidden_window_9x8,Icon, -Variable,+,I_InfraredArrowDown_4x8,Icon, -Variable,+,I_InfraredArrowUp_4x8,Icon, -Variable,+,I_InfraredLearnShort_128x31,Icon, -Variable,+,I_KeyBackspaceSelected_17x11,Icon, -Variable,+,I_KeyBackspace_17x11,Icon, -Variable,+,I_KeyKeyboardSelected_10x11,Icon, -Variable,+,I_KeyKeyboard_10x11,Icon, -Variable,+,I_KeySaveSelected_22x11,Icon, -Variable,+,I_KeySave_22x11,Icon, -Variable,+,I_Keychain_39x36,Icon, -Variable,+,I_Left_mouse_icon_9x9,Icon, -Variable,+,I_LoadingHourglass_24x24,Icon, -Variable,+,I_Lock_7x8,Icon, -Variable,+,I_Lockscreen,Icon, -Variable,+,I_MFKey_qr_25x25,Icon, -Variable,+,I_MHz_25x11,Icon, -Variable,+,I_Modern_reader_18x34,Icon, -Variable,+,I_More_data_placeholder_5x7,Icon, -Variable,+,I_Move_flipper_26x39,Icon, -Variable,+,I_Muted_8x8,Icon, -Variable,+,I_NFC_dolphin_emulation_51x64,Icon, -Variable,+,I_NFC_manual_60x50,Icon, -Variable,+,I_Nfc_10px,Icon, -Variable,+,I_Ok_btn_9x9,Icon, -Variable,+,I_Ok_btn_pressed_13x13,Icon, -Variable,+,I_Percent_10x14,Icon, -Variable,+,I_Pin_arrow_up_7x9,Icon, -Variable,+,I_Pin_attention_dpad_29x29,Icon, -Variable,+,I_Pin_back_arrow_10x8,Icon, -Variable,+,I_Pin_cell_13x13,Icon, -Variable,+,I_Pin_pointer_5x3,Icon, -Variable,+,I_Pin_star_7x7,Icon, -Variable,+,I_Play_25x27,Icon, -Variable,+,I_Play_hvr_25x27,Icon, -Variable,+,I_Pressed_Button_13x13,Icon, -Variable,+,I_Quest_7x8,Icon, -Variable,+,I_RFIDDolphinReceive_97x61,Icon, -Variable,+,I_RFIDDolphinSend_97x61,Icon, -Variable,+,I_RFIDSmallChip_14x14,Icon, -Variable,+,I_Raw_9x7,Icon, -Variable,+,I_Release_arrow_18x15,Icon, -Variable,+,I_Right_mouse_icon_9x9,Icon, -Variable,+,I_Rpc_active_7x8,Icon, -Variable,+,I_SDQuestion_35x43,Icon, -Variable,+,I_SDcardFail_11x8,Icon, -Variable,+,I_SDcardMounted_11x8,Icon, -Variable,+,I_Scanning_123x52,Icon, -Variable,+,I_SmallArrowDown_3x5,Icon, -Variable,+,I_SmallArrowUp_3x5,Icon, -Variable,+,I_Smile_18x18,Icon, -Variable,+,I_Space_65x18,Icon, -Variable,+,I_Static_9x7,Icon, -Variable,+,I_Temperature_16x16,Icon, -Variable,+,I_Unlock_7x8,Icon, -Variable,+,I_Unplug_bg_bottom_128x10,Icon, -Variable,+,I_Unplug_bg_top_128x14,Icon, -Variable,+,I_Updating_32x40,Icon, -Variable,+,I_Updating_Logo_62x15,Icon, -Variable,+,I_UsbTree_48x22,Icon, -Variable,+,I_Voldwn_6x6,Icon, -Variable,+,I_Voltage_16x16,Icon, -Variable,+,I_Volup_8x6,Icon, -Variable,+,I_WarningDolphinFlip_45x42,Icon, -Variable,+,I_WarningDolphin_45x42,Icon, -Variable,+,I_Warning_30x23,Icon, -Variable,+,I_arrow_nano_down,Icon, -Variable,+,I_arrow_nano_up,Icon, -Variable,+,I_back_10px,Icon, -Variable,+,I_badkb_10px,Icon, -Variable,+,I_bright_text_30x30,Icon, -Variable,+,I_celsius_24x23,Icon, -Variable,+,I_celsius_hover_24x23,Icon, -Variable,+,I_ch_down_24x21,Icon, -Variable,+,I_ch_down_hover_24x21,Icon, -Variable,+,I_ch_text_31x34,Icon, -Variable,+,I_ch_up_24x21,Icon, -Variable,+,I_ch_up_hover_24x21,Icon, -Variable,+,I_check_big_20x17,Icon, -Variable,+,I_cool_30x51,Icon, -Variable,+,I_dir_10px,Icon, -Variable,+,I_dolph_cry_49x54,Icon, -Variable,+,I_dry_19x20,Icon, -Variable,+,I_dry_hover_19x20,Icon, -Variable,+,I_dry_text_15x5,Icon, -Variable,+,I_err_01,Icon, -Variable,+,I_err_02,Icon, -Variable,+,I_err_03,Icon, -Variable,+,I_err_04,Icon, -Variable,+,I_err_05,Icon, -Variable,+,I_err_06,Icon, -Variable,+,I_err_07,Icon, -Variable,+,I_err_09,Icon, -Variable,+,I_exit_19x20,Icon, -Variable,+,I_exit_hover_19x20,Icon, -Variable,+,I_exit_text_18x5,Icon, -Variable,+,I_fahren_24x23,Icon, -Variable,+,I_fahren_hover_24x23,Icon, -Variable,+,I_file_10px,Icon, -Variable,+,I_flash_19x20,Icon, -Variable,+,I_flash_hover_19x20,Icon, -Variable,+,I_flash_text_21x5,Icon, -Variable,+,I_floppydisk_10px,Icon, -Variable,+,I_heat_30x51,Icon, -Variable,+,I_hourglass0_24x24,Icon, -Variable,+,I_hourglass1_24x24,Icon, -Variable,+,I_hourglass2_24x24,Icon, -Variable,+,I_hourglass3_24x24,Icon, -Variable,+,I_hourglass4_24x24,Icon, -Variable,+,I_hourglass5_24x24,Icon, -Variable,+,I_hourglass6_24x24,Icon, -Variable,+,I_iButtonDolphinVerySuccess_92x55,Icon, -Variable,+,I_iButtonKey_49x44,Icon, -Variable,+,I_ibutt_10px,Icon, -Variable,+,I_input_19x20,Icon, -Variable,+,I_input_hover_19x20,Icon, -Variable,+,I_input_text_24x5,Icon, -Variable,+,I_ir_10px,Icon, -Variable,+,I_ir_scope_10px,Icon, -Variable,+,I_js_script_10px,Icon, -Variable,+,I_keyboard_10px,Icon, -Variable,+,I_loading_10px,Icon, -Variable,+,I_mag_card_10px,Icon, -Variable,+,I_max_24x23,Icon, -Variable,+,I_max_hover_24x23,Icon, -Variable,+,I_menu_text_20x5,Icon, -Variable,+,I_mode_19x20,Icon, -Variable,+,I_mode_hover_19x20,Icon, -Variable,+,I_mode_text_20x5,Icon, -Variable,+,I_music_10px,Icon, -Variable,+,I_mute_19x20,Icon, -Variable,+,I_mute_hover_19x20,Icon, -Variable,+,I_mute_text_19x5,Icon, -Variable,+,I_next_19x20,Icon, -Variable,+,I_next_hover_19x20,Icon, -Variable,+,I_next_text_19x6,Icon, -Variable,+,I_off_19x20,Icon, -Variable,+,I_off_hover_19x20,Icon, -Variable,+,I_off_text_12x5,Icon, -Variable,+,I_passport_128x64,Icon, -Variable,+,I_passport_bad_46x49,Icon, -Variable,+,I_passport_happy_46x49,Icon, -Variable,+,I_passport_okay_46x49,Icon, -Variable,+,I_pause_19x20,Icon, -Variable,+,I_pause_hover_19x20,Icon, -Variable,+,I_pause_text_23x5,Icon, -Variable,+,I_play_19x20,Icon, -Variable,+,I_play_hover_19x20,Icon, -Variable,+,I_play_text_19x5,Icon, -Variable,+,I_power_19x20,Icon, -Variable,+,I_power_hover_19x20,Icon, -Variable,+,I_power_text_24x5,Icon, -Variable,+,I_prev_19x20,Icon, -Variable,+,I_prev_hover_19x20,Icon, -Variable,+,I_prev_text_19x5,Icon, -Variable,+,I_qr_benchmark_25x25,Icon, -Variable,+,I_rotate_19x20,Icon, -Variable,+,I_rotate_hover_19x20,Icon, -Variable,+,I_rotate_text_24x5,Icon, -Variable,+,I_search_10px,Icon, -Variable,+,I_speed_text_30x30,Icon, -Variable,+,I_stop_19x20,Icon, -Variable,+,I_stop_hover_19x20,Icon, -Variable,+,I_stop_text_19x5,Icon, -Variable,+,I_sub1_10px,Icon, -Variable,+,I_subplaylist_10px,Icon, -Variable,+,I_subrem_10px,Icon, -Variable,+,I_timer_19x20,Icon, -Variable,+,I_timer_hover_19x20,Icon, -Variable,+,I_timer_text_23x5,Icon, -Variable,+,I_u2f_10px,Icon, -Variable,+,I_unknown_10px,Icon, -Variable,+,I_update_10px,Icon, -Variable,+,I_vol_ac_text_30x30,Icon, -Variable,+,I_vol_tv_text_29x34,Icon, -Variable,+,I_voldown_24x21,Icon, -Variable,+,I_voldown_hover_24x21,Icon, -Variable,+,I_volup_24x21,Icon, -Variable,+,I_volup_hover_24x21,Icon, +Variable,+,I_125_10px,const Icon, +Variable,+,I_ActiveConnection_50x64,const Icon, +Variable,+,I_Apps_10px,const Icon, +Variable,+,I_ArrowC_1_36x36,const Icon, +Variable,+,I_ArrowUpEmpty_14x15,const Icon, +Variable,+,I_ArrowUpFilled_14x15,const Icon, +Variable,+,I_Auth_62x31,const Icon, +Variable,+,I_BLE_Pairing_128x64,const Icon, +Variable,+,I_BLE_beacon_7x8,const Icon, +Variable,+,I_Background_128x11,const Icon, +Variable,+,I_BatteryBody_52x28,const Icon, +Variable,+,I_Battery_16x16,const Icon, +Variable,+,I_Battery_25x8,const Icon, +Variable,+,I_Ble_connected_15x15,const Icon, +Variable,+,I_Ble_disconnected_15x15,const Icon, +Variable,+,I_Bluetooth_Connected_16x8,const Icon, +Variable,+,I_Bluetooth_Idle_5x8,const Icon, +Variable,+,I_ButtonCenter_7x7,const Icon, +Variable,+,I_ButtonDown_7x4,const Icon, +Variable,+,I_ButtonLeftSmall_3x5,const Icon, +Variable,+,I_ButtonLeft_4x7,const Icon, +Variable,+,I_ButtonRightSmall_3x5,const Icon, +Variable,+,I_ButtonRight_4x7,const Icon, +Variable,+,I_ButtonUp_7x4,const Icon, +Variable,+,I_Button_18x18,const Icon, +Variable,+,I_CC_Bluetooth_16x16,const Icon, +Variable,+,I_CC_DarkMode_16x16,const Icon, +Variable,+,I_CC_LefthandedMode_16x16,const Icon, +Variable,+,I_CC_Lock_16x16,const Icon, +Variable,+,I_CC_Momentum_16x16,const Icon, +Variable,+,I_CC_Settings_16x16,const Icon, +Variable,+,I_Certification1_103x56,const Icon, +Variable,+,I_Certification2_46x33,const Icon, +Variable,+,I_CertificationChina0_121x41,const Icon, +Variable,+,I_CertificationChina1_124x47,const Icon, +Variable,+,I_CertificationMexico_98x41,const Icon, +Variable,+,I_CertificationTaiwan_33x32,const Icon, +Variable,+,I_Charging_lightning_9x10,const Icon, +Variable,+,I_Charging_lightning_mask_9x10,const Icon, +Variable,+,I_Circles_47x47,const Icon, +Variable,+,I_Clock_18x18,const Icon, +Variable,+,I_Connect_me_62x31,const Icon, +Variable,+,I_Connected_62x31,const Icon, +Variable,+,I_Cos_9x7,const Icon, +Variable,+,I_DFU_128x50,const Icon, +Variable,+,I_DolphinDone_80x58,const Icon, +Variable,+,I_DolphinMafia_119x62,const Icon, +Variable,+,I_DolphinReadingSuccess_59x63,const Icon, +Variable,+,I_DolphinSaved_92x58,const Icon, +Variable,+,I_DolphinSuccess_91x55,const Icon, +Variable,+,I_DolphinWait_59x54,const Icon, +Variable,+,I_Drive_112x35,const Icon, +Variable,+,I_Dynamic_9x7,const Icon, +Variable,+,I_Erase_pin_128x64,const Icon, +Variable,+,I_Error_18x18,const Icon, +Variable,+,I_Error_62x31,const Icon, +Variable,+,I_EviSmile1_18x21,const Icon, +Variable,+,I_EviSmile2_18x21,const Icon, +Variable,+,I_EviWaiting1_18x21,const Icon, +Variable,+,I_EviWaiting2_18x21,const Icon, +Variable,+,I_Exp_module_connected_12x8,const Icon, +Variable,+,I_FaceCharging_29x14,const Icon, +Variable,+,I_FaceConfused_29x14,const Icon, +Variable,+,I_FaceNopower_29x14,const Icon, +Variable,+,I_FaceNormal_29x14,const Icon, +Variable,+,I_Fishing_123x52,const Icon, +Variable,+,I_Hashmark_7x7,const Icon, +Variable,+,I_Health_16x16,const Icon, +Variable,+,I_Hidden_window_9x8,const Icon, +Variable,+,I_InfraredArrowDown_4x8,const Icon, +Variable,+,I_InfraredArrowUp_4x8,const Icon, +Variable,+,I_InfraredLearnShort_128x31,const Icon, +Variable,+,I_KeyBackspaceSelected_17x11,const Icon, +Variable,+,I_KeyBackspace_17x11,const Icon, +Variable,+,I_KeyKeyboardSelected_10x11,const Icon, +Variable,+,I_KeyKeyboard_10x11,const Icon, +Variable,+,I_KeySaveSelected_22x11,const Icon, +Variable,+,I_KeySave_22x11,const Icon, +Variable,+,I_Keychain_39x36,const Icon, +Variable,+,I_Left_mouse_icon_9x9,const Icon, +Variable,+,I_LoadingHourglass_24x24,const Icon, +Variable,+,I_Lock_7x8,const Icon, +Variable,+,I_Lockscreen,const Icon, +Variable,+,I_MFKey_qr_25x25,const Icon, +Variable,+,I_MHz_25x11,const Icon, +Variable,+,I_Modern_reader_18x34,const Icon, +Variable,+,I_More_data_placeholder_5x7,const Icon, +Variable,+,I_Move_flipper_26x39,const Icon, +Variable,+,I_Muted_8x8,const Icon, +Variable,+,I_NFC_dolphin_emulation_51x64,const Icon, +Variable,+,I_NFC_manual_60x50,const Icon, +Variable,+,I_Nfc_10px,const Icon, +Variable,+,I_Ok_btn_9x9,const Icon, +Variable,+,I_Ok_btn_pressed_13x13,const Icon, +Variable,+,I_Percent_10x14,const Icon, +Variable,+,I_Pin_arrow_up_7x9,const Icon, +Variable,+,I_Pin_attention_dpad_29x29,const Icon, +Variable,+,I_Pin_back_arrow_10x8,const Icon, +Variable,+,I_Pin_cell_13x13,const Icon, +Variable,+,I_Pin_pointer_5x3,const Icon, +Variable,+,I_Pin_star_7x7,const Icon, +Variable,+,I_Play_25x27,const Icon, +Variable,+,I_Play_hvr_25x27,const Icon, +Variable,+,I_Pressed_Button_13x13,const Icon, +Variable,+,I_Quest_7x8,const Icon, +Variable,+,I_RFIDDolphinReceive_97x61,const Icon, +Variable,+,I_RFIDDolphinSend_97x61,const Icon, +Variable,+,I_RFIDSmallChip_14x14,const Icon, +Variable,+,I_Raw_9x7,const Icon, +Variable,+,I_Release_arrow_18x15,const Icon, +Variable,+,I_Right_mouse_icon_9x9,const Icon, +Variable,+,I_Rpc_active_7x8,const Icon, +Variable,+,I_SDQuestion_35x43,const Icon, +Variable,+,I_SDcardFail_11x8,const Icon, +Variable,+,I_SDcardMounted_11x8,const Icon, +Variable,+,I_Scanning_123x52,const Icon, +Variable,+,I_SmallArrowDown_3x5,const Icon, +Variable,+,I_SmallArrowUp_3x5,const Icon, +Variable,+,I_Smile_18x18,const Icon, +Variable,+,I_Space_65x18,const Icon, +Variable,+,I_Static_9x7,const Icon, +Variable,+,I_Temperature_16x16,const Icon, +Variable,+,I_Unlock_7x8,const Icon, +Variable,+,I_Unplug_bg_bottom_128x10,const Icon, +Variable,+,I_Unplug_bg_top_128x14,const Icon, +Variable,+,I_Updating_32x40,const Icon, +Variable,+,I_Updating_Logo_62x15,const Icon, +Variable,+,I_UsbTree_48x22,const Icon, +Variable,+,I_Voldwn_6x6,const Icon, +Variable,+,I_Voltage_16x16,const Icon, +Variable,+,I_Volup_8x6,const Icon, +Variable,+,I_WarningDolphinFlip_45x42,const Icon, +Variable,+,I_WarningDolphin_45x42,const Icon, +Variable,+,I_Warning_30x23,const Icon, +Variable,+,I_arrow_nano_down,const Icon, +Variable,+,I_arrow_nano_up,const Icon, +Variable,+,I_back_10px,const Icon, +Variable,+,I_badkb_10px,const Icon, +Variable,+,I_bright_text_30x30,const Icon, +Variable,+,I_celsius_24x23,const Icon, +Variable,+,I_celsius_hover_24x23,const Icon, +Variable,+,I_ch_down_24x21,const Icon, +Variable,+,I_ch_down_hover_24x21,const Icon, +Variable,+,I_ch_text_31x34,const Icon, +Variable,+,I_ch_up_24x21,const Icon, +Variable,+,I_ch_up_hover_24x21,const Icon, +Variable,+,I_check_big_20x17,const Icon, +Variable,+,I_cool_30x51,const Icon, +Variable,+,I_dir_10px,const Icon, +Variable,+,I_dolph_cry_49x54,const Icon, +Variable,+,I_dry_19x20,const Icon, +Variable,+,I_dry_hover_19x20,const Icon, +Variable,+,I_dry_text_15x5,const Icon, +Variable,+,I_err_01,const Icon, +Variable,+,I_err_02,const Icon, +Variable,+,I_err_03,const Icon, +Variable,+,I_err_04,const Icon, +Variable,+,I_err_05,const Icon, +Variable,+,I_err_06,const Icon, +Variable,+,I_err_07,const Icon, +Variable,+,I_err_09,const Icon, +Variable,+,I_exit_19x20,const Icon, +Variable,+,I_exit_hover_19x20,const Icon, +Variable,+,I_exit_text_18x5,const Icon, +Variable,+,I_fahren_24x23,const Icon, +Variable,+,I_fahren_hover_24x23,const Icon, +Variable,+,I_file_10px,const Icon, +Variable,+,I_flash_19x20,const Icon, +Variable,+,I_flash_hover_19x20,const Icon, +Variable,+,I_flash_text_21x5,const Icon, +Variable,+,I_floppydisk_10px,const Icon, +Variable,+,I_heat_30x51,const Icon, +Variable,+,I_hourglass0_24x24,const Icon, +Variable,+,I_hourglass1_24x24,const Icon, +Variable,+,I_hourglass2_24x24,const Icon, +Variable,+,I_hourglass3_24x24,const Icon, +Variable,+,I_hourglass4_24x24,const Icon, +Variable,+,I_hourglass5_24x24,const Icon, +Variable,+,I_hourglass6_24x24,const Icon, +Variable,+,I_iButtonDolphinVerySuccess_92x55,const Icon, +Variable,+,I_iButtonKey_49x44,const Icon, +Variable,+,I_ibutt_10px,const Icon, +Variable,+,I_input_19x20,const Icon, +Variable,+,I_input_hover_19x20,const Icon, +Variable,+,I_input_text_24x5,const Icon, +Variable,+,I_ir_10px,const Icon, +Variable,+,I_ir_scope_10px,const Icon, +Variable,+,I_js_script_10px,const Icon, +Variable,+,I_keyboard_10px,const Icon, +Variable,+,I_loading_10px,const Icon, +Variable,+,I_mag_card_10px,const Icon, +Variable,+,I_max_24x23,const Icon, +Variable,+,I_max_hover_24x23,const Icon, +Variable,+,I_menu_text_20x5,const Icon, +Variable,+,I_mode_19x20,const Icon, +Variable,+,I_mode_hover_19x20,const Icon, +Variable,+,I_mode_text_20x5,const Icon, +Variable,+,I_music_10px,const Icon, +Variable,+,I_mute_19x20,const Icon, +Variable,+,I_mute_hover_19x20,const Icon, +Variable,+,I_mute_text_19x5,const Icon, +Variable,+,I_next_19x20,const Icon, +Variable,+,I_next_hover_19x20,const Icon, +Variable,+,I_next_text_19x6,const Icon, +Variable,+,I_off_19x20,const Icon, +Variable,+,I_off_hover_19x20,const Icon, +Variable,+,I_off_text_12x5,const Icon, +Variable,+,I_passport_128x64,const Icon, +Variable,+,I_passport_bad_46x49,const Icon, +Variable,+,I_passport_happy_46x49,const Icon, +Variable,+,I_passport_okay_46x49,const Icon, +Variable,+,I_pause_19x20,const Icon, +Variable,+,I_pause_hover_19x20,const Icon, +Variable,+,I_pause_text_23x5,const Icon, +Variable,+,I_play_19x20,const Icon, +Variable,+,I_play_hover_19x20,const Icon, +Variable,+,I_play_text_19x5,const Icon, +Variable,+,I_power_19x20,const Icon, +Variable,+,I_power_hover_19x20,const Icon, +Variable,+,I_power_text_24x5,const Icon, +Variable,+,I_prev_19x20,const Icon, +Variable,+,I_prev_hover_19x20,const Icon, +Variable,+,I_prev_text_19x5,const Icon, +Variable,+,I_qr_benchmark_25x25,const Icon, +Variable,+,I_rotate_19x20,const Icon, +Variable,+,I_rotate_hover_19x20,const Icon, +Variable,+,I_rotate_text_24x5,const Icon, +Variable,+,I_search_10px,const Icon, +Variable,+,I_speed_text_30x30,const Icon, +Variable,+,I_stop_19x20,const Icon, +Variable,+,I_stop_hover_19x20,const Icon, +Variable,+,I_stop_text_19x5,const Icon, +Variable,+,I_sub1_10px,const Icon, +Variable,+,I_subplaylist_10px,const Icon, +Variable,+,I_subrem_10px,const Icon, +Variable,+,I_timer_19x20,const Icon, +Variable,+,I_timer_hover_19x20,const Icon, +Variable,+,I_timer_text_23x5,const Icon, +Variable,+,I_u2f_10px,const Icon, +Variable,+,I_unknown_10px,const Icon, +Variable,+,I_update_10px,const Icon, +Variable,+,I_vol_ac_text_30x30,const Icon, +Variable,+,I_vol_tv_text_29x34,const Icon, +Variable,+,I_voldown_24x21,const Icon, +Variable,+,I_voldown_hover_24x21,const Icon, +Variable,+,I_volup_24x21,const Icon, +Variable,+,I_volup_hover_24x21,const Icon, Variable,-,MSIRangeTable,const uint32_t[16], Variable,-,SmpsPrescalerTable,const uint32_t[4][6], Variable,+,SystemCoreClock,uint32_t, @@ -4131,7 +4130,6 @@ Variable,+,_impure_data,_reent, Variable,+,_impure_ptr,_reent*, Variable,-,_sys_errlist,const char*[], Variable,-,_sys_nerr,int, -Variable,-,asset_packs,AssetPacks, Variable,-,ble_profile_hid,const FuriHalBleProfileTemplate*, Variable,-,ble_profile_serial,const FuriHalBleProfileTemplate*, Variable,+,cli_vcp,CliSession,