mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-13 05:18:35 -07:00
Merge branch 'dev' into xtruan/eurocorp_menu
This commit is contained in:
@@ -7,7 +7,7 @@ App(
|
|||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=4 * 1024,
|
stack_size=4 * 1024,
|
||||||
order=90,
|
order=90,
|
||||||
fap_icon="wifi_10px.png",
|
fap_icon="update_10px.png",
|
||||||
fap_category="GPIO",
|
fap_category="GPIO",
|
||||||
fap_private_libs=[
|
fap_private_libs=[
|
||||||
Lib(
|
Lib(
|
||||||
|
|||||||
BIN
applications/external/esp_flasher/update_10px.png
vendored
Normal file
BIN
applications/external/esp_flasher/update_10px.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 156 B |
BIN
applications/external/esp_flasher/wifi_10px.png
vendored
BIN
applications/external/esp_flasher/wifi_10px.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB |
BIN
applications/external/esubghz_chat/assets/hex_10px.png
vendored
Normal file
BIN
applications/external/esubghz_chat/assets/hex_10px.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 171 B |
@@ -76,20 +76,30 @@ void scene_on_enter_key_menu(void* context) {
|
|||||||
menu_add_item(
|
menu_add_item(
|
||||||
state->menu,
|
state->menu,
|
||||||
"No encryption",
|
"No encryption",
|
||||||
NULL,
|
&I_chat_10px,
|
||||||
ESubGhzChatKeyMenuItems_NoEncryption,
|
ESubGhzChatKeyMenuItems_NoEncryption,
|
||||||
key_menu_cb,
|
key_menu_cb,
|
||||||
state);
|
state);
|
||||||
menu_add_item(
|
menu_add_item(
|
||||||
state->menu, "Password", NULL, ESubGhzChatKeyMenuItems_Password, key_menu_cb, state);
|
state->menu,
|
||||||
|
"Password",
|
||||||
|
&I_keyboard_10px,
|
||||||
|
ESubGhzChatKeyMenuItems_Password,
|
||||||
|
key_menu_cb,
|
||||||
|
state);
|
||||||
menu_add_item(
|
menu_add_item(
|
||||||
state->menu, "Hex Key", NULL, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state);
|
state->menu, "Hex Key", &I_hex_10px, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state);
|
||||||
menu_add_item(
|
menu_add_item(
|
||||||
state->menu, "Generate Key", NULL, ESubGhzChatKeyMenuItems_GenKey, key_menu_cb, state);
|
state->menu,
|
||||||
|
"Generate Key",
|
||||||
|
&I_u2f_10px,
|
||||||
|
ESubGhzChatKeyMenuItems_GenKey,
|
||||||
|
key_menu_cb,
|
||||||
|
state);
|
||||||
menu_add_item(
|
menu_add_item(
|
||||||
state->menu,
|
state->menu,
|
||||||
"Read Key from NFC",
|
"Read Key from NFC",
|
||||||
NULL,
|
&I_Nfc_10px,
|
||||||
ESubGhzChatKeyMenuItems_ReadKeyFromNfc,
|
ESubGhzChatKeyMenuItems_ReadKeyFromNfc,
|
||||||
key_menu_cb,
|
key_menu_cb,
|
||||||
state);
|
state);
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 156 B |
@@ -16,5 +16,6 @@ ADD_SCENE(xtreme_app, protocols_freqs_add, ProtocolsFreqsAdd)
|
|||||||
ADD_SCENE(xtreme_app, protocols_gpio, ProtocolsGpio)
|
ADD_SCENE(xtreme_app, protocols_gpio, ProtocolsGpio)
|
||||||
ADD_SCENE(xtreme_app, misc, Misc)
|
ADD_SCENE(xtreme_app, misc, Misc)
|
||||||
ADD_SCENE(xtreme_app, misc_screen, MiscScreen)
|
ADD_SCENE(xtreme_app, misc_screen, MiscScreen)
|
||||||
|
ADD_SCENE(xtreme_app, misc_screen_color, MiscScreenColor)
|
||||||
ADD_SCENE(xtreme_app, misc_dolphin, MiscDolphin)
|
ADD_SCENE(xtreme_app, misc_dolphin, MiscDolphin)
|
||||||
ADD_SCENE(xtreme_app, misc_rename, MiscRename)
|
ADD_SCENE(xtreme_app, misc_rename, MiscRename)
|
||||||
|
|||||||
@@ -27,10 +27,34 @@ static void xtreme_app_scene_interface_graphics_asset_pack_changed(VariableItem*
|
|||||||
app->apply_pack = true;
|
app->apply_pack = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* const anim_speed_names[] =
|
const char* const anim_speed_names[] = {
|
||||||
{"25%", "50%", "75%", "100%", "125%", "150%", "175%", "200%", "225%", "250%", "275%", "300%"};
|
"25%",
|
||||||
const uint32_t anim_speed_values[COUNT_OF(anim_speed_names)] =
|
"50%",
|
||||||
{25, 50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300};
|
"75%",
|
||||||
|
"100%",
|
||||||
|
"125%",
|
||||||
|
"150%",
|
||||||
|
"175%",
|
||||||
|
"200%",
|
||||||
|
"225%",
|
||||||
|
"250%",
|
||||||
|
"275%",
|
||||||
|
"300%",
|
||||||
|
};
|
||||||
|
const uint32_t anim_speed_values[COUNT_OF(anim_speed_names)] = {
|
||||||
|
25,
|
||||||
|
50,
|
||||||
|
75,
|
||||||
|
100,
|
||||||
|
125,
|
||||||
|
150,
|
||||||
|
175,
|
||||||
|
200,
|
||||||
|
225,
|
||||||
|
250,
|
||||||
|
275,
|
||||||
|
300,
|
||||||
|
};
|
||||||
static void xtreme_app_scene_interface_graphics_anim_speed_changed(VariableItem* item) {
|
static void xtreme_app_scene_interface_graphics_anim_speed_changed(VariableItem* item) {
|
||||||
XtremeApp* app = variable_item_get_context(item);
|
XtremeApp* app = variable_item_get_context(item);
|
||||||
uint8_t index = variable_item_get_current_value_index(item);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
@@ -52,9 +76,23 @@ const char* const cycle_anims_names[] = {
|
|||||||
"2 H",
|
"2 H",
|
||||||
"6 H",
|
"6 H",
|
||||||
"12 H",
|
"12 H",
|
||||||
"24 H"};
|
"24 H",
|
||||||
const int32_t cycle_anims_values[COUNT_OF(cycle_anims_names)] =
|
};
|
||||||
{-1, 0, 30, 60, 300, 600, 900, 1800, 3600, 7200, 21600, 43200, 86400};
|
const int32_t cycle_anims_values[COUNT_OF(cycle_anims_names)] = {
|
||||||
|
-1,
|
||||||
|
0,
|
||||||
|
30,
|
||||||
|
60,
|
||||||
|
300,
|
||||||
|
600,
|
||||||
|
900,
|
||||||
|
1800,
|
||||||
|
3600,
|
||||||
|
7200,
|
||||||
|
21600,
|
||||||
|
43200,
|
||||||
|
86400,
|
||||||
|
};
|
||||||
static void xtreme_app_scene_interface_graphics_cycle_anims_changed(VariableItem* item) {
|
static void xtreme_app_scene_interface_graphics_cycle_anims_changed(VariableItem* item) {
|
||||||
XtremeApp* app = variable_item_get_context(item);
|
XtremeApp* app = variable_item_get_context(item);
|
||||||
uint8_t index = variable_item_get_current_value_index(item);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
|||||||
@@ -13,8 +13,15 @@ void xtreme_app_scene_interface_statusbar_var_item_list_callback(void* context,
|
|||||||
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
view_dispatcher_send_custom_event(app->view_dispatcher, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* const battery_icon_names[BatteryIconCount] =
|
const char* const battery_icon_names[BatteryIconCount] = {
|
||||||
{"OFF", "Bar", "%", "Inv. %", "Retro 3", "Retro 5", "Bar %"};
|
"OFF",
|
||||||
|
"Bar",
|
||||||
|
"%",
|
||||||
|
"Inv. %",
|
||||||
|
"Retro 3",
|
||||||
|
"Retro 5",
|
||||||
|
"Bar %",
|
||||||
|
};
|
||||||
static void xtreme_app_scene_interface_statusbar_battery_icon_changed(VariableItem* item) {
|
static void xtreme_app_scene_interface_statusbar_battery_icon_changed(VariableItem* item) {
|
||||||
XtremeApp* app = variable_item_get_context(item);
|
XtremeApp* app = variable_item_get_context(item);
|
||||||
uint8_t index = variable_item_get_current_value_index(item);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
|||||||
@@ -29,10 +29,30 @@ static void xtreme_app_scene_misc_dolphin_dolphin_angry_changed(VariableItem* it
|
|||||||
app->save_angry = true;
|
app->save_angry = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* const butthurt_timer_names[] =
|
const char* const butthurt_timer_names[] = {
|
||||||
{"OFF", "30 M", "1 H", "2 H", "4 H", "6 H", "8 H", "12 H", "24 H", "48 H"};
|
"OFF",
|
||||||
const uint32_t butthurt_timer_values[COUNT_OF(butthurt_timer_names)] =
|
"30 M",
|
||||||
{0, 1800, 3600, 7200, 14400, 21600, 28800, 43200, 86400, 172800};
|
"1 H",
|
||||||
|
"2 H",
|
||||||
|
"4 H",
|
||||||
|
"6 H",
|
||||||
|
"8 H",
|
||||||
|
"12 H",
|
||||||
|
"24 H",
|
||||||
|
"48 H",
|
||||||
|
};
|
||||||
|
const uint32_t butthurt_timer_values[COUNT_OF(butthurt_timer_names)] = {
|
||||||
|
0,
|
||||||
|
1800,
|
||||||
|
3600,
|
||||||
|
7200,
|
||||||
|
14400,
|
||||||
|
21600,
|
||||||
|
28800,
|
||||||
|
43200,
|
||||||
|
86400,
|
||||||
|
172800,
|
||||||
|
};
|
||||||
static void xtreme_app_scene_misc_dolphin_butthurt_timer_changed(VariableItem* item) {
|
static void xtreme_app_scene_misc_dolphin_butthurt_timer_changed(VariableItem* item) {
|
||||||
XtremeApp* app = variable_item_get_context(item);
|
XtremeApp* app = variable_item_get_context(item);
|
||||||
uint8_t index = variable_item_get_current_value_index(item);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
|||||||
@@ -4,7 +4,13 @@ enum VarItemListIndex {
|
|||||||
VarItemListIndexDarkMode,
|
VarItemListIndexDarkMode,
|
||||||
VarItemListIndexLeftHanded,
|
VarItemListIndexLeftHanded,
|
||||||
VarItemListIndexRgbBacklight,
|
VarItemListIndexRgbBacklight,
|
||||||
VarItemListIndexLcdColor,
|
VarItemListIndexLcdColor0,
|
||||||
|
VarItemListIndexLcdColor1,
|
||||||
|
VarItemListIndexLcdColor2,
|
||||||
|
VarItemListIndexRainbowLcd,
|
||||||
|
VarItemListIndexRainbowSpeed,
|
||||||
|
VarItemListIndexRainbowInterval,
|
||||||
|
VarItemListIndexRainbowSaturation,
|
||||||
};
|
};
|
||||||
|
|
||||||
void xtreme_app_scene_misc_screen_var_item_list_callback(void* context, uint32_t index) {
|
void xtreme_app_scene_misc_screen_var_item_list_callback(void* context, uint32_t index) {
|
||||||
@@ -30,13 +36,117 @@ static void xtreme_app_scene_misc_screen_hand_orient_changed(VariableItem* item)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void xtreme_app_scene_misc_screen_lcd_color_changed(VariableItem* item) {
|
static const struct {
|
||||||
|
char* name;
|
||||||
|
RgbColor color;
|
||||||
|
} lcd_colors[] = {
|
||||||
|
{"Orange", {255, 69, 0}},
|
||||||
|
{"Red", {255, 0, 0}},
|
||||||
|
{"Maroon", {128, 0, 0}},
|
||||||
|
{"Yellow", {255, 255, 0}},
|
||||||
|
{"Olive", {128, 128, 0}},
|
||||||
|
{"Lime", {0, 255, 0}},
|
||||||
|
{"Green", {0, 128, 0}},
|
||||||
|
{"Aqua", {0, 255, 127}},
|
||||||
|
{"Cyan", {0, 210, 210}},
|
||||||
|
{"Azure", {0, 127, 255}},
|
||||||
|
{"Teal", {0, 128, 128}},
|
||||||
|
{"Blue", {0, 0, 255}},
|
||||||
|
{"Navy", {0, 0, 128}},
|
||||||
|
{"Purple", {128, 0, 128}},
|
||||||
|
{"Fuchsia", {255, 0, 255}},
|
||||||
|
{"Pink", {173, 31, 173}},
|
||||||
|
{"Brown", {165, 42, 42}},
|
||||||
|
{"White", {255, 192, 203}},
|
||||||
|
};
|
||||||
|
static void xtreme_app_scene_misc_screen_lcd_color_changed(VariableItem* item, uint8_t led) {
|
||||||
XtremeApp* app = variable_item_get_context(item);
|
XtremeApp* app = variable_item_get_context(item);
|
||||||
uint8_t index = variable_item_get_current_value_index(item);
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
variable_item_set_current_value_text(item, rgb_backlight_get_color_text(index));
|
variable_item_set_current_value_text(item, lcd_colors[index].name);
|
||||||
rgb_backlight_set_color(index);
|
rgb_backlight_set_color(led, lcd_colors[index].color);
|
||||||
|
app->save_backlight = true;
|
||||||
|
}
|
||||||
|
static void xtreme_app_scene_misc_screen_lcd_color_0_changed(VariableItem* item) {
|
||||||
|
xtreme_app_scene_misc_screen_lcd_color_changed(item, 0);
|
||||||
|
}
|
||||||
|
static void xtreme_app_scene_misc_screen_lcd_color_1_changed(VariableItem* item) {
|
||||||
|
xtreme_app_scene_misc_screen_lcd_color_changed(item, 1);
|
||||||
|
}
|
||||||
|
static void xtreme_app_scene_misc_screen_lcd_color_2_changed(VariableItem* item) {
|
||||||
|
xtreme_app_scene_misc_screen_lcd_color_changed(item, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* const rainbow_lcd_names[RGBBacklightRainbowModeCount] = {
|
||||||
|
"OFF",
|
||||||
|
"Wave",
|
||||||
|
"Static",
|
||||||
|
};
|
||||||
|
static void xtreme_app_scene_misc_screen_rainbow_lcd_changed(VariableItem* item) {
|
||||||
|
XtremeApp* app = variable_item_get_context(item);
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
variable_item_set_current_value_text(item, rainbow_lcd_names[index]);
|
||||||
|
rgb_backlight_set_rainbow_mode(index);
|
||||||
|
app->save_backlight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xtreme_app_scene_misc_screen_rainbow_speed_changed(VariableItem* item) {
|
||||||
|
XtremeApp* app = variable_item_get_context(item);
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item) + 1;
|
||||||
|
char str[4];
|
||||||
|
snprintf(str, sizeof(str), "%d", index);
|
||||||
|
variable_item_set_current_value_text(item, str);
|
||||||
|
rgb_backlight_set_rainbow_speed(index);
|
||||||
|
app->save_backlight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* const rainbow_interval_names[] = {
|
||||||
|
"0.1 S",
|
||||||
|
"0.2 S",
|
||||||
|
"0.25 S",
|
||||||
|
"0.5 S",
|
||||||
|
"0.75 S",
|
||||||
|
"1 S",
|
||||||
|
"1.25 S",
|
||||||
|
"1.5 S",
|
||||||
|
"1.75 S",
|
||||||
|
"2 S",
|
||||||
|
"2.5 S",
|
||||||
|
"3 S",
|
||||||
|
"4 S",
|
||||||
|
"5 S",
|
||||||
|
};
|
||||||
|
const uint32_t rainbow_interval_values[COUNT_OF(rainbow_interval_names)] = {
|
||||||
|
100,
|
||||||
|
200,
|
||||||
|
250,
|
||||||
|
500,
|
||||||
|
750,
|
||||||
|
1000,
|
||||||
|
1250,
|
||||||
|
1500,
|
||||||
|
1750,
|
||||||
|
2000,
|
||||||
|
2500,
|
||||||
|
3000,
|
||||||
|
4000,
|
||||||
|
5000,
|
||||||
|
};
|
||||||
|
static void xtreme_app_scene_misc_screen_rainbow_interval_changed(VariableItem* item) {
|
||||||
|
XtremeApp* app = variable_item_get_context(item);
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item);
|
||||||
|
variable_item_set_current_value_text(item, rainbow_interval_names[index]);
|
||||||
|
rgb_backlight_set_rainbow_interval(rainbow_interval_values[index]);
|
||||||
|
app->save_backlight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void xtreme_app_scene_misc_screen_rainbow_saturation_changed(VariableItem* item) {
|
||||||
|
XtremeApp* app = variable_item_get_context(item);
|
||||||
|
uint8_t index = variable_item_get_current_value_index(item) + 1;
|
||||||
|
char str[4];
|
||||||
|
snprintf(str, sizeof(str), "%d", index);
|
||||||
|
variable_item_set_current_value_text(item, str);
|
||||||
|
rgb_backlight_set_rainbow_saturation(index);
|
||||||
app->save_backlight = true;
|
app->save_backlight = true;
|
||||||
notification_message(app->notification, &sequence_display_backlight_on);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void xtreme_app_scene_misc_screen_on_enter(void* context) {
|
void xtreme_app_scene_misc_screen_on_enter(void* context) {
|
||||||
@@ -60,15 +170,87 @@ void xtreme_app_scene_misc_screen_on_enter(void* context) {
|
|||||||
item = variable_item_list_add(var_item_list, "RGB Backlight", 1, NULL, app);
|
item = variable_item_list_add(var_item_list, "RGB Backlight", 1, NULL, app);
|
||||||
variable_item_set_current_value_text(item, xtreme_settings->rgb_backlight ? "ON" : "OFF");
|
variable_item_set_current_value_text(item, xtreme_settings->rgb_backlight ? "ON" : "OFF");
|
||||||
|
|
||||||
|
struct {
|
||||||
|
uint8_t led;
|
||||||
|
const char* str;
|
||||||
|
VariableItemChangeCallback cb;
|
||||||
|
} lcd_cols[] = {
|
||||||
|
{0, "LCD Left", xtreme_app_scene_misc_screen_lcd_color_0_changed},
|
||||||
|
{1, "LCD Middle", xtreme_app_scene_misc_screen_lcd_color_1_changed},
|
||||||
|
{2, "LCD Right", xtreme_app_scene_misc_screen_lcd_color_2_changed},
|
||||||
|
};
|
||||||
|
size_t lcd_sz = COUNT_OF(lcd_colors);
|
||||||
|
|
||||||
|
for(size_t i = 0; i < COUNT_OF(lcd_cols); i++) {
|
||||||
|
item = variable_item_list_add(var_item_list, lcd_cols[i].str, lcd_sz, lcd_cols[i].cb, app);
|
||||||
|
RgbColor color = rgb_backlight_get_color(lcd_cols[i].led);
|
||||||
|
bool found = false;
|
||||||
|
for(size_t i = 0; i < lcd_sz; i++) {
|
||||||
|
if(rgbcmp(&color, &lcd_colors[i].color) != 0) continue;
|
||||||
|
value_index = i;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
variable_item_set_current_value_index(item, found ? value_index : lcd_sz);
|
||||||
|
if(found) {
|
||||||
|
variable_item_set_current_value_text(item, lcd_colors[value_index].name);
|
||||||
|
} else {
|
||||||
|
char str[7];
|
||||||
|
snprintf(str, sizeof(str), "%02X%02X%02X", color.r, color.g, color.b);
|
||||||
|
variable_item_set_current_value_text(item, str);
|
||||||
|
}
|
||||||
|
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
|
||||||
|
}
|
||||||
|
|
||||||
item = variable_item_list_add(
|
item = variable_item_list_add(
|
||||||
var_item_list,
|
var_item_list,
|
||||||
"LCD Color",
|
"Rainbow LCD",
|
||||||
rgb_backlight_get_color_count(),
|
RGBBacklightRainbowModeCount,
|
||||||
xtreme_app_scene_misc_screen_lcd_color_changed,
|
xtreme_app_scene_misc_screen_rainbow_lcd_changed,
|
||||||
app);
|
app);
|
||||||
value_index = rgb_backlight_get_settings()->display_color_index;
|
value_index = rgb_backlight_get_rainbow_mode();
|
||||||
variable_item_set_current_value_index(item, value_index);
|
variable_item_set_current_value_index(item, value_index);
|
||||||
variable_item_set_current_value_text(item, rgb_backlight_get_color_text(value_index));
|
variable_item_set_current_value_text(item, rainbow_lcd_names[value_index]);
|
||||||
|
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
|
||||||
|
|
||||||
|
item = variable_item_list_add(
|
||||||
|
var_item_list,
|
||||||
|
"Rainbow Speed",
|
||||||
|
25,
|
||||||
|
xtreme_app_scene_misc_screen_rainbow_speed_changed,
|
||||||
|
app);
|
||||||
|
value_index = rgb_backlight_get_rainbow_speed();
|
||||||
|
variable_item_set_current_value_index(item, value_index - 1);
|
||||||
|
char speed_str[4];
|
||||||
|
snprintf(speed_str, sizeof(speed_str), "%d", value_index);
|
||||||
|
variable_item_set_current_value_text(item, speed_str);
|
||||||
|
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
|
||||||
|
|
||||||
|
item = variable_item_list_add(
|
||||||
|
var_item_list,
|
||||||
|
"Rainbow Interval",
|
||||||
|
COUNT_OF(rainbow_interval_values),
|
||||||
|
xtreme_app_scene_misc_screen_rainbow_interval_changed,
|
||||||
|
app);
|
||||||
|
value_index = value_index_uint32(
|
||||||
|
rgb_backlight_get_rainbow_interval(),
|
||||||
|
rainbow_interval_values,
|
||||||
|
COUNT_OF(rainbow_interval_values));
|
||||||
|
variable_item_set_current_value_index(item, value_index);
|
||||||
|
variable_item_set_current_value_text(item, rainbow_interval_names[value_index]);
|
||||||
|
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
|
||||||
|
|
||||||
|
item = variable_item_list_add(
|
||||||
|
var_item_list,
|
||||||
|
"Rainbow Saturation",
|
||||||
|
25,
|
||||||
|
xtreme_app_scene_misc_screen_rainbow_saturation_changed,
|
||||||
|
app);
|
||||||
|
value_index = rgb_backlight_get_rainbow_saturation();
|
||||||
|
variable_item_set_current_value_index(item, value_index - 1);
|
||||||
|
char saturation_str[4];
|
||||||
|
snprintf(saturation_str, sizeof(saturation_str), "%d", value_index);
|
||||||
|
variable_item_set_current_value_text(item, saturation_str);
|
||||||
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
|
variable_item_set_locked(item, !xtreme_settings->rgb_backlight, "Needs RGB\nBacklight!");
|
||||||
|
|
||||||
variable_item_list_set_enter_callback(
|
variable_item_list_set_enter_callback(
|
||||||
@@ -110,12 +292,23 @@ bool xtreme_app_scene_misc_screen_on_event(void* context, SceneManagerEvent even
|
|||||||
if(change) {
|
if(change) {
|
||||||
XTREME_SETTINGS()->rgb_backlight = !XTREME_SETTINGS()->rgb_backlight;
|
XTREME_SETTINGS()->rgb_backlight = !XTREME_SETTINGS()->rgb_backlight;
|
||||||
app->save_settings = true;
|
app->save_settings = true;
|
||||||
|
app->save_backlight = true;
|
||||||
notification_message(app->notification, &sequence_display_backlight_on);
|
notification_message(app->notification, &sequence_display_backlight_on);
|
||||||
|
rgb_backlight_reconfigure(XTREME_SETTINGS()->rgb_backlight);
|
||||||
scene_manager_previous_scene(app->scene_manager);
|
scene_manager_previous_scene(app->scene_manager);
|
||||||
scene_manager_next_scene(app->scene_manager, XtremeAppSceneMiscScreen);
|
scene_manager_next_scene(app->scene_manager, XtremeAppSceneMiscScreen);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case VarItemListIndexLcdColor0:
|
||||||
|
case VarItemListIndexLcdColor1:
|
||||||
|
case VarItemListIndexLcdColor2:
|
||||||
|
scene_manager_set_scene_state(
|
||||||
|
app->scene_manager,
|
||||||
|
XtremeAppSceneMiscScreenColor,
|
||||||
|
event.event - VarItemListIndexLcdColor0);
|
||||||
|
scene_manager_next_scene(app->scene_manager, XtremeAppSceneMiscScreenColor);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#include "../xtreme_app.h"
|
||||||
|
|
||||||
|
enum ByteInputResult {
|
||||||
|
ByteInputResultOk,
|
||||||
|
};
|
||||||
|
|
||||||
|
void xtreme_app_scene_misc_screen_color_byte_input_callback(void* context) {
|
||||||
|
XtremeApp* app = context;
|
||||||
|
|
||||||
|
view_dispatcher_send_custom_event(app->view_dispatcher, ByteInputResultOk);
|
||||||
|
}
|
||||||
|
|
||||||
|
void xtreme_app_scene_misc_screen_color_on_enter(void* context) {
|
||||||
|
XtremeApp* app = context;
|
||||||
|
ByteInput* byte_input = app->byte_input;
|
||||||
|
|
||||||
|
byte_input_set_header_text(byte_input, "Set LCD Color (#RRGGBB)");
|
||||||
|
|
||||||
|
app->lcd_color = rgb_backlight_get_color(
|
||||||
|
scene_manager_get_scene_state(app->scene_manager, XtremeAppSceneMiscScreenColor));
|
||||||
|
|
||||||
|
byte_input_set_result_callback(
|
||||||
|
byte_input,
|
||||||
|
xtreme_app_scene_misc_screen_color_byte_input_callback,
|
||||||
|
NULL,
|
||||||
|
app,
|
||||||
|
(void*)&app->lcd_color,
|
||||||
|
sizeof(app->lcd_color));
|
||||||
|
|
||||||
|
view_dispatcher_switch_to_view(app->view_dispatcher, XtremeAppViewByteInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool xtreme_app_scene_misc_screen_color_on_event(void* context, SceneManagerEvent event) {
|
||||||
|
XtremeApp* app = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
|
consumed = true;
|
||||||
|
switch(event.event) {
|
||||||
|
case ByteInputResultOk:
|
||||||
|
rgb_backlight_set_color(
|
||||||
|
scene_manager_get_scene_state(app->scene_manager, XtremeAppSceneMiscScreenColor),
|
||||||
|
app->lcd_color);
|
||||||
|
app->save_backlight = true;
|
||||||
|
scene_manager_previous_scene(app->scene_manager);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void xtreme_app_scene_misc_screen_color_on_exit(void* context) {
|
||||||
|
XtremeApp* app = context;
|
||||||
|
byte_input_set_result_callback(app->byte_input, NULL, NULL, NULL, NULL, 0);
|
||||||
|
byte_input_set_header_text(app->byte_input, "");
|
||||||
|
}
|
||||||
@@ -193,6 +193,10 @@ XtremeApp* xtreme_app_alloc() {
|
|||||||
view_dispatcher_add_view(
|
view_dispatcher_add_view(
|
||||||
app->view_dispatcher, XtremeAppViewTextInput, text_input_get_view(app->text_input));
|
app->view_dispatcher, XtremeAppViewTextInput, text_input_get_view(app->text_input));
|
||||||
|
|
||||||
|
app->byte_input = byte_input_alloc();
|
||||||
|
view_dispatcher_add_view(
|
||||||
|
app->view_dispatcher, XtremeAppViewByteInput, byte_input_get_view(app->byte_input));
|
||||||
|
|
||||||
app->popup = popup_alloc();
|
app->popup = popup_alloc();
|
||||||
view_dispatcher_add_view(app->view_dispatcher, XtremeAppViewPopup, popup_get_view(app->popup));
|
view_dispatcher_add_view(app->view_dispatcher, XtremeAppViewPopup, popup_get_view(app->popup));
|
||||||
|
|
||||||
@@ -315,6 +319,8 @@ void xtreme_app_free(XtremeApp* app) {
|
|||||||
submenu_free(app->submenu);
|
submenu_free(app->submenu);
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewTextInput);
|
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewTextInput);
|
||||||
text_input_free(app->text_input);
|
text_input_free(app->text_input);
|
||||||
|
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewByteInput);
|
||||||
|
byte_input_free(app->byte_input);
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewPopup);
|
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewPopup);
|
||||||
popup_free(app->popup);
|
popup_free(app->popup);
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewDialogEx);
|
view_dispatcher_remove_view(app->view_dispatcher, XtremeAppViewDialogEx);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <gui/modules/variable_item_list.h>
|
#include <gui/modules/variable_item_list.h>
|
||||||
#include <gui/modules/submenu.h>
|
#include <gui/modules/submenu.h>
|
||||||
#include <gui/modules/text_input.h>
|
#include <gui/modules/text_input.h>
|
||||||
|
#include <gui/modules/byte_input.h>
|
||||||
#include <gui/modules/popup.h>
|
#include <gui/modules/popup.h>
|
||||||
#include <lib/toolbox/value_index.h>
|
#include <lib/toolbox/value_index.h>
|
||||||
#include <toolbox/stream/file_stream.h>
|
#include <toolbox/stream/file_stream.h>
|
||||||
@@ -42,6 +43,7 @@ typedef struct {
|
|||||||
VariableItemList* var_item_list;
|
VariableItemList* var_item_list;
|
||||||
Submenu* submenu;
|
Submenu* submenu;
|
||||||
TextInput* text_input;
|
TextInput* text_input;
|
||||||
|
ByteInput* byte_input;
|
||||||
Popup* popup;
|
Popup* popup;
|
||||||
DialogEx* dialog_ex;
|
DialogEx* dialog_ex;
|
||||||
|
|
||||||
@@ -57,6 +59,7 @@ typedef struct {
|
|||||||
uint8_t subghz_hopper_index;
|
uint8_t subghz_hopper_index;
|
||||||
char subghz_freq_buffer[XTREME_SUBGHZ_FREQ_BUFFER_SIZE];
|
char subghz_freq_buffer[XTREME_SUBGHZ_FREQ_BUFFER_SIZE];
|
||||||
bool subghz_extend;
|
bool subghz_extend;
|
||||||
|
RgbColor lcd_color;
|
||||||
char device_name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH];
|
char device_name[FURI_HAL_VERSION_ARRAY_NAME_LENGTH];
|
||||||
int32_t dolphin_level;
|
int32_t dolphin_level;
|
||||||
int32_t dolphin_angry;
|
int32_t dolphin_angry;
|
||||||
@@ -79,6 +82,7 @@ typedef enum {
|
|||||||
XtremeAppViewVarItemList,
|
XtremeAppViewVarItemList,
|
||||||
XtremeAppViewSubmenu,
|
XtremeAppViewSubmenu,
|
||||||
XtremeAppViewTextInput,
|
XtremeAppViewTextInput,
|
||||||
|
XtremeAppViewByteInput,
|
||||||
XtremeAppViewPopup,
|
XtremeAppViewPopup,
|
||||||
XtremeAppViewDialogEx,
|
XtremeAppViewDialogEx,
|
||||||
} XtremeAppView;
|
} XtremeAppView;
|
||||||
|
|||||||
@@ -1171,18 +1171,18 @@ Function,+,furi_hal_cortex_timer_is_expired,_Bool,FuriHalCortexTimer
|
|||||||
Function,+,furi_hal_cortex_timer_wait,void,FuriHalCortexTimer
|
Function,+,furi_hal_cortex_timer_wait,void,FuriHalCortexTimer
|
||||||
Function,+,furi_hal_crypto_ctr,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, uint8_t*, size_t"
|
Function,+,furi_hal_crypto_ctr,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, uint8_t*, size_t"
|
||||||
Function,+,furi_hal_crypto_decrypt,_Bool,"const uint8_t*, uint8_t*, size_t"
|
Function,+,furi_hal_crypto_decrypt,_Bool,"const uint8_t*, uint8_t*, size_t"
|
||||||
|
Function,+,furi_hal_crypto_enclave_ensure_key,_Bool,uint8_t
|
||||||
|
Function,+,furi_hal_crypto_enclave_load_key,_Bool,"uint8_t, const uint8_t*"
|
||||||
|
Function,+,furi_hal_crypto_enclave_store_key,_Bool,"FuriHalCryptoKey*, uint8_t*"
|
||||||
|
Function,+,furi_hal_crypto_enclave_unload_key,_Bool,uint8_t
|
||||||
|
Function,+,furi_hal_crypto_enclave_verify,_Bool,"uint8_t*, uint8_t*"
|
||||||
Function,+,furi_hal_crypto_encrypt,_Bool,"const uint8_t*, uint8_t*, size_t"
|
Function,+,furi_hal_crypto_encrypt,_Bool,"const uint8_t*, uint8_t*, size_t"
|
||||||
Function,+,furi_hal_crypto_gcm,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*, _Bool"
|
Function,+,furi_hal_crypto_gcm,_Bool,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*, _Bool"
|
||||||
Function,+,furi_hal_crypto_gcm_decrypt_and_verify,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, const uint8_t*"
|
Function,+,furi_hal_crypto_gcm_decrypt_and_verify,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, const uint8_t*"
|
||||||
Function,+,furi_hal_crypto_gcm_encrypt_and_tag,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*"
|
Function,+,furi_hal_crypto_gcm_encrypt_and_tag,FuriHalCryptoGCMState,"const uint8_t*, const uint8_t*, const uint8_t*, size_t, const uint8_t*, uint8_t*, size_t, uint8_t*"
|
||||||
Function,-,furi_hal_crypto_init,void,
|
Function,-,furi_hal_crypto_init,void,
|
||||||
Function,+,furi_hal_crypto_load_key,_Bool,"const uint8_t*, const uint8_t*"
|
Function,+,furi_hal_crypto_load_key,_Bool,"const uint8_t*, const uint8_t*"
|
||||||
Function,+,furi_hal_crypto_enclave_store_key,_Bool,"FuriHalCryptoKey*, uint8_t*"
|
|
||||||
Function,+,furi_hal_crypto_enclave_load_key,_Bool,"uint8_t, const uint8_t*"
|
|
||||||
Function,+,furi_hal_crypto_enclave_unload_key,_Bool,uint8_t
|
|
||||||
Function,+,furi_hal_crypto_unload_key,_Bool,
|
Function,+,furi_hal_crypto_unload_key,_Bool,
|
||||||
Function,+,furi_hal_crypto_enclave_verify,_Bool,"uint8_t*, uint8_t*"
|
|
||||||
Function,+,furi_hal_crypto_enclave_ensure_key,_Bool,uint8_t
|
|
||||||
Function,+,furi_hal_debug_disable,void,
|
Function,+,furi_hal_debug_disable,void,
|
||||||
Function,+,furi_hal_debug_enable,void,
|
Function,+,furi_hal_debug_enable,void,
|
||||||
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
|
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
|
||||||
@@ -1733,6 +1733,8 @@ Function,+,hex_char_to_hex_nibble,_Bool,"char, uint8_t*"
|
|||||||
Function,+,hex_char_to_uint8,_Bool,"char, char, uint8_t*"
|
Function,+,hex_char_to_uint8,_Bool,"char, char, uint8_t*"
|
||||||
Function,+,hex_chars_to_uint64,_Bool,"const char*, uint64_t*"
|
Function,+,hex_chars_to_uint64,_Bool,"const char*, uint64_t*"
|
||||||
Function,+,hex_chars_to_uint8,_Bool,"const char*, uint8_t*"
|
Function,+,hex_chars_to_uint8,_Bool,"const char*, uint8_t*"
|
||||||
|
Function,+,hsv2rgb,RgbColor,HsvColor
|
||||||
|
Function,+,hsvcmp,int,"const HsvColor*, const HsvColor*"
|
||||||
Function,-,hypot,double,"double, double"
|
Function,-,hypot,double,"double, double"
|
||||||
Function,-,hypotf,float,"float, float"
|
Function,-,hypotf,float,"float, float"
|
||||||
Function,-,hypotl,long double,"long double, long double"
|
Function,-,hypotl,long double,"long double, long double"
|
||||||
@@ -2555,13 +2557,22 @@ Function,-,rfal_platform_spi_acquire,void,
|
|||||||
Function,-,rfal_platform_spi_release,void,
|
Function,-,rfal_platform_spi_release,void,
|
||||||
Function,-,rfal_set_callback_context,void,void*
|
Function,-,rfal_set_callback_context,void,void*
|
||||||
Function,-,rfal_set_state_changed_callback,void,RfalStateChangedCallback
|
Function,-,rfal_set_state_changed_callback,void,RfalStateChangedCallback
|
||||||
Function,+,rgb_backlight_get_color_count,uint8_t,
|
Function,+,rgb2hsv,HsvColor,RgbColor
|
||||||
Function,+,rgb_backlight_get_color_text,const char*,uint8_t
|
Function,+,rgb_backlight_get_color,RgbColor,uint8_t
|
||||||
Function,+,rgb_backlight_get_settings,RGBBacklightSettings*,
|
Function,+,rgb_backlight_get_rainbow_interval,uint32_t,
|
||||||
|
Function,+,rgb_backlight_get_rainbow_mode,RGBBacklightRainbowMode,
|
||||||
|
Function,+,rgb_backlight_get_rainbow_saturation,uint8_t,
|
||||||
|
Function,+,rgb_backlight_get_rainbow_speed,uint8_t,
|
||||||
Function,-,rgb_backlight_load_settings,void,
|
Function,-,rgb_backlight_load_settings,void,
|
||||||
|
Function,+,rgb_backlight_reconfigure,void,_Bool
|
||||||
Function,+,rgb_backlight_save_settings,void,
|
Function,+,rgb_backlight_save_settings,void,
|
||||||
Function,+,rgb_backlight_set_color,void,uint8_t
|
Function,+,rgb_backlight_set_color,void,"uint8_t, RgbColor"
|
||||||
Function,-,rgb_backlight_update,void,uint8_t
|
Function,+,rgb_backlight_set_rainbow_interval,void,uint32_t
|
||||||
|
Function,+,rgb_backlight_set_rainbow_mode,void,RGBBacklightRainbowMode
|
||||||
|
Function,+,rgb_backlight_set_rainbow_saturation,void,uint8_t
|
||||||
|
Function,+,rgb_backlight_set_rainbow_speed,void,uint8_t
|
||||||
|
Function,-,rgb_backlight_update,void,"uint8_t, _Bool"
|
||||||
|
Function,+,rgbcmp,int,"const RgbColor*, const RgbColor*"
|
||||||
Function,-,rindex,char*,"const char*, int"
|
Function,-,rindex,char*,"const char*, int"
|
||||||
Function,-,rint,double,double
|
Function,-,rint,double,double
|
||||||
Function,-,rintf,float,float
|
Function,-,rintf,float,float
|
||||||
|
|||||||
|
@@ -45,7 +45,7 @@ void furi_hal_light_set(Light light, uint8_t value) {
|
|||||||
}
|
}
|
||||||
if(light & LightBacklight) {
|
if(light & LightBacklight) {
|
||||||
if(XTREME_SETTINGS()->rgb_backlight) {
|
if(XTREME_SETTINGS()->rgb_backlight) {
|
||||||
rgb_backlight_update(value);
|
rgb_backlight_update(value, false);
|
||||||
} else {
|
} else {
|
||||||
uint8_t prev =
|
uint8_t prev =
|
||||||
lp5562_get_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite);
|
lp5562_get_channel_value(&furi_hal_i2c_handle_power, LP5562ChannelWhite);
|
||||||
|
|||||||
@@ -19,9 +19,10 @@
|
|||||||
#include "SK6805.h"
|
#include "SK6805.h"
|
||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
|
|
||||||
|
#define TAG "SK6805"
|
||||||
|
|
||||||
/* Настройки */
|
/* Настройки */
|
||||||
#define SK6805_LED_COUNT 3 //Количество светодиодов на плате подсветки
|
#define SK6805_LED_PIN &led_pin // LED connection port
|
||||||
#define SK6805_LED_PIN &led_pin //Порт подключения светодиодов
|
|
||||||
|
|
||||||
#ifdef FURI_DEBUG
|
#ifdef FURI_DEBUG
|
||||||
#define DEBUG_PIN &gpio_ext_pa7
|
#define DEBUG_PIN &gpio_ext_pa7
|
||||||
@@ -53,17 +54,18 @@ void SK6805_set_led_color(uint8_t led_index, uint8_t r, uint8_t g, uint8_t b) {
|
|||||||
led_buffer[led_index][0] = g;
|
led_buffer[led_index][0] = g;
|
||||||
led_buffer[led_index][1] = r;
|
led_buffer[led_index][1] = r;
|
||||||
led_buffer[led_index][2] = b;
|
led_buffer[led_index][2] = b;
|
||||||
|
FURI_LOG_T(TAG, "led: %d, r: %d, g: %d, b: %d", led_index, r, g, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SK6805_update(void) {
|
void SK6805_update(void) {
|
||||||
SK6805_init();
|
SK6805_init();
|
||||||
furi_kernel_lock();
|
furi_kernel_lock();
|
||||||
uint32_t end;
|
uint32_t end;
|
||||||
/* Последовательная отправка цветов светодиодов */
|
// Sequential sending LEDs
|
||||||
for(uint8_t lednumber = 0; lednumber < SK6805_LED_COUNT; lednumber++) {
|
for(uint8_t lednumber = 0; lednumber < SK6805_LED_COUNT; lednumber++) {
|
||||||
//Последовательная отправка цветов светодиода
|
// Sequential sending colors
|
||||||
for(uint8_t color = 0; color < 3; color++) {
|
for(uint8_t color = 0; color < 3; color++) {
|
||||||
//Последовательная отправка битов цвета
|
// Sequentially sending color bits
|
||||||
uint8_t i = 0b10000000;
|
uint8_t i = 0b10000000;
|
||||||
while(i != 0) {
|
while(i != 0) {
|
||||||
if(led_buffer[lednumber][color] & (i)) {
|
if(led_buffer[lednumber][color] & (i)) {
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
|
#define SK6805_LED_COUNT 3 //Количество светодиодов на плате подсветки
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Инициализация линии управления подсветкой
|
* @brief Инициализация линии управления подсветкой
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
RGB backlight FlipperZero driver
|
RGB backlight FlipperZero driver
|
||||||
Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
|
Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
|
||||||
|
Heavily modified by Willy-JL and Z3bro
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,156 +20,243 @@
|
|||||||
#include "rgb_backlight.h"
|
#include "rgb_backlight.h"
|
||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
#include <storage/storage.h>
|
#include <storage/storage.h>
|
||||||
|
#include <toolbox/saved_struct.h>
|
||||||
|
|
||||||
#define RGB_BACKLIGHT_SETTINGS_VERSION 5
|
#define RGB_BACKLIGHT_SETTINGS_MAGIC 0x15
|
||||||
|
#define RGB_BACKLIGHT_SETTINGS_VERSION 6
|
||||||
#define RGB_BACKLIGHT_SETTINGS_PATH CFG_PATH("rgb_backlight.settings")
|
#define RGB_BACKLIGHT_SETTINGS_PATH CFG_PATH("rgb_backlight.settings")
|
||||||
|
|
||||||
#define COLOR_COUNT (sizeof(colors) / sizeof(RGBBacklightColor))
|
static struct {
|
||||||
|
RgbColor colors[SK6805_LED_COUNT];
|
||||||
#define TAG "RGB Backlight"
|
RGBBacklightRainbowMode rainbow_mode;
|
||||||
|
uint8_t rainbow_speed;
|
||||||
static RGBBacklightSettings rgb_settings = {
|
uint32_t rainbow_interval;
|
||||||
.version = RGB_BACKLIGHT_SETTINGS_VERSION,
|
uint32_t rainbow_saturation;
|
||||||
.display_color_index = 0,
|
} rgb_settings = {
|
||||||
.settings_is_loaded = false};
|
.colors =
|
||||||
|
{
|
||||||
static const RGBBacklightColor colors[] = {
|
{255, 69, 0},
|
||||||
{"Orange", 255, 69, 0},
|
{255, 69, 0},
|
||||||
{"Red", 255, 0, 0},
|
{255, 69, 0},
|
||||||
{"Maroon", 128, 0, 0},
|
},
|
||||||
{"Yellow", 255, 255, 0},
|
.rainbow_mode = RGBBacklightRainbowModeOff,
|
||||||
{"Olive", 128, 128, 0},
|
.rainbow_speed = 5,
|
||||||
{"Lime", 0, 255, 0},
|
.rainbow_interval = 250,
|
||||||
{"Green", 0, 128, 0},
|
.rainbow_saturation = 255,
|
||||||
{"Aqua", 0, 255, 127},
|
|
||||||
{"Cyan", 0, 210, 210},
|
|
||||||
{"Azure", 0, 127, 255},
|
|
||||||
{"Teal", 0, 128, 128},
|
|
||||||
{"Blue", 0, 0, 255},
|
|
||||||
{"Navy", 0, 0, 128},
|
|
||||||
{"Purple", 128, 0, 128},
|
|
||||||
{"Fuchsia", 255, 0, 255},
|
|
||||||
{"Pink", 173, 31, 173},
|
|
||||||
{"Brown", 165, 42, 42},
|
|
||||||
{"White", 255, 192, 203},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t rgb_backlight_get_color_count(void) {
|
static struct {
|
||||||
return COLOR_COUNT;
|
bool settings_loaded;
|
||||||
|
bool enabled;
|
||||||
|
bool last_rainbow;
|
||||||
|
uint8_t last_brightness;
|
||||||
|
RgbColor last_colors[SK6805_LED_COUNT];
|
||||||
|
FuriTimer* rainbow_timer;
|
||||||
|
HsvColor rainbow_hsv;
|
||||||
|
} rgb_state = {
|
||||||
|
.settings_loaded = false,
|
||||||
|
.enabled = false,
|
||||||
|
.last_rainbow = true,
|
||||||
|
.last_brightness = 0,
|
||||||
|
.last_colors =
|
||||||
|
{
|
||||||
|
{0, 0, 0},
|
||||||
|
{0, 0, 0},
|
||||||
|
{0, 0, 0},
|
||||||
|
},
|
||||||
|
.rainbow_timer = NULL,
|
||||||
|
.rainbow_hsv = {0, 255, 255},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rainbow_timer(void* ctx) {
|
||||||
|
UNUSED(ctx);
|
||||||
|
rgb_backlight_update(rgb_state.last_brightness, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* rgb_backlight_get_color_text(uint8_t index) {
|
void rgb_backlight_reconfigure(bool enabled) {
|
||||||
return colors[index].name;
|
if(enabled && !rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
rgb_state.enabled = enabled;
|
||||||
|
|
||||||
|
if(rgb_state.enabled && rgb_settings.rainbow_mode != RGBBacklightRainbowModeOff) {
|
||||||
|
if(rgb_state.rainbow_timer == NULL) {
|
||||||
|
rgb_state.rainbow_timer = furi_timer_alloc(rainbow_timer, FuriTimerTypePeriodic, NULL);
|
||||||
|
} else {
|
||||||
|
furi_timer_stop(rgb_state.rainbow_timer);
|
||||||
|
}
|
||||||
|
furi_timer_start(rgb_state.rainbow_timer, rgb_settings.rainbow_interval);
|
||||||
|
} else if(rgb_state.rainbow_timer != NULL) {
|
||||||
|
furi_timer_stop(rgb_state.rainbow_timer);
|
||||||
|
furi_timer_free(rgb_state.rainbow_timer);
|
||||||
|
rgb_state.rainbow_timer = NULL;
|
||||||
|
}
|
||||||
|
rgb_state.rainbow_hsv.s = rgb_settings.rainbow_saturation;
|
||||||
|
|
||||||
|
rgb_backlight_update(rgb_state.last_brightness, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void rgb_backlight_load_settings(void) {
|
void rgb_backlight_load_settings(void) {
|
||||||
//Не загружать данные из внутренней памяти при загрузке в режиме DFU
|
// Do not load data from internal memory when booting in DFU mode
|
||||||
if(!furi_hal_is_normal_boot()) {
|
if(!furi_hal_is_normal_boot() || rgb_state.settings_loaded) {
|
||||||
rgb_settings.settings_is_loaded = true;
|
rgb_state.settings_loaded = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
RGBBacklightSettings settings;
|
saved_struct_load(
|
||||||
File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
|
RGB_BACKLIGHT_SETTINGS_PATH,
|
||||||
const size_t settings_size = sizeof(RGBBacklightSettings);
|
&rgb_settings,
|
||||||
|
sizeof(rgb_settings),
|
||||||
|
RGB_BACKLIGHT_SETTINGS_MAGIC,
|
||||||
|
RGB_BACKLIGHT_SETTINGS_VERSION);
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "loading settings from \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH);
|
rgb_state.settings_loaded = true;
|
||||||
bool fs_result =
|
rgb_backlight_reconfigure(rgb_state.enabled);
|
||||||
storage_file_open(file, RGB_BACKLIGHT_SETTINGS_PATH, FSAM_READ, FSOM_OPEN_EXISTING);
|
|
||||||
|
|
||||||
if(fs_result) {
|
|
||||||
uint16_t bytes_count = storage_file_read(file, &settings, settings_size);
|
|
||||||
|
|
||||||
if(bytes_count != settings_size) {
|
|
||||||
fs_result = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fs_result) {
|
|
||||||
FURI_LOG_I(TAG, "load success");
|
|
||||||
if(settings.version != RGB_BACKLIGHT_SETTINGS_VERSION) {
|
|
||||||
FURI_LOG_E(
|
|
||||||
TAG,
|
|
||||||
"version(%d != %d) mismatch",
|
|
||||||
settings.version,
|
|
||||||
RGB_BACKLIGHT_SETTINGS_VERSION);
|
|
||||||
} else {
|
|
||||||
memcpy(&rgb_settings, &settings, settings_size);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FURI_LOG_E(TAG, "load failed, %s", storage_file_get_error_desc(file));
|
|
||||||
}
|
|
||||||
|
|
||||||
storage_file_close(file);
|
|
||||||
storage_file_free(file);
|
|
||||||
furi_record_close(RECORD_STORAGE);
|
|
||||||
rgb_settings.settings_is_loaded = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void rgb_backlight_save_settings(void) {
|
void rgb_backlight_save_settings(void) {
|
||||||
RGBBacklightSettings settings;
|
saved_struct_save(
|
||||||
File* file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
|
RGB_BACKLIGHT_SETTINGS_PATH,
|
||||||
const size_t settings_size = sizeof(RGBBacklightSettings);
|
&rgb_settings,
|
||||||
|
sizeof(rgb_settings),
|
||||||
|
RGB_BACKLIGHT_SETTINGS_MAGIC,
|
||||||
|
RGB_BACKLIGHT_SETTINGS_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "saving settings to \"%s\"", RGB_BACKLIGHT_SETTINGS_PATH);
|
void rgb_backlight_set_color(uint8_t index, RgbColor color) {
|
||||||
|
if(index >= COUNT_OF(rgb_settings.colors)) return;
|
||||||
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
rgb_settings.colors[index] = color;
|
||||||
|
rgb_backlight_reconfigure(rgb_state.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&settings, &rgb_settings, settings_size);
|
RgbColor rgb_backlight_get_color(uint8_t index) {
|
||||||
|
if(index >= COUNT_OF(rgb_settings.colors)) return (RgbColor){0, 0, 0};
|
||||||
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
return rgb_settings.colors[index];
|
||||||
|
}
|
||||||
|
|
||||||
bool fs_result =
|
void rgb_backlight_set_rainbow_mode(RGBBacklightRainbowMode rainbow_mode) {
|
||||||
storage_file_open(file, RGB_BACKLIGHT_SETTINGS_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS);
|
if(rainbow_mode >= RGBBacklightRainbowModeCount) return;
|
||||||
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
rgb_settings.rainbow_mode = rainbow_mode;
|
||||||
|
rgb_backlight_reconfigure(rgb_state.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
if(fs_result) {
|
RGBBacklightRainbowMode rgb_backlight_get_rainbow_mode() {
|
||||||
uint16_t bytes_count = storage_file_write(file, &settings, settings_size);
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
return rgb_settings.rainbow_mode;
|
||||||
|
}
|
||||||
|
|
||||||
if(bytes_count != settings_size) {
|
void rgb_backlight_set_rainbow_speed(uint8_t rainbow_speed) {
|
||||||
fs_result = false;
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
rgb_settings.rainbow_speed = rainbow_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t rgb_backlight_get_rainbow_speed() {
|
||||||
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
return rgb_settings.rainbow_speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rgb_backlight_set_rainbow_interval(uint32_t rainbow_interval) {
|
||||||
|
if(rainbow_interval < 100) return;
|
||||||
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
rgb_settings.rainbow_interval = rainbow_interval;
|
||||||
|
rgb_backlight_reconfigure(rgb_state.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rgb_backlight_get_rainbow_interval() {
|
||||||
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
return rgb_settings.rainbow_interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rgb_backlight_set_rainbow_saturation(uint8_t rainbow_saturation) {
|
||||||
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
rgb_settings.rainbow_saturation = rainbow_saturation;
|
||||||
|
rgb_backlight_reconfigure(rgb_state.enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t rgb_backlight_get_rainbow_saturation() {
|
||||||
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
return rgb_settings.rainbow_saturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rgb_backlight_update(uint8_t brightness, bool tick) {
|
||||||
|
if(!rgb_state.enabled) return;
|
||||||
|
if(!rgb_state.settings_loaded) {
|
||||||
|
rgb_backlight_load_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(rgb_settings.rainbow_mode) {
|
||||||
|
case RGBBacklightRainbowModeOff: {
|
||||||
|
if(!rgb_state.last_rainbow && rgb_state.last_brightness == brightness &&
|
||||||
|
memcmp(rgb_state.last_colors, rgb_settings.colors, sizeof(rgb_settings.colors)) == 0) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
rgb_state.last_rainbow = false;
|
||||||
|
memcpy(rgb_state.last_colors, rgb_settings.colors, sizeof(rgb_settings.colors));
|
||||||
|
|
||||||
|
float bright = brightness / 255.0f;
|
||||||
|
for(uint8_t i = 0; i < SK6805_get_led_count(); i++) {
|
||||||
|
SK6805_set_led_color(
|
||||||
|
i,
|
||||||
|
rgb_settings.colors[i].r * bright,
|
||||||
|
rgb_settings.colors[i].g * bright,
|
||||||
|
rgb_settings.colors[i].b * bright);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fs_result) {
|
case RGBBacklightRainbowModeWave:
|
||||||
FURI_LOG_I(TAG, "save success");
|
case RGBBacklightRainbowModeSolid: {
|
||||||
} else {
|
rgb_state.last_rainbow = true;
|
||||||
FURI_LOG_E(TAG, "save failed, %s", storage_file_get_error_desc(file));
|
|
||||||
|
if(tick && brightness) {
|
||||||
|
rgb_state.rainbow_hsv.h += rgb_settings.rainbow_speed;
|
||||||
|
} else {
|
||||||
|
if(rgb_state.last_brightness == brightness && rgb_state.last_rainbow) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rgb_state.rainbow_hsv.v = brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
HsvColor hsv = rgb_state.rainbow_hsv;
|
||||||
|
RgbColor rgb = hsv2rgb(hsv);
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < SK6805_get_led_count(); i++) {
|
||||||
|
if(i && rgb_settings.rainbow_mode == RGBBacklightRainbowModeWave) {
|
||||||
|
hsv.h += (50 * i);
|
||||||
|
rgb = hsv2rgb(hsv);
|
||||||
|
}
|
||||||
|
SK6805_set_led_color(i, rgb.r, rgb.g, rgb.b);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
storage_file_close(file);
|
default:
|
||||||
storage_file_free(file);
|
|
||||||
furi_record_close(RECORD_STORAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
RGBBacklightSettings* rgb_backlight_get_settings(void) {
|
|
||||||
if(!rgb_settings.settings_is_loaded) {
|
|
||||||
rgb_backlight_load_settings();
|
|
||||||
}
|
|
||||||
return &rgb_settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rgb_backlight_set_color(uint8_t color_index) {
|
|
||||||
if(color_index > (rgb_backlight_get_color_count() - 1)) color_index = 0;
|
|
||||||
rgb_settings.display_color_index = color_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rgb_backlight_update(uint8_t brightness) {
|
|
||||||
if(!rgb_settings.settings_is_loaded) {
|
|
||||||
rgb_backlight_load_settings();
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint8_t last_color_index = 255;
|
|
||||||
static uint8_t last_brightness = 123;
|
|
||||||
|
|
||||||
if(last_brightness == brightness && last_color_index == rgb_settings.display_color_index)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
last_brightness = brightness;
|
|
||||||
last_color_index = rgb_settings.display_color_index;
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < SK6805_get_led_count(); i++) {
|
|
||||||
uint8_t r = colors[rgb_settings.display_color_index].red * (brightness / 255.0f);
|
|
||||||
uint8_t g = colors[rgb_settings.display_color_index].green * (brightness / 255.0f);
|
|
||||||
uint8_t b = colors[rgb_settings.display_color_index].blue * (brightness / 255.0f);
|
|
||||||
|
|
||||||
SK6805_set_led_color(i, r, g, b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rgb_state.last_brightness = brightness;
|
||||||
SK6805_update();
|
SK6805_update();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
RGB backlight FlipperZero driver
|
RGB backlight FlipperZero driver
|
||||||
Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
|
Copyright (C) 2022-2023 Victor Nikitchuk (https://github.com/quen0n)
|
||||||
|
Heavily modified by Willy-JL and Z3bro
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,69 +19,89 @@
|
|||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include "SK6805.h"
|
#include "SK6805.h"
|
||||||
|
#include <toolbox/colors.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef enum {
|
||||||
char* name;
|
RGBBacklightRainbowModeOff,
|
||||||
uint8_t red;
|
RGBBacklightRainbowModeWave,
|
||||||
uint8_t green;
|
RGBBacklightRainbowModeSolid,
|
||||||
uint8_t blue;
|
RGBBacklightRainbowModeCount,
|
||||||
} RGBBacklightColor;
|
} RGBBacklightRainbowMode;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t version;
|
|
||||||
uint8_t display_color_index;
|
|
||||||
bool settings_is_loaded;
|
|
||||||
} RGBBacklightSettings;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Получить текущие настройки RGB-подсветки
|
* @brief Reconfigure rgb backlight with new settings
|
||||||
*
|
*
|
||||||
* @return Указатель на структуру настроек
|
* @param enabled Whether the rgb backlight is enabled
|
||||||
*/
|
*/
|
||||||
RGBBacklightSettings* rgb_backlight_get_settings(void);
|
void rgb_backlight_reconfigure(bool enabled);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Загрузить настройки подсветки с SD-карты
|
* @brief Load backlight settings from SD card
|
||||||
*/
|
*/
|
||||||
void rgb_backlight_load_settings(void);
|
void rgb_backlight_load_settings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Сохранить текущие настройки RGB-подсветки
|
* @brief Save Current RGB Lighting Settings
|
||||||
*/
|
*/
|
||||||
void rgb_backlight_save_settings(void);
|
void rgb_backlight_save_settings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Применить текущие настройки RGB-подсветки
|
* @brief Change the color of the backlight
|
||||||
*
|
*
|
||||||
* @param brightness Яркость свечения (0-255)
|
* @param index What led to set the color to (0 - SK6805_LED_COUNT-1)
|
||||||
|
* @param color RGB color to use
|
||||||
*/
|
*/
|
||||||
void rgb_backlight_update(uint8_t brightness);
|
void rgb_backlight_set_color(uint8_t index, RgbColor color);
|
||||||
|
|
||||||
|
RgbColor rgb_backlight_get_color(uint8_t index);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Установить цвет RGB-подсветки
|
* @brief Change rainbow mode
|
||||||
*
|
*
|
||||||
* @param color_index Индекс цвета (0 - rgb_backlight_get_color_count())
|
* @param rainbow_mode What mode to use (0 - RGBBacklightRainbowModeCount)
|
||||||
*/
|
*/
|
||||||
void rgb_backlight_set_color(uint8_t color_index);
|
void rgb_backlight_set_rainbow_mode(RGBBacklightRainbowMode rainbow_mode);
|
||||||
|
|
||||||
|
RGBBacklightRainbowMode rgb_backlight_get_rainbow_mode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Получить количество доступных цветов
|
* @brief Change rainbow speed
|
||||||
*
|
*
|
||||||
* @return Число доступных вариантов цвета
|
* @param rainbow_speed What speed to use (0 - 255)
|
||||||
*/
|
*/
|
||||||
uint8_t rgb_backlight_get_color_count(void);
|
void rgb_backlight_set_rainbow_speed(uint8_t rainbow_speed);
|
||||||
|
|
||||||
|
uint8_t rgb_backlight_get_rainbow_speed();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Получить текстовое название цвета
|
* @brief Change rainbow interval
|
||||||
*
|
*
|
||||||
* @param index Индекс из доступных вариантов цвета
|
* @param rainbow_interval What interval to use
|
||||||
* @return Указатель на строку с названием цвета
|
|
||||||
*/
|
*/
|
||||||
const char* rgb_backlight_get_color_text(uint8_t index);
|
void rgb_backlight_set_rainbow_interval(uint32_t rainbow_interval);
|
||||||
|
|
||||||
|
uint32_t rgb_backlight_get_rainbow_interval();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Change rainbow saturation
|
||||||
|
*
|
||||||
|
* @param rainbow_saturation What saturation to use (0 - 255)
|
||||||
|
*/
|
||||||
|
void rgb_backlight_set_rainbow_saturation(uint8_t rainbow_saturation);
|
||||||
|
|
||||||
|
uint8_t rgb_backlight_get_rainbow_saturation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Apply current RGB lighting settings
|
||||||
|
*
|
||||||
|
* @param brightness Backlight intensity (0-255)
|
||||||
|
* @param tick Whether this update was a tick (for rainbow)
|
||||||
|
*/
|
||||||
|
void rgb_backlight_update(uint8_t brightness, bool tick);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
95
lib/toolbox/colors.c
Normal file
95
lib/toolbox/colors.c
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
// https://stackoverflow.com/a/14733008
|
||||||
|
|
||||||
|
#include "colors.h"
|
||||||
|
|
||||||
|
inline int rgbcmp(const RgbColor* a, const RgbColor* b) {
|
||||||
|
return memcmp(a, b, sizeof(RgbColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int hsvcmp(const HsvColor* a, const HsvColor* b) {
|
||||||
|
return memcmp(a, b, sizeof(HsvColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
RgbColor hsv2rgb(HsvColor hsv) {
|
||||||
|
RgbColor rgb;
|
||||||
|
uint8_t region, remainder, p, q, t;
|
||||||
|
|
||||||
|
if(hsv.s == 0) {
|
||||||
|
rgb.r = hsv.v;
|
||||||
|
rgb.g = hsv.v;
|
||||||
|
rgb.b = hsv.v;
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
region = hsv.h / 43;
|
||||||
|
remainder = (hsv.h - (region * 43)) * 6;
|
||||||
|
|
||||||
|
p = (hsv.v * (255 - hsv.s)) >> 8;
|
||||||
|
q = (hsv.v * (255 - ((hsv.s * remainder) >> 8))) >> 8;
|
||||||
|
t = (hsv.v * (255 - ((hsv.s * (255 - remainder)) >> 8))) >> 8;
|
||||||
|
|
||||||
|
switch(region) {
|
||||||
|
case 0:
|
||||||
|
rgb.r = hsv.v;
|
||||||
|
rgb.g = t;
|
||||||
|
rgb.b = p;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
rgb.r = q;
|
||||||
|
rgb.g = hsv.v;
|
||||||
|
rgb.b = p;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
rgb.r = p;
|
||||||
|
rgb.g = hsv.v;
|
||||||
|
rgb.b = t;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
rgb.r = p;
|
||||||
|
rgb.g = q;
|
||||||
|
rgb.b = hsv.v;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
rgb.r = t;
|
||||||
|
rgb.g = p;
|
||||||
|
rgb.b = hsv.v;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rgb.r = hsv.v;
|
||||||
|
rgb.g = p;
|
||||||
|
rgb.b = q;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rgb;
|
||||||
|
}
|
||||||
|
|
||||||
|
HsvColor rgb2hsv(RgbColor rgb) {
|
||||||
|
HsvColor hsv;
|
||||||
|
uint8_t rgbMin, rgbMax;
|
||||||
|
|
||||||
|
rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
|
||||||
|
rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
|
||||||
|
|
||||||
|
hsv.v = rgbMax;
|
||||||
|
if(hsv.v == 0) {
|
||||||
|
hsv.h = 0;
|
||||||
|
hsv.s = 0;
|
||||||
|
return hsv;
|
||||||
|
}
|
||||||
|
|
||||||
|
hsv.s = 255 * ((long)rgbMax - (long)rgbMin) / hsv.v;
|
||||||
|
if(hsv.s == 0) {
|
||||||
|
hsv.h = 0;
|
||||||
|
return hsv;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(rgbMax == rgb.r)
|
||||||
|
hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
|
||||||
|
else if(rgbMax == rgb.g)
|
||||||
|
hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
|
||||||
|
else
|
||||||
|
hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
|
||||||
|
|
||||||
|
return hsv;
|
||||||
|
}
|
||||||
32
lib/toolbox/colors.h
Normal file
32
lib/toolbox/colors.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct RgbColor {
|
||||||
|
uint8_t r;
|
||||||
|
uint8_t g;
|
||||||
|
uint8_t b;
|
||||||
|
} RgbColor;
|
||||||
|
|
||||||
|
typedef struct HsvColor {
|
||||||
|
uint8_t h;
|
||||||
|
uint8_t s;
|
||||||
|
uint8_t v;
|
||||||
|
} HsvColor;
|
||||||
|
|
||||||
|
int rgbcmp(const RgbColor* a, const RgbColor* b);
|
||||||
|
|
||||||
|
int hsvcmp(const HsvColor* a, const HsvColor* b);
|
||||||
|
|
||||||
|
RgbColor hsv2rgb(HsvColor hsv);
|
||||||
|
|
||||||
|
HsvColor rgb2hsv(RgbColor rgb);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "xtreme.h"
|
#include "xtreme.h"
|
||||||
#include <furi_hal.h>
|
#include <furi_hal.h>
|
||||||
|
#include <rgb_backlight.h>
|
||||||
#include <flipper_format/flipper_format.h>
|
#include <flipper_format/flipper_format.h>
|
||||||
|
|
||||||
#define TAG "XtremeSettings"
|
#define TAG "XtremeSettings"
|
||||||
@@ -194,6 +195,8 @@ void XTREME_SETTINGS_LOAD() {
|
|||||||
}
|
}
|
||||||
flipper_format_free(file);
|
flipper_format_free(file);
|
||||||
furi_record_close(RECORD_STORAGE);
|
furi_record_close(RECORD_STORAGE);
|
||||||
|
|
||||||
|
rgb_backlight_reconfigure(x->rgb_backlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XTREME_SETTINGS_SAVE() {
|
void XTREME_SETTINGS_SAVE() {
|
||||||
|
|||||||
Reference in New Issue
Block a user