mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-13 02:18:35 -07:00
Asset Packs: Optimize icon loader (#164)
* Original pointer can be const * Back to const icons * Missed this one * Simpler string alloc * Single allocation and header struct for static icons * Shared allocation and meta struct for animated icons * Only try to load if dir exists * Restructure momentum lib * Use some internal headers * Swap icons at draw * Properly init and free, no more original in icon struct
This commit is contained in:
252
lib/momentum/asset_packs.c
Normal file
252
lib/momentum/asset_packs.c
Normal file
@@ -0,0 +1,252 @@
|
||||
#include "asset_packs_i.h"
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
#include <assets_icons.h>
|
||||
#include <core/dangerous_defines.h>
|
||||
#include <furi_hal.h>
|
||||
#include <gui/icon_i.h>
|
||||
#include <storage/storage.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
9
lib/momentum/asset_packs.h
Normal file
9
lib/momentum/asset_packs.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/canvas.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ASSET_PACKS_PATH EXT_PATH("asset_packs")
|
||||
|
||||
void asset_packs_init(void);
|
||||
void asset_packs_free(void);
|
||||
21
lib/momentum/asset_packs_i.h
Normal file
21
lib/momentum/asset_packs_i.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "asset_packs.h"
|
||||
|
||||
#include <m-list.h>
|
||||
|
||||
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);
|
||||
@@ -1,195 +0,0 @@
|
||||
#include "momentum.h"
|
||||
#include <furi_hal.h>
|
||||
#include <gui/icon_i.h>
|
||||
#include <assets_icons.h>
|
||||
#include <storage/storage.h>
|
||||
#include <core/dangerous_defines.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,117 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <furi_hal_serial_types.h>
|
||||
#include <furi_hal_version.h>
|
||||
#include <toolbox/colors.h>
|
||||
#include <gui/canvas.h>
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "namespoof.h"
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include <flipper_format/flipper_format.h>
|
||||
#include <furi_hal_version.h>
|
||||
|
||||
#define TAG "NameSpoof"
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "momentum.h"
|
||||
#include "settings_i.h"
|
||||
|
||||
#include <furi_hal.h>
|
||||
#include <rgb_backlight.h>
|
||||
#include <flipper_format/flipper_format.h>
|
||||
|
||||
97
lib/momentum/settings.h
Normal file
97
lib/momentum/settings.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include <furi_hal_serial_types.h>
|
||||
#include <furi_hal_version.h>
|
||||
#include <stdint.h>
|
||||
#include <toolbox/colors.h>
|
||||
|
||||
#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;
|
||||
3
lib/momentum/settings_i.h
Normal file
3
lib/momentum/settings_i.h
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "settings.h"
|
||||
|
||||
void momentum_settings_load(void);
|
||||
Reference in New Issue
Block a user