diff --git a/applications/services/desktop/animations/animation_manager.c b/applications/services/desktop/animations/animation_manager.c index 1e2a521e1..82a84a45f 100644 --- a/applications/services/desktop/animations/animation_manager.c +++ b/applications/services/desktop/animations/animation_manager.c @@ -553,9 +553,9 @@ static void animation_manager_switch_to_one_shot_view(AnimationManager* animatio View* next_view = one_shot_view_get_view(animation_manager->one_shot_view); view_stack_remove_view(animation_manager->view_stack, prev_view); view_stack_add_view(animation_manager->view_stack, next_view); - if(stats.level == 1) { + if(stats.level <= 20) { one_shot_view_start_animation(animation_manager->one_shot_view, &A_Levelup1_128x64); - } else if(stats.level == 2) { + } else if(stats.level >= 21) { one_shot_view_start_animation(animation_manager->one_shot_view, &A_Levelup2_128x64); } else { furi_assert(0); diff --git a/applications/services/desktop/desktop.c b/applications/services/desktop/desktop.c index 578066a6a..65f328911 100644 --- a/applications/services/desktop/desktop.c +++ b/applications/services/desktop/desktop.c @@ -57,7 +57,12 @@ static bool desktop_custom_event_callback(void* context, uint32_t event) { return true; case DesktopGlobalAutoLock: if(!loader_is_locked(desktop->loader)) { - desktop_lock(desktop); + if(desktop->settings.pin_code.length > 0) { + desktop_pin_lock(&desktop->settings); + desktop_lock(desktop); + } else { + desktop_lock(desktop); + } } return true; } diff --git a/applications/services/desktop/desktop_settings.h b/applications/services/desktop/desktop_settings.h index c33aadb76..f0aa93d04 100644 --- a/applications/services/desktop/desktop_settings.h +++ b/applications/services/desktop/desktop_settings.h @@ -43,8 +43,10 @@ typedef struct { typedef struct { uint16_t favorite_primary; uint16_t favorite_secondary; + uint16_t favorite_game; PinCode pin_code; uint8_t is_locked; uint32_t auto_lock_delay_ms; uint8_t displayBatteryPercentage; + bool is_dumbmode; } DesktopSettings; diff --git a/applications/services/desktop/scenes/desktop_scene_lock_menu.c b/applications/services/desktop/scenes/desktop_scene_lock_menu.c index bdd84cadb..6d27f256b 100644 --- a/applications/services/desktop/scenes/desktop_scene_lock_menu.c +++ b/applications/services/desktop/scenes/desktop_scene_lock_menu.c @@ -11,6 +11,7 @@ #include "desktop_scene_i.h" #include "desktop_scene.h" #include "../helpers/pin_lock.h" +#include #define TAG "DesktopSceneLock" @@ -67,6 +68,25 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) { } consumed = true; break; + case DesktopLockMenuEventPinLockShutdown: + if(desktop->settings.pin_code.length > 0) { + desktop_pin_lock(&desktop->settings); + desktop_lock(desktop); + } else { + LoaderStatus status = + loader_start(desktop->loader, "Desktop", DESKTOP_SETTINGS_RUN_PIN_SETUP_ARG); + if(status == LoaderStatusOk) { + scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 1); + } else { + FURI_LOG_E(TAG, "Unable to start desktop settings"); + } + } + consumed = true; + Power* power = furi_record_open(RECORD_POWER); + furi_delay_ms(666); + power_off(power); + furi_record_close(RECORD_POWER); + break; case DesktopLockMenuEventExit: scene_manager_set_scene_state(desktop->scene_manager, DesktopSceneLockMenu, 0); scene_manager_search_and_switch_to_previous_scene( diff --git a/applications/services/desktop/scenes/desktop_scene_main.c b/applications/services/desktop/scenes/desktop_scene_main.c index bc4101ffd..cd2cf9d90 100644 --- a/applications/services/desktop/scenes/desktop_scene_main.c +++ b/applications/services/desktop/scenes/desktop_scene_main.c @@ -86,6 +86,11 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { consumed = true; break; + case DesktopMainEventOpenGames: + loader_show_game_menu(); + consumed = true; + break; + case DesktopMainEventOpenLockMenu: scene_manager_next_scene(desktop->scene_manager, DesktopSceneLockMenu); consumed = true; @@ -111,7 +116,10 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { consumed = true; break; } - + case DesktopMainEventOpenClock: + loader_start(desktop->loader, FLIPPER_APPS[0].name, NULL); + consumed = true; + break; case DesktopMainEventOpenFavoritePrimary: LOAD_DESKTOP_SETTINGS(&desktop->settings); if(desktop->settings.favorite_primary < FLIPPER_APPS_COUNT) { @@ -140,6 +148,19 @@ bool desktop_scene_main_on_event(void* context, SceneManagerEvent event) { } consumed = true; break; + case DesktopMainEventOpenFavoriteGame: + LOAD_DESKTOP_SETTINGS(&desktop->settings); + if(desktop->settings.favorite_game < FLIPPER_GAMES_COUNT) { + LoaderStatus status = loader_start( + desktop->loader, FLIPPER_GAMES[desktop->settings.favorite_game].name, NULL); + if(status != LoaderStatusOk) { + FURI_LOG_E(TAG, "loader_start failed: %d", status); + } + } else { + FURI_LOG_E(TAG, "Can't find game favorite application"); + } + consumed = true; + break; case DesktopAnimationEventCheckAnimation: animation_manager_check_blocking_process(desktop->animation_manager); consumed = true; diff --git a/applications/services/desktop/views/desktop_events.h b/applications/services/desktop/views/desktop_events.h index 5d130be9b..c615240c9 100644 --- a/applications/services/desktop/views/desktop_events.h +++ b/applications/services/desktop/views/desktop_events.h @@ -4,8 +4,11 @@ typedef enum { DesktopMainEventOpenLockMenu, DesktopMainEventOpenArchive, DesktopMainEventOpenFavoritePrimary, + DesktopMainEventOpenClock, DesktopMainEventOpenFavoriteSecondary, + DesktopMainEventOpenFavoriteGame, DesktopMainEventOpenMenu, + DesktopMainEventOpenGames, DesktopMainEventOpenDebug, DesktopMainEventOpenPassport, /**< Broken, don't use it */ DesktopMainEventOpenPowerOff, @@ -28,6 +31,7 @@ typedef enum { DesktopLockMenuEventLock, DesktopLockMenuEventPinLock, + DesktopLockMenuEventPinLockShutdown, DesktopLockMenuEventExit, DesktopAnimationEventCheckAnimation, diff --git a/applications/services/desktop/views/desktop_view_debug.c b/applications/services/desktop/views/desktop_view_debug.c index c965432f1..c0b5b3e65 100644 --- a/applications/services/desktop/views/desktop_view_debug.c +++ b/applications/services/desktop/views/desktop_view_debug.c @@ -75,8 +75,7 @@ void desktop_debug_render(Canvas* canvas, void* model) { c2_ver ? c2_ver->StackTypeString : ""); canvas_draw_str(canvas, 0, 40 + STATUS_BAR_Y_SHIFT, buffer); - snprintf( - buffer, sizeof(buffer), "[%d] %s", version_get_target(ver), version_get_gitbranch(ver)); + snprintf(buffer, sizeof(buffer), "[%d] %s", version_get_target(ver), "dev"); canvas_draw_str(canvas, 0, 50 + STATUS_BAR_Y_SHIFT, buffer); } else { diff --git a/applications/services/desktop/views/desktop_view_lock_menu.c b/applications/services/desktop/views/desktop_view_lock_menu.c index 97d3c4898..ba044c0e6 100644 --- a/applications/services/desktop/views/desktop_view_lock_menu.c +++ b/applications/services/desktop/views/desktop_view_lock_menu.c @@ -1,10 +1,19 @@ #include #include +#include #include "../desktop_i.h" #include "desktop_view_lock_menu.h" +#include "desktop/desktop_settings/desktop_settings_app.h" -#define LOCK_MENU_ITEMS_NB 3 +#define LOCK_MENU_ITEMS_NB 4 + +static void desktop_view_lock_menu_dumbmode_changed(bool isThisGameMode) { + DesktopSettingsApp* app = malloc(sizeof(DesktopSettingsApp)); + LOAD_DESKTOP_SETTINGS(&app->settings); + app->settings.is_dumbmode = isThisGameMode; + SAVE_DESKTOP_SETTINGS(&app->settings); +} void desktop_lock_menu_set_callback( DesktopLockMenuView* lock_menu, @@ -43,6 +52,26 @@ static void lock_menu_callback(void* context, uint8_t index) { case 1: // lock lock_menu->callback(DesktopLockMenuEventPinLock, lock_menu->context); break; + case 2: // DUMB MODE .. NOW LOCK AND SHUTDOWN + with_view_model( + lock_menu->view, (DesktopLockMenuViewModel * model) { + model->hint_timeout = HINT_TIMEOUT; + return true; + }); + furi_delay_us(800); + lock_menu->callback(DesktopLockMenuEventPinLockShutdown, lock_menu->context); + break; + case 3: // GAMES ONLY MODE + with_view_model( + lock_menu->view, (DesktopLockMenuViewModel * model) { + model->hint_timeout = HINT_TIMEOUT; + return true; + }); + furi_delay_us(800); + desktop_view_lock_menu_dumbmode_changed(1); + DOLPHIN_DEED(getRandomDeed()); + lock_menu->callback(DesktopLockMenuEventExit, lock_menu->context); + break; default: // wip message with_view_model( lock_menu->view, (DesktopLockMenuViewModel * model) { @@ -54,26 +83,32 @@ static void lock_menu_callback(void* context, uint8_t index) { } void desktop_lock_menu_render(Canvas* canvas, void* model) { - const char* Lockmenu_Items[LOCK_MENU_ITEMS_NB] = {"Lock", "Lock with PIN", "DUMB mode"}; + const char* Lockmenu_Items[LOCK_MENU_ITEMS_NB] = { + "Lock", "Lock With PIN", "Lock W PIN + Off", "GAMES ONLY"}; DesktopLockMenuViewModel* m = model; canvas_clear(canvas); canvas_set_color(canvas, ColorBlack); canvas_draw_icon(canvas, -57, 0 + STATUS_BAR_Y_SHIFT, &I_DoorLeft_70x55); canvas_draw_icon(canvas, 116, 0 + STATUS_BAR_Y_SHIFT, &I_DoorRight_70x55); - canvas_set_font(canvas, FontSecondary); + canvas_set_font(canvas, FontBatteryPercent); for(uint8_t i = 0; i < LOCK_MENU_ITEMS_NB; ++i) { const char* str = Lockmenu_Items[i]; if(i == 1 && !m->pin_set) str = "Set PIN"; - if(m->hint_timeout && m->idx == 2 && m->idx == i) str = "Not Implemented"; - if(str != NULL) + if(m->hint_timeout && m->idx == 2 && m->idx == i) { + str = "Shutting Down..."; + } else if(m->hint_timeout && m->idx == 3 && m->idx == i) { + str = "UUDDLRLR From Clock"; + } + if(str != NULL) { canvas_draw_str_aligned( - canvas, 64, 9 + (i * 17) + STATUS_BAR_Y_SHIFT, AlignCenter, AlignCenter, str); + canvas, 64, 9 + (i * 13) + STATUS_BAR_Y_SHIFT, AlignCenter, AlignCenter, str); + } - if(m->idx == i) elements_frame(canvas, 15, 1 + (i * 17) + STATUS_BAR_Y_SHIFT, 98, 15); + if(m->idx == i) elements_frame(canvas, 15, 1 + (i * 13) + STATUS_BAR_Y_SHIFT, 98, 15); } } @@ -127,4 +162,4 @@ void desktop_lock_menu_free(DesktopLockMenuView* lock_menu_view) { view_free(lock_menu_view->view); free(lock_menu_view); -} +} \ No newline at end of file diff --git a/applications/services/desktop/views/desktop_view_locked.c b/applications/services/desktop/views/desktop_view_locked.c index 915b26103..86987b1d6 100644 --- a/applications/services/desktop/views/desktop_view_locked.c +++ b/applications/services/desktop/views/desktop_view_locked.c @@ -124,7 +124,7 @@ static void desktop_view_locked_draw(Canvas* canvas, void* model) { } else if(view_state == DesktopViewLockedStateLockedHintShown) { canvas_set_font(canvas, FontSecondary); elements_bold_rounded_frame(canvas, 14, 2 + STATUS_BAR_Y_SHIFT, 99, 48); - elements_multiline_text(canvas, 65, 20 + STATUS_BAR_Y_SHIFT, "To unlock\npress:"); + elements_multiline_text(canvas, 65, 20 + STATUS_BAR_Y_SHIFT, "To Unlock\nPress:"); canvas_draw_icon(canvas, 65, 36 + STATUS_BAR_Y_SHIFT, &I_Pin_back_arrow_10x8); canvas_draw_icon(canvas, 80, 36 + STATUS_BAR_Y_SHIFT, &I_Pin_back_arrow_10x8); canvas_draw_icon(canvas, 95, 36 + STATUS_BAR_Y_SHIFT, &I_Pin_back_arrow_10x8); diff --git a/applications/services/desktop/views/desktop_view_main.c b/applications/services/desktop/views/desktop_view_main.c index 397011a43..4f4b25c76 100644 --- a/applications/services/desktop/views/desktop_view_main.c +++ b/applications/services/desktop/views/desktop_view_main.c @@ -8,12 +8,14 @@ #include "../desktop_i.h" #include "desktop_view_main.h" +#include struct DesktopMainView { View* view; DesktopMainViewCallback callback; void* context; TimerHandle_t poweroff_timer; + bool is_gamemode; }; #define DESKTOP_MAIN_VIEW_POWEROFF_TIMEOUT 2000 @@ -41,26 +43,68 @@ View* desktop_main_get_view(DesktopMainView* main_view) { bool desktop_main_input(InputEvent* event, void* context) { furi_assert(event); furi_assert(context); - DesktopMainView* main_view = context; - if(event->type == InputTypeShort) { - if(event->key == InputKeyOk) { - main_view->callback(DesktopMainEventOpenMenu, main_view->context); - } else if(event->key == InputKeyUp) { - main_view->callback(DesktopMainEventOpenLockMenu, main_view->context); - } else if(event->key == InputKeyDown) { - main_view->callback(DesktopMainEventOpenArchive, main_view->context); - } else if(event->key == InputKeyLeft) { - main_view->callback(DesktopMainEventOpenFavoritePrimary, main_view->context); - } else if(event->key == InputKeyRight) { - main_view->callback(DesktopMainEventOpenPassport, main_view->context); + // change to only check for game mode setting on keypress + if(event->type == InputTypeShort || event->type == InputTypeLong) { + main_view->is_gamemode = false; + DesktopSettings* desktop_settings = malloc(sizeof(DesktopSettings)); + LOAD_DESKTOP_SETTINGS(desktop_settings); + if(desktop_settings->is_dumbmode) main_view->is_gamemode = true; + free(desktop_settings); + } + + if(!main_view->is_gamemode) { + if(event->type == InputTypeShort) { + if(event->key == InputKeyOk) { + main_view->callback(DesktopMainEventOpenMenu, main_view->context); + } else if(event->key == InputKeyUp) { + main_view->callback(DesktopMainEventOpenLockMenu, main_view->context); + } else if(event->key == InputKeyDown) { + main_view->callback(DesktopMainEventOpenArchive, main_view->context); + } else if(event->key == InputKeyLeft) { + main_view->callback(DesktopMainEventOpenFavoritePrimary, main_view->context); + } else if(event->key == InputKeyRight) { + main_view->callback(DesktopMainEventOpenPassport, main_view->context); + } + } else if(event->type == InputTypeLong) { + if(event->key == InputKeyOk) { + main_view->callback(DesktopAnimationEventNewIdleAnimation, main_view->context); + } else if(event->key == InputKeyUp) { + main_view->callback(DesktopMainEventOpenFavoriteGame, main_view->context); + } else if(event->key == InputKeyDown) { + main_view->callback(DesktopMainEventOpenGames, main_view->context); + } else if(event->key == InputKeyLeft) { + main_view->callback(DesktopMainEventOpenFavoriteSecondary, main_view->context); + } else if(event->key == InputKeyRight) { + // THIS DOESNT WORK + } } - } else if(event->type == InputTypeLong) { - if(event->key == InputKeyDown) { - main_view->callback(DesktopMainEventOpenDebug, main_view->context); - } else if(event->key == InputKeyLeft) { - main_view->callback(DesktopMainEventOpenFavoriteSecondary, main_view->context); + } else { + if(event->type == InputTypeShort) { + if(event->key == InputKeyOk) { + main_view->callback(DesktopMainEventOpenGames, main_view->context); + } else if(event->key == InputKeyUp) { + main_view->callback(DesktopMainEventOpenFavoriteGame, main_view->context); + } else if(event->key == InputKeyDown) { + // PREFER TO OPEN GAMES MENU + } else if(event->key == InputKeyLeft) { + main_view->callback(DesktopMainEventOpenClock, main_view->context); + } else if(event->key == InputKeyRight) { + // GOES TO PASSPORT NO MATTER WHAT + } + } else if(event->type == InputTypeLong) { + if(event->key == InputKeyOk) { + main_view->callback(DesktopAnimationEventNewIdleAnimation, main_view->context); + } else if(event->key == InputKeyUp) { + main_view->callback(DesktopMainEventOpenFavoriteGame, main_view->context); + } else if(event->key == InputKeyDown) { + main_view->callback(DesktopMainEventOpenGames, main_view->context); + } else if(event->key == InputKeyLeft) { + main_view->callback(DesktopMainEventOpenClock, main_view->context); + } else if(event->key == InputKeyRight) { + // THIS DOESNT WORK, PASSPORT WILL ONLY OPEN ON REGULAR RIGHT, NOTHING CAN GET ASSIGNED HERE + } } } @@ -80,6 +124,11 @@ bool desktop_main_input(InputEvent* event, void* context) { DesktopMainView* desktop_main_alloc() { DesktopMainView* main_view = malloc(sizeof(DesktopMainView)); + main_view->is_gamemode = false; + DesktopSettings* desktop_settings = malloc(sizeof(DesktopSettings)); + LOAD_DESKTOP_SETTINGS(desktop_settings); + if(desktop_settings->is_dumbmode) main_view->is_gamemode = true; + free(desktop_settings); main_view->view = view_alloc(); view_allocate_model(main_view->view, ViewModelTypeLockFree, 1); @@ -101,4 +150,4 @@ void desktop_main_free(DesktopMainView* main_view) { view_free(main_view->view); furi_timer_free(main_view->poweroff_timer); free(main_view); -} +} \ No newline at end of file diff --git a/applications/services/desktop/views/desktop_view_slideshow.c b/applications/services/desktop/views/desktop_view_slideshow.c index 3462d2f08..b1f310f09 100644 --- a/applications/services/desktop/views/desktop_view_slideshow.c +++ b/applications/services/desktop/views/desktop_view_slideshow.c @@ -61,9 +61,9 @@ static bool desktop_view_slideshow_input(InputEvent* event, void* context) { furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_SHORT); } else if(event->type == InputTypeRelease) { furi_timer_stop(instance->timer); - /*if(!slideshow_is_one_page(model->slideshow)) { - furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG); - }*/ + // if(!slideshow_is_one_page(model->slideshow)) { + // furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG); + // } } } view_commit_model(instance->view, update_view); diff --git a/applications/services/dolphin/dolphin.c b/applications/services/dolphin/dolphin.c index 41eeef3b1..36a0c3296 100644 --- a/applications/services/dolphin/dolphin.c +++ b/applications/services/dolphin/dolphin.c @@ -6,6 +6,7 @@ #include #include #include +#include "furi_hal_random.h" #define DOLPHIN_LOCK_EVENT_FLAG (0x1) #define TAG "Dolphin" @@ -21,6 +22,18 @@ void dolphin_deed(Dolphin* dolphin, DolphinDeed deed) { dolphin_event_send_async(dolphin, &event); } +DolphinDeed getRandomDeed() { + DolphinDeed returnGrp[11] = {1, 8, 12, 17, 21, 25, 26, 5, 10, 15, 20}; + static bool rand_generator_inited = false; + if(!rand_generator_inited) { + srand(furi_get_tick()); + rand_generator_inited = true; + } + uint8_t diceRoll = (rand() % COUNT_OF(returnGrp)); // JUST TO GET IT GOING? AND FIX BUG + diceRoll = (rand() % COUNT_OF(returnGrp)); + return returnGrp[diceRoll]; +} + DolphinStats dolphin_stats(Dolphin* dolphin) { furi_assert(dolphin); diff --git a/applications/services/dolphin/dolphin.h b/applications/services/dolphin/dolphin.h index 41a6a6089..4371729e1 100644 --- a/applications/services/dolphin/dolphin.h +++ b/applications/services/dolphin/dolphin.h @@ -43,6 +43,10 @@ void dolphin_deed(Dolphin* dolphin, DolphinDeed deed); */ DolphinStats dolphin_stats(Dolphin* dolphin); +/** GET RANDOM 3PT DEED + */ +DolphinDeed getRandomDeed(); + /** Flush dolphin queue and save state * Thread safe, blocking */ diff --git a/applications/services/dolphin/helpers/dolphin_deed.c b/applications/services/dolphin/helpers/dolphin_deed.c index b112d82a1..3906664ec 100644 --- a/applications/services/dolphin/helpers/dolphin_deed.c +++ b/applications/services/dolphin/helpers/dolphin_deed.c @@ -34,16 +34,20 @@ static const DolphinDeedWeight dolphin_deed_weights[] = { {3, DolphinAppBadusb}, // DolphinDeedBadUsbPlayScript {3, DolphinAppU2f}, // DolphinDeedU2fAuthorized + + // {3, DolphinAppPlugin}, // DolphinDeedPluginAchivement + // {1, DolphinAppPlugin}, // DolphinDeedPluginMinorAchivement }; static uint8_t dolphin_deed_limits[] = { - 15, // DolphinAppSubGhz - 15, // DolphinAppRfid - 15, // DolphinAppNfc - 15, // DolphinAppIr - 15, // DolphinAppIbutton - 15, // DolphinAppBadusb - 15, // DolphinAppU2f + 100, // DolphinAppSubGhz + 100, // DolphinAppRfid + 100, // DolphinAppNfc + 100, // DolphinAppIr + 100, // DolphinAppIbutton + 100, // DolphinAppBadusb + 100, // DolphinAppU2f + // 198, // DolphinAppPlugin }; _Static_assert(COUNT_OF(dolphin_deed_weights) == DolphinDeedMAX, "dolphin_deed_weights size error"); diff --git a/applications/services/dolphin/helpers/dolphin_deed.h b/applications/services/dolphin/helpers/dolphin_deed.h index 1f63db3ff..d7d8a265a 100644 --- a/applications/services/dolphin/helpers/dolphin_deed.h +++ b/applications/services/dolphin/helpers/dolphin_deed.h @@ -14,6 +14,7 @@ typedef enum { DolphinAppIbutton, DolphinAppBadusb, DolphinAppU2f, + // DolphinAppPlugin, DolphinAppMAX, } DolphinApp; @@ -52,6 +53,9 @@ typedef enum { DolphinDeedU2fAuthorized, + // DolphinDeedPluginAchivement, + // DolphinDeedPluginMinorAchivement, + DolphinDeedMAX, DolphinDeedTestLeft, diff --git a/applications/services/dolphin/helpers/dolphin_state.c b/applications/services/dolphin/helpers/dolphin_state.c index 95e2f42f4..5b2c193d2 100644 --- a/applications/services/dolphin/helpers/dolphin_state.c +++ b/applications/services/dolphin/helpers/dolphin_state.c @@ -14,8 +14,35 @@ #define DOLPHIN_STATE_PATH INT_PATH(DOLPHIN_STATE_FILE_NAME) #define DOLPHIN_STATE_HEADER_MAGIC 0xD0 #define DOLPHIN_STATE_HEADER_VERSION 0x01 -#define LEVEL2_THRESHOLD 300 -#define LEVEL3_THRESHOLD 1800 +#define LEVEL2_THRESHOLD 450 +#define LEVEL3_THRESHOLD 700 +#define LEVEL4_THRESHOLD 1100 +#define LEVEL5_THRESHOLD 1800 +#define LEVEL6_THRESHOLD 2300 +#define LEVEL7_THRESHOLD 2900 +#define LEVEL8_THRESHOLD 3900 +#define LEVEL9_THRESHOLD 5000 +#define LEVEL10_THRESHOLD 5900 +#define LEVEL11_THRESHOLD 7200 +#define LEVEL12_THRESHOLD 8400 +#define LEVEL13_THRESHOLD 10000 +#define LEVEL14_THRESHOLD 11500 +#define LEVEL15_THRESHOLD 13000 +#define LEVEL16_THRESHOLD 15000 +#define LEVEL17_THRESHOLD 18000 +#define LEVEL18_THRESHOLD 20000 +#define LEVEL19_THRESHOLD 22000 +#define LEVEL20_THRESHOLD 25000 +#define LEVEL21_THRESHOLD 33000 +#define LEVEL22_THRESHOLD 41000 +#define LEVEL23_THRESHOLD 50000 +#define LEVEL24_THRESHOLD 62000 +#define LEVEL25_THRESHOLD 75000 +#define LEVEL26_THRESHOLD 90000 +#define LEVEL27_THRESHOLD 105000 +#define LEVEL28_THRESHOLD 120000 +#define LEVEL29_THRESHOLD 135000 +#define LEVEL30_THRESHOLD 155000 #define BUTTHURT_MAX 14 #define BUTTHURT_MIN 0 @@ -80,7 +107,21 @@ uint64_t dolphin_state_timestamp() { } bool dolphin_state_is_levelup(uint32_t icounter) { - return (icounter == LEVEL2_THRESHOLD) || (icounter == LEVEL3_THRESHOLD); + return (icounter == LEVEL2_THRESHOLD) || (icounter == LEVEL3_THRESHOLD) || + (icounter == LEVEL4_THRESHOLD) || (icounter == LEVEL5_THRESHOLD) || + (icounter == LEVEL6_THRESHOLD) || (icounter == LEVEL7_THRESHOLD) || + (icounter == LEVEL8_THRESHOLD) || (icounter == LEVEL9_THRESHOLD) || + (icounter == LEVEL10_THRESHOLD) || (icounter == LEVEL11_THRESHOLD) || + (icounter == LEVEL12_THRESHOLD) || (icounter == LEVEL13_THRESHOLD) || + (icounter == LEVEL14_THRESHOLD) || (icounter == LEVEL15_THRESHOLD) || + (icounter == LEVEL16_THRESHOLD) || (icounter == LEVEL17_THRESHOLD) || + (icounter == LEVEL18_THRESHOLD) || (icounter == LEVEL19_THRESHOLD) || + (icounter == LEVEL20_THRESHOLD) || (icounter == LEVEL21_THRESHOLD) || + (icounter == LEVEL22_THRESHOLD) || (icounter == LEVEL23_THRESHOLD) || + (icounter == LEVEL24_THRESHOLD) || (icounter == LEVEL25_THRESHOLD) || + (icounter == LEVEL26_THRESHOLD) || (icounter == LEVEL27_THRESHOLD) || + (icounter == LEVEL28_THRESHOLD) || (icounter == LEVEL29_THRESHOLD) || + (icounter == LEVEL30_THRESHOLD); } uint8_t dolphin_get_level(uint32_t icounter) { @@ -88,8 +129,62 @@ uint8_t dolphin_get_level(uint32_t icounter) { return 1; } else if(icounter <= LEVEL3_THRESHOLD) { return 2; - } else { + } else if(icounter <= LEVEL4_THRESHOLD) { return 3; + } else if(icounter <= LEVEL5_THRESHOLD) { + return 4; + } else if(icounter <= LEVEL6_THRESHOLD) { + return 5; + } else if(icounter <= LEVEL7_THRESHOLD) { + return 6; + } else if(icounter <= LEVEL8_THRESHOLD) { + return 7; + } else if(icounter <= LEVEL9_THRESHOLD) { + return 8; + } else if(icounter <= LEVEL10_THRESHOLD) { + return 9; + } else if(icounter <= LEVEL11_THRESHOLD) { + return 10; + } else if(icounter <= LEVEL12_THRESHOLD) { + return 11; + } else if(icounter <= LEVEL13_THRESHOLD) { + return 12; + } else if(icounter <= LEVEL14_THRESHOLD) { + return 13; + } else if(icounter <= LEVEL15_THRESHOLD) { + return 14; + } else if(icounter <= LEVEL16_THRESHOLD) { + return 15; + } else if(icounter <= LEVEL17_THRESHOLD) { + return 16; + } else if(icounter <= LEVEL18_THRESHOLD) { + return 16; + } else if(icounter <= LEVEL19_THRESHOLD) { + return 18; + } else if(icounter <= LEVEL20_THRESHOLD) { + return 19; + } else if(icounter <= LEVEL21_THRESHOLD) { + return 20; + } else if(icounter <= LEVEL22_THRESHOLD) { + return 21; + } else if(icounter <= LEVEL23_THRESHOLD) { + return 22; + } else if(icounter <= LEVEL24_THRESHOLD) { + return 23; + } else if(icounter <= LEVEL25_THRESHOLD) { + return 24; + } else if(icounter <= LEVEL26_THRESHOLD) { + return 25; + } else if(icounter <= LEVEL27_THRESHOLD) { + return 26; + } else if(icounter <= LEVEL28_THRESHOLD) { + return 27; + } else if(icounter <= LEVEL29_THRESHOLD) { + return 28; + } else if(icounter <= LEVEL30_THRESHOLD) { + return 29; + } else { + return 30; } } @@ -99,8 +194,62 @@ uint32_t dolphin_state_xp_above_last_levelup(uint32_t icounter) { threshold = 0; } else if(icounter <= LEVEL3_THRESHOLD) { threshold = LEVEL2_THRESHOLD + 1; - } else { + } else if(icounter <= LEVEL4_THRESHOLD) { threshold = LEVEL3_THRESHOLD + 1; + } else if(icounter <= LEVEL5_THRESHOLD) { + threshold = LEVEL4_THRESHOLD + 1; + } else if(icounter <= LEVEL6_THRESHOLD) { + threshold = LEVEL5_THRESHOLD + 1; + } else if(icounter <= LEVEL7_THRESHOLD) { + threshold = LEVEL6_THRESHOLD + 1; + } else if(icounter <= LEVEL8_THRESHOLD) { + threshold = LEVEL7_THRESHOLD + 1; + } else if(icounter <= LEVEL9_THRESHOLD) { + threshold = LEVEL8_THRESHOLD + 1; + } else if(icounter <= LEVEL10_THRESHOLD) { + threshold = LEVEL9_THRESHOLD + 1; + } else if(icounter <= LEVEL11_THRESHOLD) { + threshold = LEVEL10_THRESHOLD + 1; + } else if(icounter <= LEVEL12_THRESHOLD) { + threshold = LEVEL11_THRESHOLD + 1; + } else if(icounter <= LEVEL13_THRESHOLD) { + threshold = LEVEL12_THRESHOLD + 1; + } else if(icounter <= LEVEL14_THRESHOLD) { + threshold = LEVEL13_THRESHOLD + 1; + } else if(icounter <= LEVEL15_THRESHOLD) { + threshold = LEVEL14_THRESHOLD + 1; + } else if(icounter <= LEVEL16_THRESHOLD) { + threshold = LEVEL15_THRESHOLD + 1; + } else if(icounter <= LEVEL17_THRESHOLD) { + threshold = LEVEL16_THRESHOLD + 1; + } else if(icounter <= LEVEL18_THRESHOLD) { + threshold = LEVEL17_THRESHOLD + 1; + } else if(icounter <= LEVEL19_THRESHOLD) { + threshold = LEVEL18_THRESHOLD + 1; + } else if(icounter <= LEVEL20_THRESHOLD) { + threshold = LEVEL19_THRESHOLD + 1; + } else if(icounter <= LEVEL21_THRESHOLD) { + threshold = LEVEL20_THRESHOLD + 1; + } else if(icounter <= LEVEL22_THRESHOLD) { + threshold = LEVEL21_THRESHOLD + 1; + } else if(icounter <= LEVEL23_THRESHOLD) { + threshold = LEVEL22_THRESHOLD + 1; + } else if(icounter <= LEVEL24_THRESHOLD) { + threshold = LEVEL23_THRESHOLD + 1; + } else if(icounter <= LEVEL25_THRESHOLD) { + threshold = LEVEL24_THRESHOLD + 1; + } else if(icounter <= LEVEL26_THRESHOLD) { + threshold = LEVEL25_THRESHOLD + 1; + } else if(icounter <= LEVEL27_THRESHOLD) { + threshold = LEVEL26_THRESHOLD + 1; + } else if(icounter <= LEVEL28_THRESHOLD) { + threshold = LEVEL27_THRESHOLD + 1; + } else if(icounter <= LEVEL29_THRESHOLD) { + threshold = LEVEL28_THRESHOLD + 1; + } else if(icounter <= LEVEL30_THRESHOLD) { + threshold = LEVEL29_THRESHOLD + 1; + } else { + threshold = LEVEL30_THRESHOLD + 1; } return icounter - threshold; } @@ -111,6 +260,60 @@ uint32_t dolphin_state_xp_to_levelup(uint32_t icounter) { threshold = LEVEL2_THRESHOLD; } else if(icounter <= LEVEL3_THRESHOLD) { threshold = LEVEL3_THRESHOLD; + } else if(icounter <= LEVEL4_THRESHOLD) { + threshold = LEVEL4_THRESHOLD; + } else if(icounter <= LEVEL5_THRESHOLD) { + threshold = LEVEL5_THRESHOLD; + } else if(icounter <= LEVEL6_THRESHOLD) { + threshold = LEVEL6_THRESHOLD; + } else if(icounter <= LEVEL7_THRESHOLD) { + threshold = LEVEL7_THRESHOLD; + } else if(icounter <= LEVEL8_THRESHOLD) { + threshold = LEVEL8_THRESHOLD; + } else if(icounter <= LEVEL9_THRESHOLD) { + threshold = LEVEL9_THRESHOLD; + } else if(icounter <= LEVEL10_THRESHOLD) { + threshold = LEVEL10_THRESHOLD; + } else if(icounter <= LEVEL11_THRESHOLD) { + threshold = LEVEL11_THRESHOLD; + } else if(icounter <= LEVEL12_THRESHOLD) { + threshold = LEVEL12_THRESHOLD; + } else if(icounter <= LEVEL13_THRESHOLD) { + threshold = LEVEL13_THRESHOLD; + } else if(icounter <= LEVEL14_THRESHOLD) { + threshold = LEVEL14_THRESHOLD; + } else if(icounter <= LEVEL15_THRESHOLD) { + threshold = LEVEL15_THRESHOLD; + } else if(icounter <= LEVEL16_THRESHOLD) { + threshold = LEVEL16_THRESHOLD; + } else if(icounter <= LEVEL17_THRESHOLD) { + threshold = LEVEL17_THRESHOLD; + } else if(icounter <= LEVEL18_THRESHOLD) { + threshold = LEVEL18_THRESHOLD; + } else if(icounter <= LEVEL19_THRESHOLD) { + threshold = LEVEL19_THRESHOLD; + } else if(icounter <= LEVEL20_THRESHOLD) { + threshold = LEVEL20_THRESHOLD; + } else if(icounter <= LEVEL21_THRESHOLD) { + threshold = LEVEL21_THRESHOLD; + } else if(icounter <= LEVEL22_THRESHOLD) { + threshold = LEVEL22_THRESHOLD; + } else if(icounter <= LEVEL23_THRESHOLD) { + threshold = LEVEL23_THRESHOLD; + } else if(icounter <= LEVEL24_THRESHOLD) { + threshold = LEVEL24_THRESHOLD; + } else if(icounter <= LEVEL25_THRESHOLD) { + threshold = LEVEL25_THRESHOLD; + } else if(icounter <= LEVEL26_THRESHOLD) { + threshold = LEVEL26_THRESHOLD; + } else if(icounter <= LEVEL27_THRESHOLD) { + threshold = LEVEL27_THRESHOLD; + } else if(icounter <= LEVEL28_THRESHOLD) { + threshold = LEVEL28_THRESHOLD; + } else if(icounter <= LEVEL29_THRESHOLD) { + threshold = LEVEL29_THRESHOLD; + } else if(icounter <= LEVEL30_THRESHOLD) { + threshold = LEVEL30_THRESHOLD; } else { threshold = (uint32_t)-1; } @@ -164,7 +367,7 @@ void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed) { int32_t new_butthurt = ((int32_t)dolphin_state->data.butthurt) - (butthurt_icounter_level_old != butthurt_icounter_level_new); new_butthurt = CLAMP(new_butthurt, BUTTHURT_MAX, BUTTHURT_MIN); - + if(new_butthurt >= 7) new_butthurt = BUTTHURT_MIN; // FLIPPER STAYS HAPPY dolphin_state->data.butthurt = new_butthurt; dolphin_state->data.timestamp = dolphin_state_timestamp(); dolphin_state->dirty = true; diff --git a/applications/services/gui/modules/text_input.c b/applications/services/gui/modules/text_input.c index b8098a3b9..25b545679 100644 --- a/applications/services/gui/modules/text_input.c +++ b/applications/services/gui/modules/text_input.c @@ -130,8 +130,8 @@ static bool char_is_lowercase(char letter) { return (letter >= 0x61 && letter <= 0x7A); } -static char char_to_uppercase(const char letter) { - if(letter == '_') { +static char char_to_uppercase(TextInputModel* model, const char letter) { + if(letter == '_' && !model->clear_default_text) { return 0x20; } else if(isalpha(letter)) { return (letter - 0x20); @@ -232,12 +232,13 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) { canvas_set_color(canvas, ColorBlack); } - if(text_length == 0 && char_is_lowercase(keys[column].text)) { + if(model->clear_default_text || + (text_length == 0 && char_is_lowercase(keys[column].text))) { canvas_draw_glyph( canvas, keyboard_origin_x + keys[column].x, keyboard_origin_y + keys[column].y, - char_to_uppercase(keys[column].text)); + char_to_uppercase(model, keys[column].text)); } else { canvas_draw_glyph( canvas, @@ -304,7 +305,7 @@ static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, b uint8_t text_length = strlen(model->text_buffer); if(shift) { - selected = char_to_uppercase(selected); + selected = char_to_uppercase(model, selected); } if(selected == ENTER_KEY) { @@ -323,7 +324,7 @@ static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, b text_length = 0; } if(text_length == 0 && char_is_lowercase(selected)) { - selected = char_to_uppercase(selected); + selected = char_to_uppercase(model, selected); } model->text_buffer[text_length] = selected; model->text_buffer[text_length + 1] = 0; diff --git a/applications/services/loader/loader.c b/applications/services/loader/loader.c index cf7e5a108..a88fe1912 100644 --- a/applications/services/loader/loader.c +++ b/applications/services/loader/loader.c @@ -78,6 +78,10 @@ static FlipperApplication const* loader_find_application_by_name_in_list( const FlipperApplication* loader_find_application_by_name(const char* name) { const FlipperApplication* application = NULL; application = loader_find_application_by_name_in_list(name, FLIPPER_APPS, FLIPPER_APPS_COUNT); + if(!application) { + application = + loader_find_application_by_name_in_list(name, FLIPPER_GAMES, FLIPPER_GAMES_COUNT); + } if(!application) { application = loader_find_application_by_name_in_list(name, FLIPPER_PLUGINS, FLIPPER_PLUGINS_COUNT); @@ -146,6 +150,11 @@ void loader_cli_list(Cli* cli, string_t args, Loader* instance) { printf("\t%s\r\n", FLIPPER_APPS[i].name); } + printf("Games:\r\n"); + for(size_t i = 0; i < FLIPPER_GAMES_COUNT; i++) { + printf("\t%s\r\n", FLIPPER_GAMES[i].name); + } + printf("Plugins:\r\n"); for(size_t i = 0; i < FLIPPER_PLUGINS_COUNT; i++) { printf("\t%s\r\n", FLIPPER_PLUGINS[i].name); @@ -309,6 +318,12 @@ static Loader* loader_alloc() { view_set_previous_callback(menu_get_view(instance->primary_menu), loader_hide_menu); view_dispatcher_add_view( instance->view_dispatcher, LoaderMenuViewPrimary, menu_get_view(instance->primary_menu)); + // Games menu + instance->games_menu = submenu_alloc(); + view_set_context(submenu_get_view(instance->games_menu), instance->games_menu); + view_set_previous_callback(submenu_get_view(instance->games_menu), loader_hide_menu); + view_dispatcher_add_view( + instance->view_dispatcher, LoaderMenuViewGames, submenu_get_view(instance->games_menu)); // Plugins menu instance->plugins_menu = submenu_alloc(); view_set_context(submenu_get_view(instance->plugins_menu), instance->plugins_menu); @@ -353,6 +368,8 @@ static void loader_free(Loader* instance) { menu_free(loader_instance->primary_menu); view_dispatcher_remove_view(loader_instance->view_dispatcher, LoaderMenuViewPrimary); + submenu_free(loader_instance->games_menu); + view_dispatcher_remove_view(loader_instance->view_dispatcher, LoaderMenuViewGames); submenu_free(loader_instance->plugins_menu); view_dispatcher_remove_view(loader_instance->view_dispatcher, LoaderMenuViewPlugins); submenu_free(loader_instance->debug_menu); @@ -388,7 +405,16 @@ static void loader_build_menu() { loader_submenu_callback, (void*)LoaderMenuViewPlugins); } - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug) && (FLIPPER_DEBUG_APPS_COUNT > 0)) { + if(FLIPPER_GAMES_COUNT != 0) { + menu_add_item( + loader_instance->primary_menu, + "Games", + &A_Games_14, + i++, + loader_submenu_callback, + (void*)LoaderMenuViewGames); + } + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { menu_add_item( loader_instance->primary_menu, "Debug Tools", @@ -407,8 +433,18 @@ static void loader_build_menu() { } static void loader_build_submenu() { - FURI_LOG_I(TAG, "Building plugins menu"); + FURI_LOG_I(TAG, "Building games menu"); size_t i; + for(i = 0; i < FLIPPER_GAMES_COUNT; i++) { + submenu_add_item( + loader_instance->games_menu, + FLIPPER_GAMES[i].name, + i, + loader_menu_callback, + (void*)&FLIPPER_GAMES[i]); + } + + FURI_LOG_I(TAG, "Building plugins menu"); for(i = 0; i < FLIPPER_PLUGINS_COUNT; i++) { submenu_add_item( loader_instance->plugins_menu, @@ -444,6 +480,13 @@ void loader_show_menu() { furi_thread_flags_set(loader_instance->loader_thread, LOADER_THREAD_FLAG_SHOW_MENU); } +void loader_show_game_menu() { + furi_assert(loader_instance); + menu_set_selected_item(loader_instance->primary_menu, 10); + view_dispatcher_switch_to_view(loader_instance->view_dispatcher, LoaderMenuViewGames); + view_dispatcher_run(loader_instance->view_dispatcher); +} + void loader_update_menu() { menu_reset(loader_instance->primary_menu); loader_build_menu(); diff --git a/applications/services/loader/loader.h b/applications/services/loader/loader.h index 954e79c57..497c1dd25 100644 --- a/applications/services/loader/loader.h +++ b/applications/services/loader/loader.h @@ -48,6 +48,9 @@ bool loader_is_locked(Loader* instance); /** Show primary loader */ void loader_show_menu(); +/** Show games loader */ +void loader_show_game_menu(); + /** Show primary loader */ void loader_update_menu(); diff --git a/applications/services/loader/loader_i.h b/applications/services/loader/loader_i.h index db91f806c..626d76e13 100644 --- a/applications/services/loader/loader_i.h +++ b/applications/services/loader/loader_i.h @@ -26,6 +26,7 @@ struct Loader { ViewDispatcher* view_dispatcher; Menu* primary_menu; + Submenu* games_menu; Submenu* plugins_menu; Submenu* debug_menu; Submenu* settings_menu; @@ -37,6 +38,7 @@ struct Loader { typedef enum { LoaderMenuViewPrimary, + LoaderMenuViewGames, LoaderMenuViewPlugins, LoaderMenuViewDebug, LoaderMenuViewSettings, diff --git a/applications/services/power/power_service/power.c b/applications/services/power/power_service/power.c index af922a09b..78d19aeac 100644 --- a/applications/services/power/power_service/power.c +++ b/applications/services/power/power_service/power.c @@ -67,7 +67,6 @@ void power_draw_battery_callback(Canvas* canvas, void* context) { } else { //default bar display, added here to serve as fallback/default behaviour. canvas_draw_box(canvas, 2, 2, (power->info.charge + 4) / 5, 4); } - if(power->state == PowerStateCharging) { canvas_set_bitmap_mode(canvas, 1); canvas_set_color(canvas, ColorWhite); @@ -90,16 +89,75 @@ static ViewPort* power_battery_view_port_alloc(Power* power) { return battery_view_port; } +static void power_start_auto_shutdown_timer(Power* power) { + furi_timer_start(power->auto_shutdown_timer, furi_ms_to_ticks(power->shutdown_idle_delay_ms)); +} + +static void power_stop_auto_shutdown_timer(Power* power) { + furi_timer_stop(power->auto_shutdown_timer); +} + +static void power_input_event_callback(const void* value, void* context) { + furi_assert(value); + furi_assert(context); + const InputEvent* event = value; + Power* power = context; + if(event->type == InputTypePress) { + power_start_auto_shutdown_timer(power); + } +} + +static void power_auto_shutdown_arm(Power* power) { + if(power->shutdown_idle_delay_ms) { + power->input_events_subscription = + furi_pubsub_subscribe(power->input_events_pubsub, power_input_event_callback, power); + power_start_auto_shutdown_timer(power); + } +} + +static void power_auto_shutdown_inhibit(Power* power) { + power_stop_auto_shutdown_timer(power); + if(power->input_events_subscription) { + furi_pubsub_unsubscribe(power->input_events_pubsub, power->input_events_subscription); + power->input_events_subscription = NULL; + } +} + +static void power_auto_shutdown_timer_callback(void* context) { + furi_assert(context); + Power* power = context; + power_auto_shutdown_inhibit(power); + power_off(power); +} + +static void auto_shutdown_update(Power* power) { + uint32_t old_time = power->shutdown_idle_delay_ms; + LOAD_POWER_SETTINGS(&power->shutdown_idle_delay_ms); + if(power->shutdown_idle_delay_ms) { + if(power->shutdown_idle_delay_ms != old_time) { + if(old_time) { + power_start_auto_shutdown_timer(power); + } else { + power_auto_shutdown_arm(power); + } + } + } else if(old_time) { + power_auto_shutdown_inhibit(power); + } +} + Power* power_alloc() { Power* power = malloc(sizeof(Power)); // Records power->notification = furi_record_open(RECORD_NOTIFICATION); power->gui = furi_record_open(RECORD_GUI); - // Pubsub power->event_pubsub = furi_pubsub_alloc(); + power->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS); + power->input_events_subscription = NULL; + // State initialization power->state = PowerStateNotCharging; power->battery_low = false; @@ -123,6 +181,10 @@ Power* power_alloc() { power->battery_view_port = power_battery_view_port_alloc(power); power->show_low_bat_level_message = true; + //Auto shutdown timer + power->auto_shutdown_timer = + furi_timer_alloc(power_auto_shutdown_timer_callback, FuriTimerTypeOnce, power); + return power; } @@ -142,6 +204,12 @@ void power_free(Power* power) { // FuriPubSub furi_pubsub_free(power->event_pubsub); + furi_pubsub_free(power->input_events_pubsub); + + if(power->input_events_subscription) { + furi_pubsub_unsubscribe(power->input_events_pubsub, power->input_events_subscription); + power->input_events_subscription = NULL; + } // Records furi_record_close(RECORD_NOTIFICATION); @@ -259,6 +327,11 @@ static void power_check_battery_level_change(Power* power) { int32_t power_srv(void* p) { UNUSED(p); Power* power = power_alloc(); + if(!LOAD_POWER_SETTINGS(&power->shutdown_idle_delay_ms)) { + power->shutdown_idle_delay_ms = 0; + SAVE_POWER_SETTINGS(&power->shutdown_idle_delay_ms); + } + power_auto_shutdown_arm(power); power_update_info(power); furi_record_create(RECORD_POWER, power); @@ -268,6 +341,9 @@ int32_t power_srv(void* p) { free(settings); while(1) { + //Check current setting for automatic shutdown + auto_shutdown_update(power); + // Update data from gauge and charger bool need_refresh = power_update_info(power); @@ -296,7 +372,7 @@ int32_t power_srv(void* p) { furi_delay_ms(1000); } - + power_auto_shutdown_inhibit(power); power_free(power); return 0; diff --git a/applications/services/power/power_service/power_i.h b/applications/services/power/power_service/power_i.h index 434472896..4225e5d27 100644 --- a/applications/services/power/power_service/power_i.h +++ b/applications/services/power/power_service/power_i.h @@ -8,6 +8,7 @@ #include #include "views/power_off.h" +// #include "power/power_settings.h" #include "views/power_unplug_usb.h" #include @@ -29,6 +30,8 @@ struct Power { Gui* gui; NotificationApp* notification; FuriPubSub* event_pubsub; + FuriPubSub* input_events_pubsub; + FuriPubSubSubscription* input_events_subscription; PowerEvent event; PowerState state; @@ -40,6 +43,9 @@ struct Power { uint8_t battery_level; uint8_t power_off_timeout; + uint32_t shutdown_idle_delay_ms; + FuriTimer* auto_shutdown_timer; + FuriMutex* api_mtx; }; diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c index 0ec18af7a..d58c6f0d5 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_favorite.c @@ -7,11 +7,7 @@ static void desktop_settings_scene_favorite_submenu_callback(void* context, uint view_dispatcher_send_custom_event(app->view_dispatcher, index); } -void desktop_settings_scene_favorite_on_enter(void* context) { - DesktopSettingsApp* app = context; - Submenu* submenu = app->submenu; - submenu_reset(submenu); - +void add_favorite_submenu_item(DesktopSettingsApp* app, Submenu* submenu) { for(size_t i = 0; i < FLIPPER_APPS_COUNT; i++) { submenu_add_item( submenu, @@ -20,18 +16,47 @@ void desktop_settings_scene_favorite_on_enter(void* context) { desktop_settings_scene_favorite_submenu_callback, app); } +} - uint32_t primary_favorite = +void add_game_submenu_item(DesktopSettingsApp* app, Submenu* submenu) { + for(size_t i = 0; i < FLIPPER_GAMES_COUNT; i++) { + submenu_add_item( + submenu, + FLIPPER_GAMES[i].name, + i, + desktop_settings_scene_favorite_submenu_callback, + app); + } +} + +void desktop_settings_scene_favorite_on_enter(void* context) { + DesktopSettingsApp* app = context; + Submenu* submenu = app->submenu; + submenu_reset(submenu); + + uint32_t favorite = scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite); - submenu_set_header( - app->submenu, primary_favorite ? "Primary favorite app:" : "Secondary favorite app:"); - - if(primary_favorite) { + switch(favorite) { + case 0: + add_favorite_submenu_item(app, submenu); + submenu_set_header(app->submenu, "Primary Favorite App:"); submenu_set_selected_item(app->submenu, app->settings.favorite_primary); - } else { + break; + case 1: + add_favorite_submenu_item(app, submenu); + submenu_set_header(app->submenu, "Secondary Favorite App:"); submenu_set_selected_item(app->submenu, app->settings.favorite_secondary); + break; + case 2: + add_game_submenu_item(app, submenu); + submenu_set_header(app->submenu, "Favorite Game:"); + submenu_set_selected_item(app->submenu, app->settings.favorite_game); + break; + default: + break; } + view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu); } @@ -39,18 +64,27 @@ bool desktop_settings_scene_favorite_on_event(void* context, SceneManagerEvent e DesktopSettingsApp* app = context; bool consumed = false; - uint32_t primary_favorite = + uint32_t favorite = scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite); if(event.type == SceneManagerEventTypeCustom) { - if(primary_favorite) { + switch(favorite) { + case 0: app->settings.favorite_primary = event.event; - } else { + break; + case 1: app->settings.favorite_secondary = event.event; + break; + case 2: + app->settings.favorite_game = event.event; + break; + default: + break; } - scene_manager_previous_scene(app->scene_manager); - consumed = true; } + + scene_manager_previous_scene(app->scene_manager); + consumed = true; return consumed; } diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c index ce191487d..58c81d95f 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_auth.c @@ -42,7 +42,7 @@ void desktop_settings_scene_pin_auth_on_enter(void* context) { desktop_view_pin_input_set_label_button(app->pin_input_view, "OK"); desktop_view_pin_input_set_label_primary(app->pin_input_view, 0, 0, NULL); desktop_view_pin_input_set_label_secondary( - app->pin_input_view, 0, 8, "Enter your current PIN:"); + app->pin_input_view, 0, 8, "Enter Your Current PIN:"); desktop_view_pin_input_reset_pin(app->pin_input_view); desktop_view_pin_input_unlock_input(app->pin_input_view); view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c index dcbba5df0..30e9b1938 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_disable.c @@ -25,7 +25,7 @@ void desktop_settings_scene_pin_disable_on_enter(void* context) { popup_set_context(app->popup, app); popup_set_callback(app->popup, pin_disable_back_callback); popup_set_icon(app->popup, 0, 2, &I_DolphinMafia_115x62); - popup_set_header(app->popup, "PIN\ndeleted!", 95, 9, AlignCenter, AlignCenter); + popup_set_header(app->popup, "PIN\nDeleted!", 95, 9, AlignCenter, AlignCenter); popup_set_timeout(app->popup, 1500); popup_enable_timeout(app->popup); view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPopup); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_error.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_error.c index dd1e85795..f813525e6 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_error.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_error.c @@ -35,7 +35,7 @@ void desktop_settings_scene_pin_error_on_enter(void* context) { uint32_t state = scene_manager_get_scene_state(app->scene_manager, DesktopSettingsAppScenePinError); if(state == SCENE_STATE_PIN_ERROR_MISMATCH) { - desktop_view_pin_input_set_label_primary(app->pin_input_view, 29, 8, "PIN mismatch!"); + desktop_view_pin_input_set_label_primary(app->pin_input_view, 29, 8, "PIN Mismatch!"); } else if(state == SCENE_STATE_PIN_ERROR_WRONG) { desktop_view_pin_input_set_label_primary(app->pin_input_view, 35, 8, "Wrong PIN!"); } else { diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c index d226181d7..5721846c6 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_menu.c @@ -43,7 +43,7 @@ void desktop_settings_scene_pin_menu_on_enter(void* context) { app); } - submenu_set_header(app->submenu, "Pin code settings:"); + submenu_set_header(app->submenu, "Pin Code Settings:"); submenu_set_selected_item(app->submenu, app->menu_idx); view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewMenu); } diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup.c index bf0f48ae6..6befe5f9d 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup.c @@ -48,7 +48,7 @@ void desktop_settings_scene_pin_setup_on_enter(void* context) { desktop_view_pin_input_set_label_button(app->pin_input_view, "OK"); desktop_view_pin_input_set_label_primary(app->pin_input_view, 0, 0, NULL); desktop_view_pin_input_set_label_secondary( - app->pin_input_view, 0, 8, "Enter from 4 to 10 arrows:"); + app->pin_input_view, 0, 8, "Enter From 4 To 10 Arrows:"); desktop_view_pin_input_reset_pin(app->pin_input_view); desktop_view_pin_input_unlock_input(app->pin_input_view); view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput); @@ -64,7 +64,7 @@ bool desktop_settings_scene_pin_setup_on_event(void* context, SceneManagerEvent desktop_view_pin_input_set_label_button(app->pin_input_view, "OK"); desktop_view_pin_input_set_label_primary(app->pin_input_view, 0, 0, NULL); desktop_view_pin_input_set_label_secondary( - app->pin_input_view, 0, 8, "Confirm your PIN:"); + app->pin_input_view, 0, 8, "Confirm Your PIN:"); desktop_view_pin_input_reset_pin(app->pin_input_view); desktop_view_pin_input_unlock_input(app->pin_input_view); consumed = true; diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c index b2d07e99f..256d75fa6 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_pin_setup_done.c @@ -34,9 +34,9 @@ void desktop_settings_scene_pin_setup_done_on_enter(void* context) { desktop_view_pin_input_set_done_callback(app->pin_input_view, pin_setup_done_callback); desktop_view_pin_input_set_pin(app->pin_input_view, &app->settings.pin_code); desktop_view_pin_input_set_label_button(app->pin_input_view, "Done"); - desktop_view_pin_input_set_label_primary(app->pin_input_view, 29, 8, "PIN activated!"); + desktop_view_pin_input_set_label_primary(app->pin_input_view, 29, 8, "PIN Activated!"); desktop_view_pin_input_set_label_secondary( - app->pin_input_view, 7, 45, "Remember or write it down"); + app->pin_input_view, 7, 45, "Remember Or Write It Down!"); desktop_view_pin_input_lock_input(app->pin_input_view); desktop_view_pin_input_set_pin_position(app->pin_input_view, 64, 24); view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewIdPinInput); diff --git a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c index d3c3aa072..f0671abb0 100644 --- a/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c +++ b/applications/settings/desktop_settings/scenes/desktop_settings_scene_start.c @@ -6,9 +6,11 @@ #define SCENE_EVENT_SELECT_FAVORITE_PRIMARY 0 #define SCENE_EVENT_SELECT_FAVORITE_SECONDARY 1 -#define SCENE_EVENT_SELECT_PIN_SETUP 2 -#define SCENE_EVENT_SELECT_AUTO_LOCK_DELAY 3 -#define SCENE_EVENT_SELECT_BATTERY_DISPLAY 4 +#define SCENE_EVENT_SELECT_FAVORITE_GAME 2 +#define SCENE_EVENT_SELECT_PIN_SETUP 3 +#define SCENE_EVENT_SELECT_AUTO_LOCK_DELAY 4 +#define SCENE_EVENT_SELECT_BATTERY_DISPLAY 5 +#define SCENE_EVENT_SELECT_DUMBMODE 6 #define AUTO_LOCK_DELAY_COUNT 9 const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { @@ -22,12 +24,10 @@ const char* const auto_lock_delay_text[AUTO_LOCK_DELAY_COUNT] = { "5min", "10min", }; - const uint32_t auto_lock_delay_value[AUTO_LOCK_DELAY_COUNT] = {0, 10000, 15000, 30000, 60000, 90000, 120000, 300000, 600000}; #define BATTERY_VIEW_COUNT 5 - const char* const battery_view_count_text[BATTERY_VIEW_COUNT] = { "Bar", "%", @@ -35,22 +35,23 @@ const char* const battery_view_count_text[BATTERY_VIEW_COUNT] = { "Retro 3", "Retro 5", }; - const uint32_t displayBatteryPercentage_value[BATTERY_VIEW_COUNT] = {0, 1, 2, 3, 4}; +uint8_t origBattDisp_value = 0; + +#define DUMBMODE_COUNT 2 +const char* const dumbmode_text[DUMBMODE_COUNT] = { + "OFF", + "ON", +}; + +const uint32_t dumbmode_value[DUMBMODE_COUNT] = {0, 1}; + static void desktop_settings_scene_start_var_list_enter_callback(void* context, uint32_t index) { DesktopSettingsApp* app = context; view_dispatcher_send_custom_event(app->view_dispatcher, index); } -static void desktop_settings_scene_start_battery_view_changed(VariableItem* item) { - DesktopSettingsApp* app = variable_item_get_context(item); - uint8_t index = variable_item_get_current_value_index(item); - - variable_item_set_current_value_text(item, battery_view_count_text[index]); - app->settings.displayBatteryPercentage = index; -} - static void desktop_settings_scene_start_auto_lock_delay_changed(VariableItem* item) { DesktopSettingsApp* app = variable_item_get_context(item); uint8_t index = variable_item_get_current_value_index(item); @@ -59,9 +60,26 @@ static void desktop_settings_scene_start_auto_lock_delay_changed(VariableItem* i app->settings.auto_lock_delay_ms = auto_lock_delay_value[index]; } +static void desktop_settings_scene_start_battery_view_changed(VariableItem* item) { + DesktopSettingsApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, battery_view_count_text[index]); + app->settings.displayBatteryPercentage = index; +} + +static void desktop_settings_scene_start_dumbmode_changed(VariableItem* item) { + DesktopSettingsApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, dumbmode_text[index]); + app->settings.is_dumbmode = dumbmode_value[index]; +} + void desktop_settings_scene_start_on_enter(void* context) { DesktopSettingsApp* app = context; VariableItemList* variable_item_list = app->variable_item_list; + origBattDisp_value = app->settings.displayBatteryPercentage; VariableItem* item; uint8_t value_index; @@ -70,6 +88,8 @@ void desktop_settings_scene_start_on_enter(void* context) { variable_item_list_add(variable_item_list, "Secondary Favorite App", 1, NULL, NULL); + variable_item_list_add(variable_item_list, "Favorite Game", 1, NULL, NULL); + variable_item_list_add(variable_item_list, "PIN Setup", 1, NULL, NULL); item = variable_item_list_add( @@ -79,8 +99,6 @@ void desktop_settings_scene_start_on_enter(void* context) { desktop_settings_scene_start_auto_lock_delay_changed, app); - variable_item_list_set_enter_callback( - variable_item_list, desktop_settings_scene_start_var_list_enter_callback, app); value_index = value_index_uint32( app->settings.auto_lock_delay_ms, auto_lock_delay_value, AUTO_LOCK_DELAY_COUNT); variable_item_set_current_value_index(item, value_index); @@ -100,22 +118,40 @@ void desktop_settings_scene_start_on_enter(void* context) { variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_text(item, battery_view_count_text[value_index]); + item = variable_item_list_add( + variable_item_list, + "Games Only", + DUMBMODE_COUNT, + desktop_settings_scene_start_dumbmode_changed, + app); + + value_index = value_index_uint32(app->settings.is_dumbmode, dumbmode_value, DUMBMODE_COUNT); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, dumbmode_text[value_index]); + + variable_item_list_set_enter_callback( + variable_item_list, desktop_settings_scene_start_var_list_enter_callback, app); view_dispatcher_switch_to_view(app->view_dispatcher, DesktopSettingsAppViewVarItemList); } -bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent event) { +bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent sme) { DesktopSettingsApp* app = context; bool consumed = false; - if(event.type == SceneManagerEventTypeCustom) { - switch(event.event) { + if(sme.type == SceneManagerEventTypeCustom) { + switch(sme.event) { case SCENE_EVENT_SELECT_FAVORITE_PRIMARY: - scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 1); + scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 0); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite); consumed = true; break; case SCENE_EVENT_SELECT_FAVORITE_SECONDARY: - scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 0); + scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 1); + scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite); + consumed = true; + break; + case SCENE_EVENT_SELECT_FAVORITE_GAME: + scene_manager_set_scene_state(app->scene_manager, DesktopSettingsAppSceneFavorite, 2); scene_manager_next_scene(app->scene_manager, DesktopSettingsAppSceneFavorite); consumed = true; break; @@ -129,6 +165,9 @@ bool desktop_settings_scene_start_on_event(void* context, SceneManagerEvent even case SCENE_EVENT_SELECT_BATTERY_DISPLAY: consumed = true; break; + case SCENE_EVENT_SELECT_DUMBMODE: + consumed = true; + break; } } return consumed; @@ -138,4 +177,8 @@ void desktop_settings_scene_start_on_exit(void* context) { DesktopSettingsApp* app = context; variable_item_list_reset(app->variable_item_list); SAVE_DESKTOP_SETTINGS(&app->settings); + + if(app->settings.displayBatteryPercentage != origBattDisp_value) { + furi_hal_power_reset(); + } } diff --git a/applications/settings/desktop_settings/views/desktop_settings_view_pin_setup_howto.c b/applications/settings/desktop_settings/views/desktop_settings_view_pin_setup_howto.c index 3831be8c4..e8bd373a3 100644 --- a/applications/settings/desktop_settings/views/desktop_settings_view_pin_setup_howto.c +++ b/applications/settings/desktop_settings/views/desktop_settings_view_pin_setup_howto.c @@ -23,7 +23,7 @@ static void desktop_settings_view_pin_setup_howto_draw(Canvas* canvas, void* mod elements_button_right(canvas, "Next"); canvas_set_font(canvas, FontPrimary); - elements_multiline_text_aligned(canvas, 64, 0, AlignCenter, AlignTop, "Setting up PIN"); + elements_multiline_text_aligned(canvas, 64, 0, AlignCenter, AlignTop, "Setting Up PIN"); canvas_set_font(canvas, FontSecondary); elements_multiline_text(canvas, 58, 24, "Prepare to use\narrows as\nPIN symbols"); diff --git a/applications/settings/desktop_settings/views/desktop_settings_view_pin_setup_howto2.c b/applications/settings/desktop_settings/views/desktop_settings_view_pin_setup_howto2.c index ab1fa2383..9a2eb8aaa 100644 --- a/applications/settings/desktop_settings/views/desktop_settings_view_pin_setup_howto2.c +++ b/applications/settings/desktop_settings/views/desktop_settings_view_pin_setup_howto2.c @@ -29,7 +29,7 @@ static void desktop_settings_view_pin_setup_howto2_draw(Canvas* canvas, void* mo AlignCenter, "Forgotten PIN can only be\n" "reset with entire device.\n" - "Read docs How to reset PIN."); + "Read docs: How to reset PIN."); elements_button_right(canvas, "OK"); elements_button_left(canvas, "Cancel"); diff --git a/applications/settings/dolphin_passport/passport.c b/applications/settings/dolphin_passport/passport.c index d43f150c6..41a7a1f69 100644 --- a/applications/settings/dolphin_passport/passport.c +++ b/applications/settings/dolphin_passport/passport.c @@ -6,25 +6,51 @@ #include #include #include "dolphin/dolphin.h" +#include "desktop/desktop_settings/desktop_settings_app.h" #include "math.h" -#define MOODS_TOTAL 3 -#define BUTTHURT_MAX 3 +#define MOODS_TOTAL 1 +#define BUTTHURT_MAX 14 -static const Icon* const portrait_happy[BUTTHURT_MAX] = { +static const Icon* const portrait_happy[7] = { &I_passport_happy1_46x49, &I_passport_happy2_46x49, - &I_passport_happy3_46x49}; -static const Icon* const portrait_ok[BUTTHURT_MAX] = { - &I_passport_okay1_46x49, - &I_passport_okay2_46x49, - &I_passport_okay3_46x49}; -static const Icon* const portrait_bad[BUTTHURT_MAX] = { - &I_passport_bad1_46x49, - &I_passport_bad2_46x49, - &I_passport_bad3_46x49}; + &I_passport_happy3_46x49, + &I_G0ku, + &I_g0ku_1, + &I_g0ku_2, + &I_g0ku_3 + }; +// static const Icon* const portrait_ok[MOODS_TOTAL] = { + // &I_passport_okay1_46x49, + // &I_passport_okay2_46x49, + // &I_passport_okay3_46x49}; +// static const Icon* const portrait_bad[MOODS_TOTAL] = { + // &I_passport_bad1_46x49, + // &I_passport_bad2_46x49, + // &I_passport_bad3_46x49}; -static const Icon* const* portraits[MOODS_TOTAL] = {portrait_happy, portrait_ok, portrait_bad}; +// static const Icon* const* portraits[MOODS_TOTAL] = {portrait_happy, portrait_ok, portrait_bad}; +static const Icon* const* portraits[MOODS_TOTAL] = {portrait_happy}; + +static const char* const moods[16] = { + "Stoned", + "Baked", + "Ripped", + "Joyful", + "Happy", + "Satisfied", + "Relaxed", + "Nostalgic", + "Okay", + "Tired", + "Bored", + "Sad", + "Annoyed", + "Upset", + "Angry", + "Furious" +}; static void input_callback(InputEvent* input, void* ctx) { FuriSemaphore* semaphore = ctx; @@ -36,57 +62,59 @@ static void input_callback(InputEvent* input, void* ctx) { static void render_callback(Canvas* canvas, void* ctx) { DolphinStats* stats = ctx; + DesktopSettings* desktop_settings = malloc(sizeof(DesktopSettings)); + LOAD_DESKTOP_SETTINGS(desktop_settings); - char level_str[20]; - char mood_str[32]; + char level_str[12]; + char xp_str[12]; + char mood_str[20]; uint8_t mood = 0; - - if(stats->butthurt <= 4) { - mood = 0; - snprintf(mood_str, 20, "Mood: Happy"); - } else if(stats->butthurt <= 9) { - mood = 1; - snprintf(mood_str, 20, "Mood: Ok"); - } else { - mood = 2; - snprintf(mood_str, 20, "Mood: Angry"); - } + uint8_t moodStrIndex = stats->butthurt; + if(desktop_settings->is_dumbmode) moodStrIndex = moodStrIndex + 4; + snprintf(mood_str, 20, "Mood: %s", moods[moodStrIndex]); + mood = 0; // DONT NEED DIFFERENT PICS BASED ON MOOD uint32_t xp_progress = 0; uint32_t xp_to_levelup = dolphin_state_xp_to_levelup(stats->icounter); - uint32_t xp_for_current_level = - xp_to_levelup + dolphin_state_xp_above_last_levelup(stats->icounter); - if(stats->level == 3) { + uint32_t xp_above_last_levelup = dolphin_state_xp_above_last_levelup(stats->icounter); + uint32_t xp_for_current_level = xp_to_levelup + xp_above_last_levelup; + + if(stats->level == 30) { xp_progress = 0; } else { xp_progress = xp_to_levelup * 64 / xp_for_current_level; } // multipass - canvas_draw_icon(canvas, 0, 0, &I_passport_left_6x46); - canvas_draw_icon(canvas, 0, 46, &I_passport_bottom_128x18); - canvas_draw_line(canvas, 6, 0, 125, 0); - canvas_draw_line(canvas, 127, 2, 127, 47); - canvas_draw_dot(canvas, 126, 1); - + canvas_draw_icon(canvas, 0, 0, &I_passport_DB); + // portrait - furi_assert((stats->level > 0) && (stats->level <= 3)); - canvas_draw_icon(canvas, 9, 5, portraits[mood][stats->level - 1]); - canvas_draw_line(canvas, 58, 16, 123, 16); - canvas_draw_line(canvas, 58, 30, 123, 30); - canvas_draw_line(canvas, 58, 44, 123, 44); - + furi_assert((stats->level > 0) && (stats->level <= 30)); + uint16_t tmpLvl = 0; + if(stats->level > 10) tmpLvl = 1; + if(stats->level > 15) tmpLvl = 2; + if(stats->level > 18) tmpLvl = 3; + if(stats->level > 21) tmpLvl = 4; + if(stats->level > 24) tmpLvl = 5; + if(stats->level > 27) tmpLvl = 6; + canvas_draw_icon(canvas, 11, 2, portraits[mood][tmpLvl]); + const char* my_name = furi_hal_version_get_name_ptr(); - snprintf(level_str, 20, "Level: %hu", stats->level); - canvas_draw_str(canvas, 58, 12, my_name ? my_name : "Unknown"); - canvas_draw_str(canvas, 58, 26, mood_str); - canvas_draw_str(canvas, 58, 40, level_str); + snprintf(level_str, 12, "Level: %hu", stats->level); + snprintf(xp_str, 12, "%lu/%lu", xp_above_last_levelup, xp_for_current_level); + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 58, 10, my_name ? my_name : "Unknown"); + canvas_draw_str(canvas, 58, 22, mood_str); + canvas_set_color(canvas, ColorBlack); + canvas_draw_str(canvas, 58, 34, level_str); + canvas_set_font(canvas, FontBatteryPercent); + canvas_draw_str(canvas, 58, 42, xp_str); + canvas_set_font(canvas, FontSecondary); canvas_set_color(canvas, ColorWhite); - canvas_draw_box(canvas, 123 - xp_progress, 47, xp_progress + 1, 6); + canvas_draw_box(canvas, 123 - xp_progress, 45, xp_progress + 1, 5); canvas_set_color(canvas, ColorBlack); - canvas_draw_line(canvas, 123, 47, 123, 52); -} + } int32_t passport_app(void* p) { UNUSED(p); @@ -112,4 +140,4 @@ int32_t passport_app(void* p) { furi_semaphore_free(semaphore); return 0; -} +} \ No newline at end of file diff --git a/applications/settings/power_settings_app/power_settings_app.c b/applications/settings/power_settings_app/power_settings_app.c index b01f32f75..ec010ee71 100644 --- a/applications/settings/power_settings_app/power_settings_app.c +++ b/applications/settings/power_settings_app/power_settings_app.c @@ -45,11 +45,16 @@ PowerSettingsApp* power_settings_app_alloc(uint32_t first_scene) { PowerSettingsAppViewBatteryInfo, battery_info_get_view(app->batery_info)); app->submenu = submenu_alloc(); + app->variable_item_list = variable_item_list_alloc(); view_dispatcher_add_view( app->view_dispatcher, PowerSettingsAppViewSubmenu, submenu_get_view(app->submenu)); app->dialog = dialog_ex_alloc(); view_dispatcher_add_view( app->view_dispatcher, PowerSettingsAppViewDialog, dialog_ex_get_view(app->dialog)); + view_dispatcher_add_view( + app->view_dispatcher, + PowerSettingsAppViewVariableItemList, + variable_item_list_get_view(app->variable_item_list)); // Set first scene scene_manager_next_scene(app->scene_manager, first_scene); @@ -63,8 +68,10 @@ void power_settings_app_free(PowerSettingsApp* app) { battery_info_free(app->batery_info); view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewSubmenu); submenu_free(app->submenu); + variable_item_list_free(app->variable_item_list); view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewDialog); dialog_ex_free(app->dialog); + view_dispatcher_remove_view(app->view_dispatcher, PowerSettingsAppViewVariableItemList); // View dispatcher view_dispatcher_free(app->view_dispatcher); scene_manager_free(app->scene_manager); diff --git a/applications/settings/power_settings_app/power_settings_app.h b/applications/settings/power_settings_app/power_settings_app.h index 8429b54b4..d16fe06f5 100644 --- a/applications/settings/power_settings_app/power_settings_app.h +++ b/applications/settings/power_settings_app/power_settings_app.h @@ -10,7 +10,9 @@ #include "views/battery_info.h" #include #include +#include +// #include "power/power_settings.h" #include "scenes/power_settings_scene.h" typedef struct { @@ -22,10 +24,13 @@ typedef struct { Submenu* submenu; DialogEx* dialog; PowerInfo info; + VariableItemList* variable_item_list; + uint32_t shutdown_idle_delay_ms; } PowerSettingsApp; typedef enum { PowerSettingsAppViewBatteryInfo, PowerSettingsAppViewSubmenu, PowerSettingsAppViewDialog, + PowerSettingsAppViewVariableItemList } PowerSettingsAppView; diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_config.h b/applications/settings/power_settings_app/scenes/power_settings_scene_config.h index cc8656dcf..b6a6d4d05 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_config.h +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_config.h @@ -2,3 +2,4 @@ ADD_SCENE(power_settings, start, Start) ADD_SCENE(power_settings, battery_info, BatteryInfo) ADD_SCENE(power_settings, reboot, Reboot) ADD_SCENE(power_settings, power_off, PowerOff) +ADD_SCENE(power_settings, shutdown_idle, ShutdownIdle) diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_reboot.c b/applications/settings/power_settings_app/scenes/power_settings_scene_reboot.c index 2d879612e..2d5dedfd4 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_reboot.c +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_reboot.c @@ -15,10 +15,10 @@ void power_settings_scene_reboot_on_enter(void* context) { PowerSettingsApp* app = context; Submenu* submenu = app->submenu; - submenu_set_header(submenu, "Reboot type"); + submenu_set_header(submenu, "Reboot Type"); submenu_add_item( submenu, - "Firmware upgrade", + "Firmware Upgrade", PowerSettingsRebootSubmenuIndexDfu, power_settings_scene_reboot_submenu_callback, app); diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_shutdown_idle.c b/applications/settings/power_settings_app/scenes/power_settings_scene_shutdown_idle.c new file mode 100644 index 000000000..b6c36a890 --- /dev/null +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_shutdown_idle.c @@ -0,0 +1,67 @@ +#include "../power_settings_app.h" +#include + +#define SHUTDOWN_IDLE_DELAY_COUNT 8 +#define SCENE_EVENT_SELECT_SHUTDOWN_IDLE_DELAY 0 + +const char* const shutdown_idle_delay_text[SHUTDOWN_IDLE_DELAY_COUNT] = + {"OFF", "15min", "30min", "1h", "6h", "12h", "24h", "48h"}; + +const uint32_t shutdown_idle_delay_value[SHUTDOWN_IDLE_DELAY_COUNT] = + {0, 900000, 1800000, 3600000, 21600000, 43200000, 86400000, 172800000}; + +static void power_settings_scene_shutodwn_idle_callback(void* context, uint32_t index) { + PowerSettingsApp* app = context; + view_dispatcher_send_custom_event(app->view_dispatcher, index); +} + +static void power_settings_scene_start_shutdown_idle_delay_changed(VariableItem* item) { + PowerSettingsApp* app = variable_item_get_context(item); + uint8_t index = variable_item_get_current_value_index(item); + + variable_item_set_current_value_text(item, shutdown_idle_delay_text[index]); + app->shutdown_idle_delay_ms = shutdown_idle_delay_value[index]; +} + +void power_settings_scene_shutdown_idle_on_enter(void* context) { + PowerSettingsApp* app = context; + LOAD_POWER_SETTINGS(&app->shutdown_idle_delay_ms); + VariableItemList* variable_item_list = app->variable_item_list; + VariableItem* item; + uint8_t value_index; + + item = variable_item_list_add( + variable_item_list, + "Set Time", + SHUTDOWN_IDLE_DELAY_COUNT, + power_settings_scene_start_shutdown_idle_delay_changed, + app); + + variable_item_list_set_enter_callback( + variable_item_list, power_settings_scene_shutodwn_idle_callback, app); + + value_index = value_index_uint32( + app->shutdown_idle_delay_ms, shutdown_idle_delay_value, SHUTDOWN_IDLE_DELAY_COUNT); + variable_item_set_current_value_index(item, value_index); + variable_item_set_current_value_text(item, shutdown_idle_delay_text[value_index]); + + view_dispatcher_switch_to_view(app->view_dispatcher, PowerSettingsAppViewVariableItemList); +} + +bool power_settings_scene_shutdown_idle_on_event(void* context, SceneManagerEvent event) { + UNUSED(context); + bool consumed = false; + + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == SCENE_EVENT_SELECT_SHUTDOWN_IDLE_DELAY) { + consumed = true; + } + } + return consumed; +} + +void power_settings_scene_shutdown_idle_on_exit(void* context) { + PowerSettingsApp* app = context; + SAVE_POWER_SETTINGS(&app->shutdown_idle_delay_ms); + variable_item_list_reset(app->variable_item_list); +} diff --git a/applications/settings/power_settings_app/scenes/power_settings_scene_start.c b/applications/settings/power_settings_app/scenes/power_settings_scene_start.c index 63f123d89..47c5b85c3 100644 --- a/applications/settings/power_settings_app/scenes/power_settings_scene_start.c +++ b/applications/settings/power_settings_app/scenes/power_settings_scene_start.c @@ -4,6 +4,7 @@ enum PowerSettingsSubmenuIndex { PowerSettingsSubmenuIndexBatteryInfo, PowerSettingsSubmenuIndexReboot, PowerSettingsSubmenuIndexOff, + PowerSettingsSubmenuShutdownIdle }; static void power_settings_scene_start_submenu_callback(void* context, uint32_t index) { @@ -34,6 +35,12 @@ void power_settings_scene_start_on_enter(void* context) { PowerSettingsSubmenuIndexOff, power_settings_scene_start_submenu_callback, app); + submenu_add_item( + submenu, + "Shutdown on Idle", + PowerSettingsSubmenuShutdownIdle, + power_settings_scene_start_submenu_callback, + app); submenu_set_selected_item( submenu, scene_manager_get_scene_state(app->scene_manager, PowerSettingsAppSceneStart)); @@ -51,6 +58,8 @@ bool power_settings_scene_start_on_event(void* context, SceneManagerEvent event) scene_manager_next_scene(app->scene_manager, PowerSettingsAppSceneReboot); } else if(event.event == PowerSettingsSubmenuIndexOff) { scene_manager_next_scene(app->scene_manager, PowerSettingsAppScenePowerOff); + } else if(event.event == PowerSettingsSubmenuShutdownIdle) { + scene_manager_next_scene(app->scene_manager, PowerSettingsAppSceneShutdownIdle); } scene_manager_set_scene_state(app->scene_manager, PowerSettingsAppSceneStart, event.event); consumed = true;