[FL-1019] New main screen and graphics (#389)
* new status bar, lock menu and dolphin activities screen * lock icon indication * main screen animation, basic scene switching * level progression calculations based on icounter value Co-authored-by: rusdacent <rusdacentx0x08@gmail.com> Co-authored-by: あく <alleteam@gmail.com>
							
								
								
									
										6
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @ -20,7 +20,11 @@ jobs: | |||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 0 |           fetch-depth: 0 | ||||||
|           submodules: true |       - name: Checkout submodules | ||||||
|  |         run: git submodule update --init --recursive | ||||||
|  |       - name: Checkout submodules | ||||||
|  |         run: git submodule sync | ||||||
|  | 
 | ||||||
|       - uses: satackey/action-docker-layer-caching@v0.0.11 |       - uses: satackey/action-docker-layer-caching@v0.0.11 | ||||||
|         continue-on-error: true |         continue-on-error: true | ||||||
|         with: |         with: | ||||||
|  | |||||||
| @ -1,4 +1,27 @@ | |||||||
| #include "dolphin_i.h" | #include "dolphin_i.h" | ||||||
|  | #include <stdlib.h> | ||||||
|  | 
 | ||||||
|  | // temporary main screen animation managment
 | ||||||
|  | void dolphin_scene_handler_set_scene(Dolphin* dolphin, IconName icon) { | ||||||
|  |     with_view_model( | ||||||
|  |         dolphin->idle_view_main, (DolphinViewMainModel * model) { | ||||||
|  |             model->animation = assets_icons_get(icon); | ||||||
|  |             icon_start_animation(model->animation); | ||||||
|  |             return true; | ||||||
|  |         }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void dolphin_scene_handler_switch_scene(Dolphin* dolphin) { | ||||||
|  |     with_view_model( | ||||||
|  |         dolphin->idle_view_main, (DolphinViewMainModel * model) { | ||||||
|  |             if(icon_is_last_frame(model->animation)) { | ||||||
|  |                 model->animation = assets_icons_get(idle_scenes[model->scene_num]); | ||||||
|  |                 icon_start_animation(model->animation); | ||||||
|  |                 model->scene_num = random() % sizeof(idle_scenes); | ||||||
|  |             } | ||||||
|  |             return true; | ||||||
|  |         }); | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| bool dolphin_view_first_start_input(InputEvent* event, void* context) { | bool dolphin_view_first_start_input(InputEvent* event, void* context) { | ||||||
|     furi_assert(event); |     furi_assert(event); | ||||||
| @ -34,15 +57,38 @@ bool dolphin_view_idle_main_input(InputEvent* event, void* context) { | |||||||
|     Dolphin* dolphin = context; |     Dolphin* dolphin = context; | ||||||
| 
 | 
 | ||||||
|     if(event->type == InputTypeShort) { |     if(event->type == InputTypeShort) { | ||||||
|         if(event->key == InputKeyOk) { |         if(!dolphin->locked) { | ||||||
|             with_value_mutex( |             if(event->key == InputKeyOk) { | ||||||
|                 dolphin->menu_vm, (Menu * menu) { menu_ok(menu); }); |                 with_value_mutex( | ||||||
|         } else if(event->key == InputKeyUp) { |                     dolphin->menu_vm, (Menu * menu) { menu_ok(menu); }); | ||||||
|             view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleUp); |             } else if(event->key == InputKeyUp) { | ||||||
|         } else if(event->key == InputKeyDown) { |                 view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewLockMenu); | ||||||
|             view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleDown); |             } else if(event->key == InputKeyLeft) { | ||||||
|  |                 view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleUp); | ||||||
|  |             } else if(event->key == InputKeyRight) { | ||||||
|  |                 view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMeta); | ||||||
|  |             } else if(event->key == InputKeyDown) { | ||||||
|  |                 view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleDown); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             if(event->key == InputKeyBack) { | ||||||
|  |                 view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMain); | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             if(event->key == InputKeyBack) { | ||||||
|  |                 dolphin->lock_count++; | ||||||
|  |                 if(dolphin->lock_count == 3) { | ||||||
|  |                     dolphin->locked = false; | ||||||
|  |                     dolphin->lock_count = 0; | ||||||
|  |                     view_dispatcher_switch_to_view( | ||||||
|  |                         dolphin->idle_view_dispatcher, DolphinViewIdleMain); | ||||||
|  |                     view_port_enabled_set(dolphin->lock_viewport, false); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|  |         dolphin_scene_handler_switch_scene(dolphin); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|     // All events consumed
 |     // All events consumed
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| @ -67,6 +113,182 @@ bool dolphin_view_idle_up_input(InputEvent* event, void* context) { | |||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void lock_menu_callback(void* context, uint8_t index) { | ||||||
|  |     Dolphin* dolphin = context; | ||||||
|  |     switch(index) { | ||||||
|  |     case 0: | ||||||
|  |         dolphin->locked = true; | ||||||
|  |         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMain); | ||||||
|  |         view_port_enabled_set(dolphin->lock_viewport, true); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |     default: | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void meta_menu_callback(void* context, uint8_t index) { | ||||||
|  |     Dolphin* dolphin = context; | ||||||
|  |     switch(index) { | ||||||
|  |     case 0: | ||||||
|  |         view_port_enabled_set(dolphin->passport, true); | ||||||
|  |         break; | ||||||
|  | 
 | ||||||
|  |     default: | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void lock_icon_callback(Canvas* canvas, void* context) { | ||||||
|  |     assert(context); | ||||||
|  |     Dolphin* dolphin = context; | ||||||
|  |     canvas_draw_icon(canvas, 0, 0, dolphin->lock_icon); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void draw_passport_callback(Canvas* canvas, void* context) { | ||||||
|  |     assert(context); | ||||||
|  |     Dolphin* dolphin = context; | ||||||
|  | 
 | ||||||
|  |     char level[20]; | ||||||
|  |     uint32_t current_level = dolphin_state_get_level(dolphin->state); | ||||||
|  |     uint32_t prev_cap = dolphin_state_xp_to_levelup(dolphin->state, current_level - 1, false); | ||||||
|  |     uint32_t exp = (dolphin_state_xp_to_levelup(dolphin->state, current_level, true) * 63) / | ||||||
|  |                    (dolphin_state_xp_to_levelup(dolphin->state, current_level, false) - prev_cap); | ||||||
|  | 
 | ||||||
|  |     canvas_clear(canvas); | ||||||
|  | 
 | ||||||
|  |     // multipass
 | ||||||
|  |     canvas_draw_icon_name(canvas, 0, 0, I_PassportLeft_6x47); | ||||||
|  |     canvas_draw_icon_name(canvas, 0, 47, I_PassportBottom_128x17); | ||||||
|  |     canvas_draw_line(canvas, 6, 0, 125, 0); | ||||||
|  |     canvas_draw_line(canvas, 127, 2, 127, 47); | ||||||
|  |     canvas_draw_dot(canvas, 126, 1); | ||||||
|  | 
 | ||||||
|  |     //portrait frame
 | ||||||
|  |     canvas_draw_line(canvas, 9, 6, 9, 53); | ||||||
|  |     canvas_draw_line(canvas, 10, 5, 52, 5); | ||||||
|  |     canvas_draw_line(canvas, 55, 8, 55, 53); | ||||||
|  |     canvas_draw_line(canvas, 10, 54, 54, 54); | ||||||
|  |     canvas_draw_line(canvas, 53, 5, 55, 7); | ||||||
|  | 
 | ||||||
|  |     // portrait
 | ||||||
|  |     canvas_draw_icon_name(canvas, 14, 11, I_DolphinOkay_41x43); | ||||||
|  |     canvas_draw_line(canvas, 59, 18, 124, 18); | ||||||
|  |     canvas_draw_line(canvas, 59, 31, 124, 31); | ||||||
|  |     canvas_draw_line(canvas, 59, 44, 124, 44); | ||||||
|  | 
 | ||||||
|  |     canvas_draw_str(canvas, 59, 15, api_hal_version_get_name_ptr()); | ||||||
|  |     canvas_draw_str(canvas, 59, 28, "Mood: OK"); | ||||||
|  | 
 | ||||||
|  |     snprintf(level, 20, "Level: %ld", current_level); | ||||||
|  | 
 | ||||||
|  |     canvas_draw_str(canvas, 59, 41, level); | ||||||
|  |     canvas_set_color(canvas, ColorWhite); | ||||||
|  |     canvas_draw_box(canvas, 123 - exp, 48, exp + 1, 6); | ||||||
|  |     canvas_set_color(canvas, ColorBlack); | ||||||
|  |     canvas_draw_line(canvas, 123 - exp, 48, 123 - exp, 54); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void passport_input_callback(InputEvent* event, void* context) { | ||||||
|  |     Dolphin* dolphin = context; | ||||||
|  |     if(event->type == InputTypeShort) { | ||||||
|  |         if(event->key == InputKeyBack) { | ||||||
|  |             view_port_enabled_set(dolphin->passport, false); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool dolphin_view_lockmenu_input(InputEvent* event, void* context) { | ||||||
|  |     furi_assert(event); | ||||||
|  |     furi_assert(context); | ||||||
|  |     Dolphin* dolphin = context; | ||||||
|  | 
 | ||||||
|  |     if(event->type != InputTypeShort) return false; | ||||||
|  | 
 | ||||||
|  |     if(event->key == InputKeyUp) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->view_lockmenu, (DolphinViewMenuModel * model) { | ||||||
|  |                 if(model->idx <= 0) | ||||||
|  |                     model->idx = 0; | ||||||
|  |                 else | ||||||
|  |                     --model->idx; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |     } else if(event->key == InputKeyDown) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->view_lockmenu, (DolphinViewMenuModel * model) { | ||||||
|  |                 if(model->idx >= 2) | ||||||
|  |                     model->idx = 2; | ||||||
|  |                 else | ||||||
|  |                     ++model->idx; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |     } else if(event->key == InputKeyOk) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->view_lockmenu, (DolphinViewMenuModel * model) { | ||||||
|  |                 lock_menu_callback(context, model->idx); | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |     } else if(event->key == InputKeyBack) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->view_lockmenu, (DolphinViewMenuModel * model) { | ||||||
|  |                 model->idx = 0; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMain); | ||||||
|  | 
 | ||||||
|  |         if(random() % 100 > 50) | ||||||
|  |             dolphin_scene_handler_set_scene(dolphin, idle_scenes[random() % sizeof(idle_scenes)]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool dolphin_view_idle_meta_input(InputEvent* event, void* context) { | ||||||
|  |     furi_assert(event); | ||||||
|  |     furi_assert(context); | ||||||
|  |     Dolphin* dolphin = context; | ||||||
|  | 
 | ||||||
|  |     if(event->type != InputTypeShort) return false; | ||||||
|  | 
 | ||||||
|  |     if(event->key == InputKeyLeft) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->idle_view_meta, (DolphinViewMenuModel * model) { | ||||||
|  |                 if(model->idx <= 0) | ||||||
|  |                     model->idx = 0; | ||||||
|  |                 else | ||||||
|  |                     --model->idx; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |     } else if(event->key == InputKeyRight) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->idle_view_meta, (DolphinViewMenuModel * model) { | ||||||
|  |                 if(model->idx >= 2) | ||||||
|  |                     model->idx = 2; | ||||||
|  |                 else | ||||||
|  |                     ++model->idx; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |     } else if(event->key == InputKeyOk) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->idle_view_meta, (DolphinViewMenuModel * model) { | ||||||
|  |                 meta_menu_callback(context, model->idx); | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |     } else if(event->key == InputKeyBack) { | ||||||
|  |         with_view_model( | ||||||
|  |             dolphin->idle_view_meta, (DolphinViewMenuModel * model) { | ||||||
|  |                 model->idx = 0; | ||||||
|  |                 return true; | ||||||
|  |             }); | ||||||
|  |         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMain); | ||||||
|  |         if(random() % 100 > 50) | ||||||
|  |             dolphin_scene_handler_set_scene(dolphin, idle_scenes[random() % sizeof(idle_scenes)]); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     return true; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| Dolphin* dolphin_alloc() { | Dolphin* dolphin_alloc() { | ||||||
|     Dolphin* dolphin = furi_alloc(sizeof(Dolphin)); |     Dolphin* dolphin = furi_alloc(sizeof(Dolphin)); | ||||||
|     // Message queue
 |     // Message queue
 | ||||||
| @ -90,6 +312,9 @@ Dolphin* dolphin_alloc() { | |||||||
|     // Main Idle View
 |     // Main Idle View
 | ||||||
|     dolphin->idle_view_main = view_alloc(); |     dolphin->idle_view_main = view_alloc(); | ||||||
|     view_set_context(dolphin->idle_view_main, dolphin); |     view_set_context(dolphin->idle_view_main, dolphin); | ||||||
|  |     view_allocate_model( | ||||||
|  |         dolphin->idle_view_main, ViewModelTypeLockFree, sizeof(DolphinViewIdleUpModel)); | ||||||
|  | 
 | ||||||
|     view_set_draw_callback(dolphin->idle_view_main, dolphin_view_idle_main_draw); |     view_set_draw_callback(dolphin->idle_view_main, dolphin_view_idle_main_draw); | ||||||
|     view_set_input_callback(dolphin->idle_view_main, dolphin_view_idle_main_input); |     view_set_input_callback(dolphin->idle_view_main, dolphin_view_idle_main_input); | ||||||
|     view_dispatcher_add_view( |     view_dispatcher_add_view( | ||||||
| @ -97,13 +322,34 @@ Dolphin* dolphin_alloc() { | |||||||
|     // Stats Idle View
 |     // Stats Idle View
 | ||||||
|     dolphin->idle_view_up = view_alloc(); |     dolphin->idle_view_up = view_alloc(); | ||||||
|     view_set_context(dolphin->idle_view_up, dolphin); |     view_set_context(dolphin->idle_view_up, dolphin); | ||||||
|  | 
 | ||||||
|     view_allocate_model( |     view_allocate_model( | ||||||
|         dolphin->idle_view_up, ViewModelTypeLockFree, sizeof(DolphinViewIdleUpModel)); |         dolphin->idle_view_up, ViewModelTypeLockFree, sizeof(DolphinViewMainModel)); | ||||||
|     view_set_draw_callback(dolphin->idle_view_up, dolphin_view_idle_up_draw); |     view_set_draw_callback(dolphin->idle_view_up, dolphin_view_idle_up_draw); | ||||||
|     view_set_input_callback(dolphin->idle_view_up, dolphin_view_idle_up_input); |     view_set_input_callback(dolphin->idle_view_up, dolphin_view_idle_up_input); | ||||||
|     view_set_previous_callback(dolphin->idle_view_up, dolphin_view_idle_back); |     view_set_previous_callback(dolphin->idle_view_up, dolphin_view_idle_back); | ||||||
|     view_dispatcher_add_view( |     view_dispatcher_add_view( | ||||||
|         dolphin->idle_view_dispatcher, DolphinViewIdleUp, dolphin->idle_view_up); |         dolphin->idle_view_dispatcher, DolphinViewIdleUp, dolphin->idle_view_up); | ||||||
|  |     // Lock Menu View
 | ||||||
|  |     dolphin->view_lockmenu = view_alloc(); | ||||||
|  |     view_set_context(dolphin->view_lockmenu, dolphin); | ||||||
|  |     view_allocate_model( | ||||||
|  |         dolphin->view_lockmenu, ViewModelTypeLockFree, sizeof(DolphinViewMenuModel)); | ||||||
|  |     view_set_draw_callback(dolphin->view_lockmenu, dolphin_view_lockmenu_draw); | ||||||
|  |     view_set_input_callback(dolphin->view_lockmenu, dolphin_view_lockmenu_input); | ||||||
|  |     view_set_previous_callback(dolphin->view_lockmenu, dolphin_view_idle_back); | ||||||
|  |     view_dispatcher_add_view( | ||||||
|  |         dolphin->idle_view_dispatcher, DolphinViewLockMenu, dolphin->view_lockmenu); | ||||||
|  |     // Meta View
 | ||||||
|  |     dolphin->idle_view_meta = view_alloc(); | ||||||
|  |     view_set_context(dolphin->idle_view_meta, dolphin); | ||||||
|  |     view_allocate_model( | ||||||
|  |         dolphin->idle_view_meta, ViewModelTypeLockFree, sizeof(DolphinViewMenuModel)); | ||||||
|  |     view_set_draw_callback(dolphin->idle_view_meta, dolphin_view_idle_meta_draw); | ||||||
|  |     view_set_input_callback(dolphin->idle_view_meta, dolphin_view_idle_meta_input); | ||||||
|  |     view_set_previous_callback(dolphin->idle_view_meta, dolphin_view_idle_back); | ||||||
|  |     view_dispatcher_add_view( | ||||||
|  |         dolphin->idle_view_dispatcher, DolphinViewIdleMeta, dolphin->idle_view_meta); | ||||||
|     // Down Idle View
 |     // Down Idle View
 | ||||||
|     dolphin->idle_view_down = view_alloc(); |     dolphin->idle_view_down = view_alloc(); | ||||||
|     view_set_draw_callback(dolphin->idle_view_down, dolphin_view_idle_down_draw); |     view_set_draw_callback(dolphin->idle_view_down, dolphin_view_idle_down_draw); | ||||||
| @ -117,6 +363,22 @@ Dolphin* dolphin_alloc() { | |||||||
|     view_dispatcher_add_view( |     view_dispatcher_add_view( | ||||||
|         dolphin->idle_view_dispatcher, DolphinViewHwMismatch, dolphin->view_hw_mismatch); |         dolphin->idle_view_dispatcher, DolphinViewHwMismatch, dolphin->view_hw_mismatch); | ||||||
| 
 | 
 | ||||||
|  |     // Lock icon
 | ||||||
|  |     dolphin->lock_icon = assets_icons_get(I_Lock_8x8); | ||||||
|  |     dolphin->lock_viewport = view_port_alloc(); | ||||||
|  |     view_port_set_width(dolphin->lock_viewport, icon_get_width(dolphin->lock_icon)); | ||||||
|  |     view_port_draw_callback_set(dolphin->lock_viewport, lock_icon_callback, dolphin); | ||||||
|  |     view_port_enabled_set(dolphin->lock_viewport, false); | ||||||
|  | 
 | ||||||
|  |     // Passport
 | ||||||
|  |     dolphin->passport = view_port_alloc(); | ||||||
|  |     view_port_draw_callback_set(dolphin->passport, draw_passport_callback, dolphin); | ||||||
|  |     view_port_input_callback_set(dolphin->passport, passport_input_callback, dolphin); | ||||||
|  |     view_port_enabled_set(dolphin->passport, false); | ||||||
|  | 
 | ||||||
|  |     // Main screen animation
 | ||||||
|  |     dolphin_scene_handler_set_scene(dolphin, idle_scenes[random() % sizeof(idle_scenes)]); | ||||||
|  | 
 | ||||||
|     return dolphin; |     return dolphin; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -139,7 +401,12 @@ int32_t dolphin_task() { | |||||||
|     Dolphin* dolphin = dolphin_alloc(); |     Dolphin* dolphin = dolphin_alloc(); | ||||||
| 
 | 
 | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open("gui"); | ||||||
|  | 
 | ||||||
|     view_dispatcher_attach_to_gui(dolphin->idle_view_dispatcher, gui, ViewDispatcherTypeWindow); |     view_dispatcher_attach_to_gui(dolphin->idle_view_dispatcher, gui, ViewDispatcherTypeWindow); | ||||||
|  |     gui_add_view_port(gui, dolphin->lock_viewport, GuiLayerStatusBarLeft); | ||||||
|  | 
 | ||||||
|  |     gui_add_view_port(gui, dolphin->passport, GuiLayerFullscreen); | ||||||
|  | 
 | ||||||
|     if(dolphin_state_load(dolphin->state)) { |     if(dolphin_state_load(dolphin->state)) { | ||||||
|         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMain); |         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewIdleMain); | ||||||
|     } else { |     } else { | ||||||
| @ -157,7 +424,6 @@ int32_t dolphin_task() { | |||||||
|     if(!api_hal_version_do_i_belong_here()) { |     if(!api_hal_version_do_i_belong_here()) { | ||||||
|         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewHwMismatch); |         view_dispatcher_switch_to_view(dolphin->idle_view_dispatcher, DolphinViewHwMismatch); | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     DolphinEvent event; |     DolphinEvent event; | ||||||
|     while(1) { |     while(1) { | ||||||
|         furi_check(osMessageQueueGet(dolphin->event_queue, &event, NULL, osWaitForever) == osOK); |         furi_check(osMessageQueueGet(dolphin->event_queue, &event, NULL, osWaitForever) == osOK); | ||||||
| @ -173,6 +439,5 @@ int32_t dolphin_task() { | |||||||
|             dolphin_state_save(dolphin->state); |             dolphin_state_save(dolphin->state); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 |  | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -39,9 +39,20 @@ struct Dolphin { | |||||||
|     View* idle_view_main; |     View* idle_view_main; | ||||||
|     View* idle_view_up; |     View* idle_view_up; | ||||||
|     View* idle_view_down; |     View* idle_view_down; | ||||||
|  |     View* idle_view_meta; | ||||||
|     View* view_hw_mismatch; |     View* view_hw_mismatch; | ||||||
|  |     View* view_lockmenu; | ||||||
|  |     ViewPort* passport; | ||||||
|  |     ViewPort* lock_viewport; | ||||||
|  |     Icon* lock_icon; | ||||||
|  | 
 | ||||||
|  |     bool locked; | ||||||
|  |     uint8_t lock_count; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | // Temporary
 | ||||||
|  | const IconName idle_scenes[] = {A_Wink_128x64, A_WatchingTV_128x64}; | ||||||
|  | 
 | ||||||
| Dolphin* dolphin_alloc(); | Dolphin* dolphin_alloc(); | ||||||
| 
 | 
 | ||||||
| /* Save Dolphin state (write to permanent memory)
 | /* Save Dolphin state (write to permanent memory)
 | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #include "dolphin_state.h" | #include "dolphin_state.h" | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
|  | #include <math.h> | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint8_t magic; |     uint8_t magic; | ||||||
| @ -17,6 +18,8 @@ typedef struct { | |||||||
| #define DOLPHIN_DATA_HEADER_MAGIC 0xD0 | #define DOLPHIN_DATA_HEADER_MAGIC 0xD0 | ||||||
| #define DOLPHIN_DATA_HEADER_VERSION 0x01 | #define DOLPHIN_DATA_HEADER_VERSION 0x01 | ||||||
| 
 | 
 | ||||||
|  | #define DOLPHIN_LVL_THRESHOLD 20.0f | ||||||
|  | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     uint32_t limit_ibutton; |     uint32_t limit_ibutton; | ||||||
|     uint32_t limit_nfc; |     uint32_t limit_nfc; | ||||||
| @ -119,3 +122,14 @@ uint32_t dolphin_state_get_icounter(DolphinState* dolphin_state) { | |||||||
| uint32_t dolphin_state_get_butthurt(DolphinState* dolphin_state) { | uint32_t dolphin_state_get_butthurt(DolphinState* dolphin_state) { | ||||||
|     return dolphin_state->data.butthurt; |     return dolphin_state->data.butthurt; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | uint32_t dolphin_state_get_level(DolphinState* dolphin_state) { | ||||||
|  |     return 0.5f + | ||||||
|  |            sqrtf(1.0f + 8.0f * ((float)dolphin_state->data.icounter / DOLPHIN_LVL_THRESHOLD)) / | ||||||
|  |                2.0f; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | uint32_t dolphin_state_xp_to_levelup(DolphinState* dolphin_state, uint32_t level, bool remaining) { | ||||||
|  |     return (DOLPHIN_LVL_THRESHOLD * level * (level + 1) / 2) - | ||||||
|  |            (remaining ? dolphin_state->data.icounter : 0); | ||||||
|  | } | ||||||
| @ -21,3 +21,7 @@ void dolphin_state_on_deed(DolphinState* dolphin_state, DolphinDeed deed); | |||||||
| uint32_t dolphin_state_get_icounter(DolphinState* dolphin_state); | uint32_t dolphin_state_get_icounter(DolphinState* dolphin_state); | ||||||
| 
 | 
 | ||||||
| uint32_t dolphin_state_get_butthurt(DolphinState* dolphin_state); | uint32_t dolphin_state_get_butthurt(DolphinState* dolphin_state); | ||||||
|  | 
 | ||||||
|  | uint32_t dolphin_state_get_level(DolphinState* dolphin_state); | ||||||
|  | 
 | ||||||
|  | uint32_t dolphin_state_xp_to_levelup(DolphinState* dolphin_state, uint32_t level, bool remaining); | ||||||
| @ -2,9 +2,11 @@ | |||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
| #include <gui/gui.h> | #include <gui/gui.h> | ||||||
| #include <gui/elements.h> | #include <gui/elements.h> | ||||||
| 
 |  | ||||||
| #include <api-hal.h> | #include <api-hal.h> | ||||||
| 
 | 
 | ||||||
|  | static char* Lockmenu_Items[3] = {"Lock", "Set PIN", "DUMB mode"}; | ||||||
|  | static char* Meta_Items[3] = {"Passport", "Games", "???"}; | ||||||
|  | 
 | ||||||
| void dolphin_view_first_start_draw(Canvas* canvas, void* model) { | void dolphin_view_first_start_draw(Canvas* canvas, void* model) { | ||||||
|     DolphinViewFirstStartModel* m = model; |     DolphinViewFirstStartModel* m = model; | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
| @ -57,40 +59,73 @@ void dolphin_view_first_start_draw(Canvas* canvas, void* model) { | |||||||
| 
 | 
 | ||||||
| void dolphin_view_idle_main_draw(Canvas* canvas, void* model) { | void dolphin_view_idle_main_draw(Canvas* canvas, void* model) { | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_color(canvas, ColorBlack); |     DolphinViewMainModel* m = model; | ||||||
|     canvas_draw_icon_name( |     if(m->animation) canvas_draw_icon(canvas, 0, 0, m->animation); | ||||||
|         canvas, canvas_width(canvas) - 80, canvas_height(canvas) - 60 + 6, I_Flipper_young_80x60); |  | ||||||
|     canvas_set_font(canvas, FontSecondary); |  | ||||||
|     canvas_draw_str(canvas, 2, 10, "/\\: Stats"); |  | ||||||
|     canvas_draw_str(canvas, 5, 32, "OK: Menu"); |  | ||||||
|     canvas_draw_str(canvas, 2, 52, "\\/: Version"); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void dolphin_view_idle_up_draw(Canvas* canvas, void* model) { | void dolphin_view_idle_up_draw(Canvas* canvas, void* model) { | ||||||
|     DolphinViewIdleUpModel* m = model; |     DolphinViewIdleUpModel* m = model; | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|  | 
 | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
|     canvas_set_font(canvas, FontPrimary); |     canvas_set_font(canvas, FontPrimary); | ||||||
|     canvas_draw_str(canvas, 2, 10, "Dolphin stats:"); |     canvas_draw_str(canvas, 2, 15, "Dolphin stats:"); | ||||||
| 
 | 
 | ||||||
|     char buffer[64]; |     char buffer[64]; | ||||||
|     canvas_set_font(canvas, FontSecondary); |     canvas_set_font(canvas, FontSecondary); | ||||||
|     snprintf(buffer, 64, "Icounter: %ld", m->icounter); |     snprintf(buffer, 64, "Icounter: %ld", m->icounter); | ||||||
|     canvas_draw_str(canvas, 5, 22, buffer); |     canvas_draw_str(canvas, 5, 30, buffer); | ||||||
|     snprintf(buffer, 64, "Butthurt: %ld", m->butthurt); |     snprintf(buffer, 64, "Butthurt: %ld", m->butthurt); | ||||||
|     canvas_draw_str(canvas, 5, 32, buffer); |     canvas_draw_str(canvas, 5, 40, buffer); | ||||||
|     canvas_draw_str(canvas, 5, 40, "< > change icounter"); |     canvas_draw_str(canvas, 0, 53, "[< >] icounter value   [ok] save"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void dolphin_view_lockmenu_draw(Canvas* canvas, void* model) { | ||||||
|  |     DolphinViewMenuModel* m = model; | ||||||
|  |     canvas_clear(canvas); | ||||||
|  |     canvas_set_color(canvas, ColorBlack); | ||||||
|  |     canvas_draw_icon_name(canvas, 5, 0, I_DoorLeft_8x56); | ||||||
|  |     canvas_draw_icon_name(canvas, 115, 0, I_DoorRight_8x56); | ||||||
|  |     canvas_set_font(canvas, FontSecondary); | ||||||
|  |     for(uint8_t i = 0; i < 3; ++i) { | ||||||
|  |         canvas_draw_str_aligned( | ||||||
|  |             canvas, 64, 13 + (i * 17), AlignCenter, AlignCenter, Lockmenu_Items[i]); | ||||||
|  |         if(m->idx == i) elements_frame(canvas, 15, 5 + (i * 17), 98, 15); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void dolphin_view_idle_meta_draw(Canvas* canvas, void* model) { | ||||||
|  |     DolphinViewMenuModel* m = model; | ||||||
|  |     canvas_clear(canvas); | ||||||
|  |     canvas_set_color(canvas, ColorBlack); | ||||||
|  |     canvas_set_font(canvas, FontSecondary); | ||||||
|  | 
 | ||||||
|  |     canvas_draw_icon_name(canvas, 20, 23, I_BigProfile_24x24); | ||||||
|  |     canvas_draw_icon_name(canvas, 55, 23, I_BigGames_24x24); | ||||||
|  |     canvas_draw_icon_name(canvas, 90, 23, I_BigBurger_24x24); | ||||||
|  | 
 | ||||||
|  |     canvas_draw_str_aligned(canvas, 66, 12, AlignCenter, AlignCenter, Meta_Items[m->idx]); | ||||||
|  | 
 | ||||||
|  |     canvas_draw_frame(canvas, 17 + (35 * m->idx), 20, 30, 30); | ||||||
|  |     canvas_set_color(canvas, ColorWhite); | ||||||
|  | 
 | ||||||
|  |     canvas_draw_dot(canvas, 17 + (35 * m->idx), 20); | ||||||
|  |     canvas_draw_dot(canvas, 17 + (35 * m->idx), 49); | ||||||
|  |     canvas_draw_dot(canvas, 46 + (35 * m->idx), 20); | ||||||
|  |     canvas_draw_dot(canvas, 46 + (35 * m->idx), 49); | ||||||
|  | 
 | ||||||
|  |     canvas_set_color(canvas, ColorBlack); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void dolphin_view_idle_down_draw(Canvas* canvas, void* model) { | void dolphin_view_idle_down_draw(Canvas* canvas, void* model) { | ||||||
|     canvas_clear(canvas); |     canvas_clear(canvas); | ||||||
|     canvas_set_color(canvas, ColorBlack); |     canvas_set_color(canvas, ColorBlack); | ||||||
|     canvas_set_font(canvas, FontPrimary); |     canvas_set_font(canvas, FontPrimary); | ||||||
|     canvas_draw_str(canvas, 2, 10, "Version info:"); |     canvas_draw_str(canvas, 2, 15, "Version info:"); | ||||||
|     canvas_set_font(canvas, FontSecondary); |     canvas_set_font(canvas, FontSecondary); | ||||||
|     canvas_draw_str(canvas, 5, 22, TARGET " " BUILD_DATE); |     canvas_draw_str(canvas, 5, 25, TARGET " " BUILD_DATE); | ||||||
|     canvas_draw_str(canvas, 5, 32, GIT_BRANCH); |     canvas_draw_str(canvas, 5, 35, GIT_BRANCH); | ||||||
|     canvas_draw_str(canvas, 5, 42, GIT_BRANCH_NUM " " GIT_COMMIT); |     canvas_draw_str(canvas, 5, 45, GIT_BRANCH_NUM " " GIT_COMMIT); | ||||||
| 
 | 
 | ||||||
|     char buffer[64]; |     char buffer[64]; | ||||||
|     snprintf( |     snprintf( | ||||||
| @ -101,7 +136,7 @@ void dolphin_view_idle_down_draw(Canvas* canvas, void* model) { | |||||||
|         api_hal_version_get_hw_target(), |         api_hal_version_get_hw_target(), | ||||||
|         api_hal_version_get_hw_body(), |         api_hal_version_get_hw_body(), | ||||||
|         api_hal_version_get_hw_connect()); |         api_hal_version_get_hw_connect()); | ||||||
|     canvas_draw_str(canvas, 5, 52, buffer); |     canvas_draw_str(canvas, 5, 55, buffer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void dolphin_view_hw_mismatch_draw(Canvas* canvas, void* model) { | void dolphin_view_hw_mismatch_draw(Canvas* canvas, void* model) { | ||||||
|  | |||||||
| @ -13,6 +13,8 @@ typedef enum { | |||||||
|     DolphinViewIdleUp, |     DolphinViewIdleUp, | ||||||
|     DolphinViewIdleDown, |     DolphinViewIdleDown, | ||||||
|     DolphinViewHwMismatch, |     DolphinViewHwMismatch, | ||||||
|  |     DolphinViewLockMenu, | ||||||
|  |     DolphinViewIdleMeta, | ||||||
| } DolphinViewIdle; | } DolphinViewIdle; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| @ -27,12 +29,27 @@ typedef struct { | |||||||
|     uint32_t butthurt; |     uint32_t butthurt; | ||||||
| } DolphinViewIdleUpModel; | } DolphinViewIdleUpModel; | ||||||
| 
 | 
 | ||||||
|  | typedef struct { | ||||||
|  |     uint8_t idx; | ||||||
|  | } DolphinViewMenuModel; | ||||||
|  | 
 | ||||||
|  | typedef struct { | ||||||
|  |     Icon* animation; | ||||||
|  |     uint8_t scene_num; | ||||||
|  | 
 | ||||||
|  | } DolphinViewMainModel; | ||||||
|  | 
 | ||||||
| void dolphin_view_idle_main_draw(Canvas* canvas, void* model); | void dolphin_view_idle_main_draw(Canvas* canvas, void* model); | ||||||
| bool dolphin_view_idle_main_input(InputEvent* event, void* context); | bool dolphin_view_idle_main_input(InputEvent* event, void* context); | ||||||
| 
 | 
 | ||||||
| void dolphin_view_idle_up_draw(Canvas* canvas, void* model); | void dolphin_view_idle_up_draw(Canvas* canvas, void* model); | ||||||
|  | 
 | ||||||
|  | void dolphin_view_lockmenu_draw(Canvas* canvas, void* model); | ||||||
|  | 
 | ||||||
| void dolphin_view_idle_down_draw(Canvas* canvas, void* model); | void dolphin_view_idle_down_draw(Canvas* canvas, void* model); | ||||||
| 
 | 
 | ||||||
|  | void dolphin_view_idle_meta_draw(Canvas* canvas, void* model); | ||||||
|  | 
 | ||||||
| void dolphin_view_hw_mismatch_draw(Canvas* canvas, void* model); | void dolphin_view_hw_mismatch_draw(Canvas* canvas, void* model); | ||||||
| 
 | 
 | ||||||
| uint32_t dolphin_view_idle_back(void* context); | uint32_t dolphin_view_idle_back(void* context); | ||||||
|  | |||||||
| @ -46,8 +46,12 @@ void gui_redraw_status_bar(Gui* gui) { | |||||||
|     uint8_t x_used = 0; |     uint8_t x_used = 0; | ||||||
|     uint8_t width; |     uint8_t width; | ||||||
|     ViewPort* view_port; |     ViewPort* view_port; | ||||||
|  |     canvas_frame_set( | ||||||
|  |         gui->canvas, GUI_STATUS_BAR_X, GUI_STATUS_BAR_Y, GUI_DISPLAY_WIDTH, GUI_STATUS_BAR_HEIGHT); | ||||||
|  |     canvas_draw_icon_name(gui->canvas, 0, 0, I_Background_128x11); | ||||||
|  | 
 | ||||||
|     // Right side
 |     // Right side
 | ||||||
|     x = GUI_DISPLAY_WIDTH + 2; |     x = GUI_DISPLAY_WIDTH; | ||||||
|     ViewPortArray_it(it, gui->layers[GuiLayerStatusBarRight]); |     ViewPortArray_it(it, gui->layers[GuiLayerStatusBarRight]); | ||||||
|     while(!ViewPortArray_end_p(it) && x_used < GUI_STATUS_BAR_WIDTH) { |     while(!ViewPortArray_end_p(it) && x_used < GUI_STATUS_BAR_WIDTH) { | ||||||
|         // Render view_port;
 |         // Render view_port;
 | ||||||
| @ -57,7 +61,28 @@ void gui_redraw_status_bar(Gui* gui) { | |||||||
|             if(!width) width = 8; |             if(!width) width = 8; | ||||||
|             x_used += width; |             x_used += width; | ||||||
|             x -= (width + 2); |             x -= (width + 2); | ||||||
|             canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); |             canvas_frame_set(gui->canvas, x - 3, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); | ||||||
|  | 
 | ||||||
|  |             canvas_set_color(gui->canvas, ColorWhite); | ||||||
|  |             canvas_draw_box(gui->canvas, 1, 1, width + 3, 11); | ||||||
|  | 
 | ||||||
|  |             canvas_set_color(gui->canvas, ColorBlack); | ||||||
|  | 
 | ||||||
|  |             canvas_draw_box(gui->canvas, 1, 0, 1, 12); | ||||||
|  |             canvas_draw_box(gui->canvas, 0, 1, 1, 11); | ||||||
|  | 
 | ||||||
|  |             canvas_draw_box(gui->canvas, 1, 11, width + 4, 2); | ||||||
|  |             canvas_draw_box(gui->canvas, 1, 0, width + 4, 1); | ||||||
|  |             canvas_draw_box(gui->canvas, width + 4, 1, 1, 11); | ||||||
|  | 
 | ||||||
|  |             canvas_set_color(gui->canvas, ColorWhite); | ||||||
|  |             canvas_draw_dot(gui->canvas, width + 4, 0); | ||||||
|  |             canvas_draw_dot(gui->canvas, width + 4, 12); | ||||||
|  | 
 | ||||||
|  |             canvas_set_color(gui->canvas, ColorBlack); | ||||||
|  | 
 | ||||||
|  |             canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_HEIGHT); | ||||||
|  | 
 | ||||||
|             view_port_draw(view_port, gui->canvas); |             view_port_draw(view_port, gui->canvas); | ||||||
|         } |         } | ||||||
|         ViewPortArray_next(it); |         ViewPortArray_next(it); | ||||||
| @ -73,7 +98,31 @@ void gui_redraw_status_bar(Gui* gui) { | |||||||
|             if(!width) width = 8; |             if(!width) width = 8; | ||||||
|             x_used += width; |             x_used += width; | ||||||
|             canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); |             canvas_frame_set(gui->canvas, x, GUI_STATUS_BAR_Y, width, GUI_STATUS_BAR_HEIGHT); | ||||||
|  | 
 | ||||||
|  |             canvas_set_color(gui->canvas, ColorWhite); | ||||||
|  |             canvas_draw_box(gui->canvas, 1, 1, width + 3, 11); | ||||||
|  | 
 | ||||||
|  |             canvas_set_color(gui->canvas, ColorBlack); | ||||||
|  | 
 | ||||||
|  |             if(x == 0) { // Frame start
 | ||||||
|  |                 canvas_draw_box(gui->canvas, 1, 0, 1, 12); | ||||||
|  |                 canvas_draw_box(gui->canvas, 0, 1, 1, 11); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             canvas_draw_box(gui->canvas, 1, 11, width + 4, 2); | ||||||
|  |             canvas_draw_box(gui->canvas, 1, 0, width + 4, 1); | ||||||
|  |             canvas_draw_box(gui->canvas, width + 4, 0, 1, 12); | ||||||
|  | 
 | ||||||
|  |             canvas_set_color(gui->canvas, ColorWhite); | ||||||
|  |             canvas_draw_dot(gui->canvas, width + 4, 0); | ||||||
|  |             canvas_draw_dot(gui->canvas, width + 4, 12); | ||||||
|  | 
 | ||||||
|  |             canvas_set_color(gui->canvas, ColorBlack); | ||||||
|  | 
 | ||||||
|  |             canvas_frame_set( | ||||||
|  |                 gui->canvas, x + 3, GUI_STATUS_BAR_Y + 2, width, GUI_STATUS_BAR_HEIGHT); | ||||||
|             view_port_draw(view_port, gui->canvas); |             view_port_draw(view_port, gui->canvas); | ||||||
|  | 
 | ||||||
|             x += (width + 2); |             x += (width + 2); | ||||||
|         } |         } | ||||||
|         ViewPortArray_next(it); |         ViewPortArray_next(it); | ||||||
|  | |||||||
| @ -58,3 +58,13 @@ void icon_stop_animation(Icon* icon) { | |||||||
|     icon->tick = 0; |     icon->tick = 0; | ||||||
|     icon->frame = 0; |     icon->frame = 0; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | uint8_t icon_get_current_frame(Icon* icon) { | ||||||
|  |     furi_assert(icon); | ||||||
|  |     return icon->frame; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool icon_is_last_frame(Icon* icon) { | ||||||
|  |     furi_assert(icon); | ||||||
|  |     return icon->data->frame_count - icon->frame <= 1; | ||||||
|  | } | ||||||
| @ -46,6 +46,16 @@ void icon_start_animation(Icon* icon); | |||||||
|  */ |  */ | ||||||
| void icon_stop_animation(Icon* icon); | void icon_stop_animation(Icon* icon); | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * Get current frame | ||||||
|  |  */ | ||||||
|  | uint8_t icon_get_current_frame(Icon* icon); | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * Returns true if current frame is a last one | ||||||
|  |  */ | ||||||
|  | bool icon_is_last_frame(Icon* icon); | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -42,11 +42,10 @@ void power_draw_usb_callback(Canvas* canvas, void* context) { | |||||||
| void power_draw_battery_callback(Canvas* canvas, void* context) { | void power_draw_battery_callback(Canvas* canvas, void* context) { | ||||||
|     assert(context); |     assert(context); | ||||||
|     Power* power = context; |     Power* power = context; | ||||||
| 
 |  | ||||||
|     canvas_draw_icon(canvas, 0, 0, power->battery_icon); |     canvas_draw_icon(canvas, 0, 0, power->battery_icon); | ||||||
|     with_view_model( |     with_view_model( | ||||||
|         power->info_view, (PowerInfoModel * model) { |         power->info_view, (PowerInfoModel * model) { | ||||||
|             canvas_draw_box(canvas, 2, 2, (float)model->charge / 100 * 14, 4); |             canvas_draw_box(canvas, 2, 2, (float)model->charge / 100 * 20, 4); | ||||||
|             return false; |             return false; | ||||||
|         }); |         }); | ||||||
| } | } | ||||||
| @ -130,11 +129,11 @@ Power* power_alloc() { | |||||||
|     view_port_set_width(power->usb_view_port, icon_get_width(power->usb_icon)); |     view_port_set_width(power->usb_view_port, icon_get_width(power->usb_icon)); | ||||||
|     view_port_draw_callback_set(power->usb_view_port, power_draw_usb_callback, power); |     view_port_draw_callback_set(power->usb_view_port, power_draw_usb_callback, power); | ||||||
| 
 | 
 | ||||||
|     power->battery_icon = assets_icons_get(I_Battery_19x8); |     power->battery_icon = assets_icons_get(I_Battery_26x8); | ||||||
|     power->battery_view_port = view_port_alloc(); |     power->battery_view_port = view_port_alloc(); | ||||||
|  | 
 | ||||||
|     view_port_set_width(power->battery_view_port, icon_get_width(power->battery_icon)); |     view_port_set_width(power->battery_view_port, icon_get_width(power->battery_icon)); | ||||||
|     view_port_draw_callback_set(power->battery_view_port, power_draw_battery_callback, power); |     view_port_draw_callback_set(power->battery_view_port, power_draw_battery_callback, power); | ||||||
| 
 |  | ||||||
|     return power; |     return power; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/WatchingTV_128x64/frame_01.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 809 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/WatchingTV_128x64/frame_02.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 833 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/WatchingTV_128x64/frame_03.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 818 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/WatchingTV_128x64/frame_04.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 830 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/WatchingTV_128x64/frame_05.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 830 B | 
							
								
								
									
										1
									
								
								assets/icons/Animations/WatchingTV_128x64/frame_rate
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | |||||||
|  | 10 | ||||||
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/Wink_128x64/frame_01.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 674 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/Wink_128x64/frame_02.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 673 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/Wink_128x64/frame_03.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 667 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/Wink_128x64/frame_04.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 673 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/Wink_128x64/frame_05.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 674 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/Wink_128x64/frame_06.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 667 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/Wink_128x64/frame_07.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 673 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/Wink_128x64/frame_08.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 677 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Animations/Wink_128x64/frame_09.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 674 B | 
							
								
								
									
										1
									
								
								assets/icons/Animations/Wink_128x64/frame_rate
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | |||||||
|  | 10 | ||||||
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/BigBurger_24x24.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 356 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/BigGames_24x24.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 338 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/BigProfile_24x24.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 340 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Dolphin/DolphinOkay_41x43.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 423 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Interface/DoorLeft_8x56.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 328 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Interface/DoorLocked_10x56.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 372 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Interface/DoorRight_8x56.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 317 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Interface/PassportBottom_128x17.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 364 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/Interface/PassportLeft_6x47.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 298 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/StatusBar/Background_128x11.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 410 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/StatusBar/Background_128x8.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 374 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/StatusBar/Battery_26x8.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 313 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/StatusBar/Lock_8x8.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 303 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/StatusBar/PlaceholderL_11x13.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 312 B | 
							
								
								
									
										
											BIN
										
									
								
								assets/icons/StatusBar/PlaceholderR_30x13.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 318 B | 
 its your bedtime
						its your bedtime