mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-16 04:24:45 -07:00
Small bump in the road
- Update assets and references for new project - Revert DFU image and CLI motd - Remove NSFW text and flag - Remove credits animation (will be replaced with a setting menu soon) - New EvilPortal example HTML and better error message - Initial standalone naming for asset packs and mainmenu apps - File migration fixes/improvements - Remove hotfix workflow
This commit is contained in:
20
lib/momentum/SConscript
Normal file
20
lib/momentum/SConscript
Normal file
@@ -0,0 +1,20 @@
|
||||
Import("env")
|
||||
|
||||
env.Append(
|
||||
SDK_HEADERS=[
|
||||
File("../../icons/assets_icons.h"),
|
||||
File("momentum.h"),
|
||||
],
|
||||
LINT_SOURCES=[
|
||||
Dir("."),
|
||||
],
|
||||
)
|
||||
|
||||
libenv = env.Clone(FW_LIB_NAME="momentum")
|
||||
libenv.ApplyLibFlags()
|
||||
|
||||
sources = libenv.GlobRecursive("*.c")
|
||||
|
||||
lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources)
|
||||
libenv.Install("${LIB_DIST_DIR}", lib)
|
||||
Return("lib")
|
||||
195
lib/momentum/assets.c
Normal file
195
lib/momentum/assets.c
Normal file
@@ -0,0 +1,195 @@
|
||||
#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() {
|
||||
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() {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
105
lib/momentum/momentum.h
Normal file
105
lib/momentum/momentum.h
Normal file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <furi_hal_serial_types.h>
|
||||
#include <gui/canvas.h>
|
||||
|
||||
#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,
|
||||
MenuStyleTerminal,
|
||||
MenuStyleCount,
|
||||
} MenuStyle;
|
||||
|
||||
typedef enum {
|
||||
SpiDefault, // cs on pa4
|
||||
SpiExtra, // cs on pc3
|
||||
SpiCount,
|
||||
} SpiHandle;
|
||||
|
||||
_Static_assert(sizeof(MenuStyle) == sizeof(uint8_t), "enum too big, fix load/save");
|
||||
_Static_assert(sizeof(BatteryIcon) == sizeof(uint8_t), "enum too big, fix load/save");
|
||||
_Static_assert(sizeof(SpiHandle) == sizeof(uint8_t), "enum too big, fix load/save");
|
||||
_Static_assert(sizeof(FuriHalSerialId) == sizeof(uint8_t), "enum too big, fix load/save");
|
||||
|
||||
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 bad_bt;
|
||||
bool bad_bt_remember;
|
||||
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;
|
||||
FuriHalSerialId uart_general_channel;
|
||||
bool file_naming_prefix_after;
|
||||
} MomentumSettings;
|
||||
|
||||
typedef struct {
|
||||
uint8_t* fonts[FontTotalNumber];
|
||||
CanvasFontParameters* font_params[FontTotalNumber];
|
||||
} AssetPacks;
|
||||
|
||||
void momentum_settings_load();
|
||||
void momentum_settings_save();
|
||||
extern MomentumSettings momentum_settings;
|
||||
|
||||
void asset_packs_init();
|
||||
void asset_packs_free();
|
||||
extern AssetPacks asset_packs;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
27
lib/momentum/namespoof.c
Normal file
27
lib/momentum/namespoof.c
Normal file
@@ -0,0 +1,27 @@
|
||||
#include "namespoof.h"
|
||||
#include <furi_hal.h>
|
||||
#include <flipper_format/flipper_format.h>
|
||||
|
||||
#define TAG "NameSpoof"
|
||||
|
||||
void namespoof_init() {
|
||||
FuriString* str = furi_string_alloc();
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||
|
||||
do {
|
||||
uint32_t version;
|
||||
if(!flipper_format_file_open_existing(file, NAMESPOOF_PATH)) break;
|
||||
if(!flipper_format_read_header(file, str, &version)) break;
|
||||
if(furi_string_cmp_str(str, NAMESPOOF_HEADER)) break;
|
||||
if(version != NAMESPOOF_VERSION) break;
|
||||
|
||||
if(!flipper_format_read_string(file, "Name", str)) break;
|
||||
version_set_custom_name(NULL, strdup(furi_string_get_cstr(str)));
|
||||
furi_hal_version_set_name(NULL);
|
||||
} while(false);
|
||||
|
||||
flipper_format_free(file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
furi_string_free(str);
|
||||
}
|
||||
7
lib/momentum/namespoof.h
Normal file
7
lib/momentum/namespoof.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#define NAMESPOOF_HEADER "Flipper Name File"
|
||||
#define NAMESPOOF_VERSION 1
|
||||
#define NAMESPOOF_PATH EXT_PATH("dolphin/name.txt")
|
||||
|
||||
void namespoof_init();
|
||||
197
lib/momentum/settings.c
Normal file
197
lib/momentum/settings.c
Normal file
@@ -0,0 +1,197 @@
|
||||
#include "momentum.h"
|
||||
#include <furi_hal.h>
|
||||
#include <rgb_backlight.h>
|
||||
#include <flipper_format/flipper_format.h>
|
||||
|
||||
#define TAG "MomentumSettings"
|
||||
|
||||
MomentumSettings momentum_settings = {
|
||||
.asset_pack = "", // Default
|
||||
.anim_speed = 100, // 100%
|
||||
.cycle_anims = 0, // Meta.txt
|
||||
.unlock_anims = false, // OFF
|
||||
.menu_style = MenuStyleDsi, // DSi
|
||||
.lock_on_boot = false, // OFF
|
||||
.bad_pins_format = false, // OFF
|
||||
.allow_locked_rpc_commands = false, // OFF
|
||||
.lockscreen_poweroff = true, // ON
|
||||
.lockscreen_time = true, // ON
|
||||
.lockscreen_seconds = false, // OFF
|
||||
.lockscreen_date = true, // ON
|
||||
.lockscreen_statusbar = true, // ON
|
||||
.lockscreen_prompt = true, // ON
|
||||
.lockscreen_transparent = false, // OFF
|
||||
.battery_icon = BatteryIconBarPercent, // Bar %
|
||||
.statusbar_clock = false, // OFF
|
||||
.status_icons = true, // ON
|
||||
.bar_borders = true, // ON
|
||||
.bar_background = false, // OFF
|
||||
.sort_dirs_first = true, // ON
|
||||
.show_hidden_files = false, // OFF
|
||||
.show_internal_tab = false, // OFF
|
||||
.favorite_timeout = 0, // OFF
|
||||
.bad_bt = false, // USB
|
||||
.bad_bt_remember = false, // OFF
|
||||
.dark_mode = false, // OFF
|
||||
.rgb_backlight = false, // OFF
|
||||
.butthurt_timer = 21600, // 6 H
|
||||
.charge_cap = 100, // 100%
|
||||
.spi_cc1101_handle = SpiDefault, // &furi_hal_spi_bus_handle_external
|
||||
.spi_nrf24_handle = SpiDefault, // &furi_hal_spi_bus_handle_external
|
||||
.uart_esp_channel = FuriHalSerialIdUsart, // pin 13,14
|
||||
.uart_nmea_channel = FuriHalSerialIdUsart, // pin 13,14
|
||||
.uart_general_channel = FuriHalSerialIdUsart, // pin 13,14
|
||||
.file_naming_prefix_after = false, // Before
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
momentum_settings_type_str,
|
||||
momentum_settings_type_int,
|
||||
momentum_settings_type_uint,
|
||||
momentum_settings_type_enum,
|
||||
momentum_settings_type_bool,
|
||||
} momentum_settings_type;
|
||||
|
||||
static const struct {
|
||||
momentum_settings_type type;
|
||||
const char* key;
|
||||
void* val;
|
||||
union {
|
||||
size_t str_len;
|
||||
struct {
|
||||
int32_t i_min;
|
||||
int32_t i_max;
|
||||
};
|
||||
struct {
|
||||
uint32_t u_min;
|
||||
uint32_t u_max;
|
||||
};
|
||||
uint8_t e_cnt;
|
||||
};
|
||||
#define clamp(t, min, max) .t##_min = min, .t##_max = max
|
||||
#define setting(t, n) .type = momentum_settings_type##t, .key = #n, .val = &momentum_settings.n
|
||||
#define setting_str(n) setting(_str, n), .str_len = sizeof(momentum_settings.n)
|
||||
#define setting_int(n, min, max) setting(_int, n), clamp(i, min, max)
|
||||
#define setting_uint(n, min, max) setting(_uint, n), clamp(u, min, max)
|
||||
#define setting_enum(n, cnt) setting(_enum, n), .e_cnt = cnt
|
||||
#define setting_bool(n) setting(_bool, n)
|
||||
} momentum_settings_entries[] = {
|
||||
{setting_str(asset_pack)},
|
||||
{setting_uint(anim_speed, 25, 300)},
|
||||
{setting_int(cycle_anims, -1, 86400)},
|
||||
{setting_bool(unlock_anims)},
|
||||
{setting_enum(menu_style, MenuStyleCount)},
|
||||
{setting_bool(bad_pins_format)},
|
||||
{setting_bool(allow_locked_rpc_commands)},
|
||||
{setting_bool(lock_on_boot)},
|
||||
{setting_bool(lockscreen_poweroff)},
|
||||
{setting_bool(lockscreen_time)},
|
||||
{setting_bool(lockscreen_seconds)},
|
||||
{setting_bool(lockscreen_date)},
|
||||
{setting_bool(lockscreen_statusbar)},
|
||||
{setting_bool(lockscreen_prompt)},
|
||||
{setting_bool(lockscreen_transparent)},
|
||||
{setting_enum(battery_icon, BatteryIconCount)},
|
||||
{setting_bool(statusbar_clock)},
|
||||
{setting_bool(status_icons)},
|
||||
{setting_bool(bar_borders)},
|
||||
{setting_bool(bar_background)},
|
||||
{setting_bool(sort_dirs_first)},
|
||||
{setting_bool(show_hidden_files)},
|
||||
{setting_bool(show_internal_tab)},
|
||||
{setting_uint(favorite_timeout, 0, 60)},
|
||||
{setting_bool(bad_bt)},
|
||||
{setting_bool(bad_bt_remember)},
|
||||
{setting_bool(dark_mode)},
|
||||
{setting_bool(rgb_backlight)},
|
||||
{setting_uint(butthurt_timer, 0, 172800)},
|
||||
{setting_uint(charge_cap, 5, 100)},
|
||||
{setting_enum(spi_cc1101_handle, SpiCount)},
|
||||
{setting_enum(spi_nrf24_handle, SpiCount)},
|
||||
{setting_enum(uart_esp_channel, FuriHalSerialIdMax)},
|
||||
{setting_enum(uart_nmea_channel, FuriHalSerialIdMax)},
|
||||
{setting_enum(uart_general_channel, FuriHalSerialIdMax)},
|
||||
{setting_bool(file_naming_prefix_after)},
|
||||
};
|
||||
|
||||
void momentum_settings_load() {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||
if(flipper_format_file_open_existing(file, MOMENTUM_SETTINGS_PATH)) {
|
||||
FuriString* val_str = furi_string_alloc();
|
||||
int32_t val_int;
|
||||
uint32_t val_uint;
|
||||
bool val_bool;
|
||||
|
||||
bool ok;
|
||||
for(size_t entry_i = 0; entry_i < COUNT_OF(momentum_settings_entries); entry_i++) {
|
||||
#define entry momentum_settings_entries[entry_i]
|
||||
switch(entry.type) {
|
||||
case momentum_settings_type_str:
|
||||
ok = flipper_format_read_string(file, entry.key, val_str);
|
||||
if(ok) strlcpy((char*)entry.val, furi_string_get_cstr(val_str), entry.str_len);
|
||||
break;
|
||||
case momentum_settings_type_int:
|
||||
ok = flipper_format_read_int32(file, entry.key, &val_int, 1);
|
||||
if(ok) *(int32_t*)entry.val = CLAMP(val_int, entry.i_max, entry.i_min);
|
||||
break;
|
||||
case momentum_settings_type_uint:
|
||||
ok = flipper_format_read_uint32(file, entry.key, &val_uint, 1);
|
||||
if(ok) *(uint32_t*)entry.val = CLAMP(val_uint, entry.u_max, entry.u_min);
|
||||
break;
|
||||
case momentum_settings_type_enum:
|
||||
ok = flipper_format_read_uint32(file, entry.key, &val_uint, 1);
|
||||
if(ok) *(uint8_t*)entry.val = CLAMP(val_uint, entry.e_cnt - 1U, 0U);
|
||||
break;
|
||||
case momentum_settings_type_bool:
|
||||
ok = flipper_format_read_bool(file, entry.key, &val_bool, 1);
|
||||
if(ok) *(bool*)entry.val = val_bool;
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
if(!ok) flipper_format_rewind(file);
|
||||
}
|
||||
|
||||
furi_string_free(val_str);
|
||||
}
|
||||
flipper_format_free(file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
|
||||
rgb_backlight_load_settings(momentum_settings.rgb_backlight);
|
||||
}
|
||||
|
||||
void momentum_settings_save() {
|
||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
||||
|
||||
if(flipper_format_file_open_always(file, MOMENTUM_SETTINGS_PATH)) {
|
||||
uint32_t tmp_enum;
|
||||
for(size_t entry_i = 0; entry_i < COUNT_OF(momentum_settings_entries); entry_i++) {
|
||||
#define entry momentum_settings_entries[entry_i]
|
||||
switch(entry.type) {
|
||||
case momentum_settings_type_str:
|
||||
flipper_format_write_string_cstr(file, entry.key, (char*)entry.val);
|
||||
break;
|
||||
case momentum_settings_type_int:
|
||||
flipper_format_write_int32(file, entry.key, (int32_t*)entry.val, 1);
|
||||
break;
|
||||
case momentum_settings_type_uint:
|
||||
flipper_format_write_uint32(file, entry.key, (uint32_t*)entry.val, 1);
|
||||
break;
|
||||
case momentum_settings_type_enum:
|
||||
tmp_enum = *(uint8_t*)entry.val;
|
||||
flipper_format_write_uint32(file, entry.key, &tmp_enum, 1);
|
||||
break;
|
||||
case momentum_settings_type_bool:
|
||||
flipper_format_write_bool(file, entry.key, (bool*)entry.val, 1);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
flipper_format_free(file);
|
||||
furi_record_close(RECORD_STORAGE);
|
||||
}
|
||||
Reference in New Issue
Block a user