diff --git a/.vscode/settings.json b/.vscode/settings.json index 6567bb65..d1d9dd6a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -29,6 +29,11 @@ "functional": "c", "tuple": "c", "type_traits": "c", - "utility": "c" + "utility": "c", + "mui_list_view.h": "c", + "nrf_log.h": "c", + "string.h": "c", + "math.h": "c", + "mlib_common.h": "c" } } \ No newline at end of file diff --git a/fw/application/Makefile b/fw/application/Makefile index fb1eeae3..5af589ca 100644 --- a/fw/application/Makefile +++ b/fw/application/Makefile @@ -211,6 +211,7 @@ SRC_FILES += \ $(PROJ_DIR)/mui/mui_mem.c \ $(PROJ_DIR)/mui/mui_anim.c \ $(PROJ_DIR)/mui/mui_math.c \ + $(PROJ_DIR)/mui/mui_resource.c \ $(PROJ_DIR)/mui/view/mui_list_view.c \ $(PROJ_DIR)/mui/view/mui_text_input.c \ $(PROJ_DIR)/mui/view/mui_msg_box.c \ @@ -275,6 +276,7 @@ SRC_FILES += \ $(PROJ_DIR)/app/chameleon/port/fds_utils.c \ $(PROJ_DIR)/app/chameleon/port/tag_helper.c \ $(PROJ_DIR)/app/desktop/app_desktop.c \ + $(PROJ_DIR)/app/desktop/view/app_list_view.c \ $(PROJ_DIR)/app/amiibo/app_amiibo.c \ $(PROJ_DIR)/app/amiibo/view/amiibo_detail_view.c \ $(PROJ_DIR)/app/amiibo/scene/amiibo_scene.c \ @@ -541,6 +543,7 @@ INC_FOLDERS += \ $(PROJ_DIR)/app/ble/scene \ $(PROJ_DIR)/app/ble/view \ $(PROJ_DIR)/app/desktop \ + $(PROJ_DIR)/app/desktop/view \ $(PROJ_DIR)/app/settings \ $(PROJ_DIR)/app/settings/scene \ $(PROJ_DIR)/app/amiibo \ @@ -721,6 +724,11 @@ ota: full: settingsgen mergehex --merge $(OUTPUT_DIRECTORY)/settings.hex $(OUTPUT_DIRECTORY)/bootloader.hex $(SDK_ROOT)/components/softdevice/s112/hex/s112_nrf52_7.2.0_softdevice.hex $(OUTPUT_DIRECTORY)/pixljs.hex --output $(OUTPUT_DIRECTORY)/pixljs_all.hex +gen: + python3 ../scripts/amiibo_db_gen.py + python3 ../scripts/i18n_gen.py + python3 ../scripts/resource_gen.py + flash_ocd: default openocd -f interface/cmsis-dap.cfg -c "transport select swd" -f target/nrf52.cfg -d2 -c init -c "reset init" -c halt -c "program $(OUTPUT_DIRECTORY)/pixljs.hex verify" -c "reset" -c exit diff --git a/fw/application/src/app/amiibo/app_amiibo.c b/fw/application/src/app/amiibo/app_amiibo.c index 56e6455d..192015b0 100644 --- a/fw/application/src/app/amiibo/app_amiibo.c +++ b/fw/application/src/app/amiibo/app_amiibo.c @@ -151,6 +151,7 @@ mini_app_t app_amiibo_info = {.id = MINI_APP_ID_AMIIBO, .sys = false, .deamon = false, .hibernate_enabled = true, + .icon_32x32 = &app_amiibo_emulator_32x32, .run_cb = app_amiibo_on_run, .kill_cb = app_amiibo_on_kill, .on_event_cb = app_amiibo_on_event}; diff --git a/fw/application/src/app/amiibo/scene/amiibo_scene_amiibo_detail_menu.c b/fw/application/src/app/amiibo/scene/amiibo_scene_amiibo_detail_menu.c index 3ca2d91c..58a09ba2 100644 --- a/fw/application/src/app/amiibo/scene/amiibo_scene_amiibo_detail_menu.c +++ b/fw/application/src/app/amiibo/scene/amiibo_scene_amiibo_detail_menu.c @@ -142,7 +142,7 @@ static void amiibo_scene_amiibo_detail_menu_on_selected(mui_list_view_event_t ev sprintf(msg, _T(DELETE_TAG_CONFIRM), string_get_cstr(app->current_file)); mui_msg_box_set_message(app->p_msg_box, msg); mui_msg_box_set_btn_text(app->p_msg_box, _T(CONFIRM), NULL, _T(CANCEL)); - mui_msg_box_set_btn_focus(app->p_msg_box, 0); + mui_msg_box_set_btn_focus(app->p_msg_box, 2); mui_msg_box_set_event_cb(app->p_msg_box, amiibo_scene_amiibo_detail_delete_tag_confirmed); mui_view_dispatcher_switch_to_view(app->p_view_dispatcher, AMIIBO_VIEW_ID_MSG_BOX); diff --git a/fw/application/src/app/amiibo/scene/amiibo_scene_file_browser_menu.c b/fw/application/src/app/amiibo/scene/amiibo_scene_file_browser_menu.c index 110471ba..169a605e 100644 --- a/fw/application/src/app/amiibo/scene/amiibo_scene_file_browser_menu.c +++ b/fw/application/src/app/amiibo/scene/amiibo_scene_file_browser_menu.c @@ -259,7 +259,7 @@ static void amiibo_scene_file_browser_menu_on_selected(mui_list_view_event_t eve mui_msg_box_set_header(app->p_msg_box, getLangString(_L_DELETE)); mui_msg_box_set_message(app->p_msg_box, msg); mui_msg_box_set_btn_text(app->p_msg_box, getLangString(_L_DELETE), NULL, getLangString(_L_CANCEL)); - mui_msg_box_set_btn_focus(app->p_msg_box, 0); + mui_msg_box_set_btn_focus(app->p_msg_box, 2); mui_msg_box_set_event_cb(app->p_msg_box, amiibo_scene_file_browser_menu_msg_box_remove_folder_event_cb); mui_view_dispatcher_switch_to_view(app->p_view_dispatcher, AMIIBO_VIEW_ID_MSG_BOX); diff --git a/fw/application/src/app/amiibolink/app_amiibolink.c b/fw/application/src/app/amiibolink/app_amiibolink.c index a1c01b44..3e2ad487 100644 --- a/fw/application/src/app/amiibolink/app_amiibolink.c +++ b/fw/application/src/app/amiibolink/app_amiibolink.c @@ -87,6 +87,7 @@ mini_app_t app_amiibolink_info = {.id = MINI_APP_ID_AMIIBOLINK, .deamon = false, .sys = false, .hibernate_enabled = true, + .icon_32x32 = &app_amiibo_link_32x32, .run_cb = app_amiibolink_on_run, .kill_cb = app_amiibolink_on_kill, .on_event_cb = app_amiibolink_on_event}; diff --git a/fw/application/src/app/amiidb/app_amiidb.c b/fw/application/src/app/amiidb/app_amiidb.c index 08627742..97c38d3c 100644 --- a/fw/application/src/app/amiidb/app_amiidb.c +++ b/fw/application/src/app/amiidb/app_amiidb.c @@ -155,6 +155,7 @@ const mini_app_t app_amiidb_info = {.id = MINI_APP_ID_AMIIDB, .sys = false, .deamon = false, .hibernate_enabled = false, + .icon_32x32 = &app_amiibo_database_32x32, .run_cb = app_amiidb_on_run, .kill_cb = app_amiidb_on_kill, .on_event_cb = app_amiidb_on_event}; diff --git a/fw/application/src/app/amiidb/scene/amiidb_scene_fav_list_menu.c b/fw/application/src/app/amiidb/scene/amiidb_scene_fav_list_menu.c index 7c99bff6..d55a5931 100644 --- a/fw/application/src/app/amiidb/scene/amiidb_scene_fav_list_menu.c +++ b/fw/application/src/app/amiidb/scene/amiidb_scene_fav_list_menu.c @@ -70,7 +70,7 @@ static void amiidb_scene_fav_list_menu_msg_box(app_amiidb_t *app, const char *he mui_msg_box_set_message(app->p_msg_box, msg); mui_msg_box_set_btn_text(app->p_msg_box, getLangString(_L_APP_AMIIDB_CONFIRM), NULL, getLangString(_L_APP_AMIIDB_CANCEL)); - mui_msg_box_set_btn_focus(app->p_msg_box, 0); + mui_msg_box_set_btn_focus(app->p_msg_box, 2); mui_msg_box_set_event_cb(app->p_msg_box, cb); mui_view_dispatcher_switch_to_view(app->p_view_dispatcher, AMIIDB_VIEW_ID_MSG_BOX); diff --git a/fw/application/src/app/ble/app_ble.c b/fw/application/src/app/ble/app_ble.c index 78d074d5..18bde963 100644 --- a/fw/application/src/app/ble/app_ble.c +++ b/fw/application/src/app/ble/app_ble.c @@ -54,6 +54,7 @@ mini_app_t app_ble_info = {.id = MINI_APP_ID_BLE, .deamon = false, .sys = false, .hibernate_enabled = false, + .icon_32x32 = &app_ble_transfer_32x32, .run_cb = app_ble_on_run, .kill_cb = app_ble_on_kill, .on_event_cb = app_ble_on_event}; diff --git a/fw/application/src/app/chameleon/app_chameleon.c b/fw/application/src/app/chameleon/app_chameleon.c index 2b5a2dfd..fdb1fb53 100644 --- a/fw/application/src/app/chameleon/app_chameleon.c +++ b/fw/application/src/app/chameleon/app_chameleon.c @@ -105,6 +105,7 @@ mini_app_t app_chameleon_info = {.id = MINI_APP_ID_CHAMELEON, .deamon = false, .sys = false, .hibernate_enabled = true, + .icon_32x32 = &app_card_emulator_32x32, .run_cb = app_chameleon_on_run, .kill_cb = app_chameleon_on_kill, .on_event_cb = app_chameleon_on_event}; diff --git a/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_data_file_load.c b/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_data_file_load.c index 884df232..41163a5b 100644 --- a/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_data_file_load.c +++ b/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_data_file_load.c @@ -54,6 +54,13 @@ void chameleon_scene_menu_card_data_file_load_from_file(app_chameleon_t *app, co return; } + // set nickname by filename + err = tag_helper_set_nickname(file_name); + if (err != 0) { + mui_toast_view_show(app->p_toast_view, _T(APP_CHAMELEON_CARD_SET_NICK_FAILED)); + return; + } + NRF_LOG_INFO("load card data:%d", err); mui_toast_view_show(app->p_toast_view, _T(APP_CHAMELEON_CARD_DATA_LOAD_SUCCESS)); mui_scene_dispatcher_back_scene(app->p_scene_dispatcher, 2); diff --git a/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_data_file_save.c b/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_data_file_save.c index 7770de98..ef3ee360 100644 --- a/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_data_file_save.c +++ b/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_data_file_save.c @@ -49,7 +49,7 @@ void chameleon_scene_menu_card_data_file_save_on_enter(void *user_data) { app_chameleon_t *app = user_data; char file_name[32]; - sprintf(file_name, "%02d.bin", tag_emulation_get_slot()); + tag_helper_get_nickname(file_name, sizeof(file_name)); mui_text_input_set_header(app->p_text_input, _T(APP_CHAMELEON_CARD_DATA_SAVE_INPUT_FILE_NAME)); mui_text_input_set_input_text(app->p_text_input, file_name); diff --git a/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_type.c b/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_type.c index 2c4a3475..0593f934 100644 --- a/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_type.c +++ b/fw/application/src/app/chameleon/scene/chameleon_scene_menu_card_type.c @@ -46,7 +46,7 @@ void chameleon_scene_menu_card_type_on_event(mui_list_view_event_t event, mui_li mui_msg_box_set_header(app->p_msg_box, _T(MESSAGE)); mui_msg_box_set_message(app->p_msg_box, _T(APP_CHAMELEON_CARD_TYPE_FACTORY_DATA_CONFRIM)); mui_msg_box_set_btn_text(app->p_msg_box, _T(CONFIRM), NULL, _T(CANCEL)); - mui_msg_box_set_btn_focus(app->p_msg_box, 0); + mui_msg_box_set_btn_focus(app->p_msg_box, 2); mui_msg_box_set_event_cb(app->p_msg_box, chameleon_scene_menu_card_type_factory_cb); mui_view_dispatcher_switch_to_view(app->p_view_dispatcher, CHAMELEON_VIEW_ID_MSG_BOX); diff --git a/fw/application/src/app/chameleon/view/chameleon_view.c b/fw/application/src/app/chameleon/view/chameleon_view.c index 351441d6..13fbbec8 100644 --- a/fw/application/src/app/chameleon/view/chameleon_view.c +++ b/fw/application/src/app/chameleon/view/chameleon_view.c @@ -17,7 +17,7 @@ static void chameleon_view_on_draw(mui_view_t *p_view, mui_canvas_t *p_canvas) { mui_canvas_set_font(p_canvas, MUI_FONT_NORMAL); - uint8_t x = 0, y = 0; + uint8_t x = 0, y = 0, w = 0; mui_canvas_draw_box(p_canvas, 0, y, mui_canvas_get_width(p_canvas), 12); mui_canvas_set_draw_color(p_canvas, 0); @@ -43,13 +43,19 @@ static void chameleon_view_on_draw(mui_view_t *p_view, mui_canvas_t *p_canvas) { mui_canvas_set_draw_color(p_canvas, 1); + x = 8; + y = 13 + (mui_canvas_get_height(p_canvas) - 16) / 2; + w = mui_canvas_get_width(p_canvas) - x * 2; + tag_helper_get_nickname(buff, sizeof(buff)); - y = 13 + (mui_canvas_get_height(p_canvas) - 16) / 2; - x = (mui_canvas_get_width(p_canvas) - mui_canvas_get_utf8_width(p_canvas, buff)) / 2; - mui_canvas_draw_utf8(p_canvas, x, y, buff); + if (w > mui_canvas_get_utf8_width(p_canvas, buff)) { + x += (w - mui_canvas_get_utf8_width(p_canvas, buff)) / 2; + } + + mui_canvas_draw_utf8_truncate(p_canvas, x, y, w, buff); mui_canvas_draw_utf8(p_canvas, 0, y, "<"); - mui_canvas_draw_utf8(p_canvas, mui_canvas_get_width(p_canvas) - 8, y, ">"); + mui_canvas_draw_utf8(p_canvas, mui_canvas_get_width(p_canvas) - 5, y, ">"); mui_canvas_set_font(p_canvas, MUI_FONT_SMALL); sprintf(buff, "%s <%02x/%02x %02x>", tag_name->short_name, coll_res->sak[0], coll_res->atqa[0], coll_res->atqa[1]); diff --git a/fw/application/src/app/desktop/app_desktop.c b/fw/application/src/app/desktop/app_desktop.c index ab09d24a..01df8280 100644 --- a/fw/application/src/app/desktop/app_desktop.c +++ b/fw/application/src/app/desktop/app_desktop.c @@ -3,9 +3,9 @@ #include "mui_include.h" +#include "app_list_view.h" #include "i18n/language.h" #include "mini_app_launcher.h" -#include "mui_list_view.h" typedef enum { DESKTOP_VIEW_ID_MAIN } desktop_view_id_t; @@ -14,13 +14,13 @@ static void app_desktop_on_kill(mini_app_inst_t *p_app_inst); static void app_desktop_on_event(mini_app_inst_t *p_app_inst, mini_app_event_t *p_event); typedef struct { - mui_list_view_t *p_list_view; + app_list_view_t *p_app_list_view; mui_view_dispatcher_t *p_view_dispatcher; } app_desktop_t; -static void app_desktop_list_view_on_selected(mui_list_view_event_t event, mui_list_view_t *p_view, - mui_list_item_t *p_item) { - mini_app_launcher_run(mini_app_launcher(), (uint32_t)p_item->user_data); +static void app_desktop_list_view_on_selected(app_list_view_event_t event, app_list_view_t *p_view) { + mini_app_t * app = app_list_view_get(p_view, app_list_view_get_focus(p_view)); + mini_app_launcher_run(mini_app_launcher(), app->id); } void app_desktop_on_run(mini_app_inst_t *p_app_inst) { @@ -29,30 +29,30 @@ void app_desktop_on_run(mini_app_inst_t *p_app_inst) { p_app_inst->p_handle = p_app_handle; p_app_handle->p_view_dispatcher = mui_view_dispatcher_create(); - p_app_handle->p_list_view = mui_list_view_create(); + p_app_handle->p_app_list_view = app_list_view_create(); for (uint32_t i = 0; i < mini_app_registry_get_app_num(); i++) { const mini_app_t *p_app = mini_app_registry_find_by_index(i); if (!p_app->sys) { - mui_list_view_add_item(p_app_handle->p_list_view, p_app->icon, getLangString(p_app->name_i18n_key), - (void *)p_app->id); + app_list_view_add_app(p_app_handle->p_app_list_view, p_app); } } - mui_list_view_set_selected_cb(p_app_handle->p_list_view, app_desktop_list_view_on_selected); + app_list_view_set_event_cb(p_app_handle->p_app_list_view, app_desktop_list_view_on_selected); mui_view_dispatcher_add_view(p_app_handle->p_view_dispatcher, DESKTOP_VIEW_ID_MAIN, - mui_list_view_get_view(p_app_handle->p_list_view)); - mui_view_dispatcher_attach(p_app_handle->p_view_dispatcher, MUI_LAYER_DESKTOP); + app_list_view_get_view(p_app_handle->p_app_list_view)); + mui_view_dispatcher_attach(p_app_handle->p_view_dispatcher, MUI_LAYER_WINDOW); mui_view_dispatcher_switch_to_view(p_app_handle->p_view_dispatcher, DESKTOP_VIEW_ID_MAIN); } void app_desktop_on_kill(mini_app_inst_t *p_app_inst) { app_desktop_t *p_app_handle = p_app_inst->p_handle; - mui_view_dispatcher_detach(p_app_handle->p_view_dispatcher, MUI_LAYER_DESKTOP); + mui_view_dispatcher_switch_to_view(p_app_handle->p_view_dispatcher, VIEW_NONE); + mui_view_dispatcher_detach(p_app_handle->p_view_dispatcher, MUI_LAYER_WINDOW); mui_view_dispatcher_free(p_app_handle->p_view_dispatcher); - mui_list_view_free(p_app_handle->p_list_view); + app_list_view_free(p_app_handle->p_app_list_view); mui_mem_free(p_app_handle); diff --git a/fw/application/src/app/desktop/view/app_list_view.c b/fw/application/src/app/desktop/view/app_list_view.c new file mode 100644 index 00000000..fbf4cfad --- /dev/null +++ b/fw/application/src/app/desktop/view/app_list_view.c @@ -0,0 +1,203 @@ +#include "app_list_view.h" +#include "i18n/language.h" +#include "nrf_log.h" +#include "settings.h" + +#define ICON_WIDTH 32 +#define ICON_HEIGHT 32 +#define ICON_MARGIN 3 +#define ICON_TOP_MARGIN 3 +#define ICON_GROUP_WIDTH (ICON_WIDTH + ICON_MARGIN) +#define FONT_HEIGHT 12 + +#define ICON_ANIM_LONG_TIME 500 +#define ICON_ANIM_SHORT_TIME 200 + +static bool mui_list_view_anim_enabled() { return settings_get_data()->anim_enabled; } +static void app_list_view_icon_anim_exec(void *p, int32_t value) { + app_list_view_t *p_view = (app_list_view_t *)p; + p_view->icon_anim_value = value; +} + +static void app_list_view_name_anim_exec(void *p, int32_t value) { + app_list_view_t *p_view = (app_list_view_t *)p; + p_view->name_anim_value = value; +} + +static void app_list_view_on_draw(mui_view_t *p_view, mui_canvas_t *p_canvas) { + app_list_view_t *p_list_view = p_view->user_data; + + p_list_view->canvas_height = p_canvas->height; + p_list_view->canvas_width = p_canvas->width; + + mini_app_t *focus_app = *ptr_array_get(p_list_view->items, p_list_view->focus); + + mui_canvas_set_font(p_canvas, u8g2_font_wqy12_t_gb2312a); + uint8_t font_height = mui_canvas_current_font_height(p_canvas); + uint8_t canvas_height = mui_canvas_get_height(p_canvas); + uint8_t canvas_width = mui_canvas_get_width(p_canvas); + uint8_t name_width = mui_canvas_get_utf8_width(p_canvas, getLangString(focus_app->name_i18n_key)); + uint8_t focus = p_list_view->focus; + + uint8_t first_offset = (canvas_width - ICON_WIDTH) / 2; + int16_t scroll_offset = focus * ICON_GROUP_WIDTH + p_list_view->icon_anim_value; + + // icon + mui_canvas_set_font(p_canvas, u8g2_font_siji_t_6x10); + mui_canvas_set_draw_color(p_canvas, 1); + + for (uint8_t i = 0; i < ptr_array_size(p_list_view->items); i++) { + mini_app_t *app = *ptr_array_get(p_list_view->items, i); + int16_t icon_x = i * ICON_GROUP_WIDTH - scroll_offset + first_offset; + if (icon_x + ICON_GROUP_WIDTH > 0 && icon_x < canvas_width) { + if (app->icon_32x32) { + mui_canvas_draw_xbm(p_canvas, icon_x, ICON_TOP_MARGIN, ICON_WIDTH, ICON_HEIGHT, app->icon_32x32->data); + } + } + } + + // focus + mui_canvas_set_draw_color(p_canvas, 2); + mui_canvas_draw_rbox(p_canvas, first_offset, ICON_TOP_MARGIN, 32, 32, 1); + mui_canvas_set_draw_color(p_canvas, 1); + + // left selection + // uint8_t fx = first_offset - 3; + // mui_canvas_draw_line(p_canvas, fx + 1, ICON_TOP_MARGIN - 2, fx + 3, ICON_TOP_MARGIN - 2); + // mui_canvas_draw_line(p_canvas, fx, ICON_TOP_MARGIN - 1, fx, ICON_TOP_MARGIN + ICON_HEIGHT); + // mui_canvas_draw_line(p_canvas, fx + 1, ICON_TOP_MARGIN + ICON_HEIGHT + 1, fx + 3, + // ICON_TOP_MARGIN + ICON_HEIGHT + 1); + + // // right selection + // fx = first_offset + ICON_WIDTH + 2; + // mui_canvas_draw_line(p_canvas, fx - 3, ICON_TOP_MARGIN - 2, fx - 1, ICON_TOP_MARGIN - 2); + // mui_canvas_draw_line(p_canvas, fx, ICON_TOP_MARGIN - 1, fx, ICON_TOP_MARGIN + ICON_HEIGHT); + // mui_canvas_draw_line(p_canvas, fx - 3, ICON_TOP_MARGIN + ICON_HEIGHT + 1, fx - 1, + // ICON_TOP_MARGIN + ICON_HEIGHT + 1); + + // dash line + mui_canvas_set_draw_color(p_canvas, 1); + for (uint8_t i = 0; i < canvas_width; i += 6) { + mui_canvas_draw_line(p_canvas, i, canvas_height - font_height, i + 3, canvas_height - font_height); + } + + // app name + mui_canvas_set_font(p_canvas, u8g2_font_wqy12_t_gb2312a); + mui_canvas_draw_utf8(p_canvas, (canvas_width - name_width) / 2, canvas_height - 1 + p_list_view->name_anim_value, + getLangString(focus_app->name_i18n_key)); + + // left and right icon + mui_canvas_set_font(p_canvas, u8g2_font_siji_t_6x10); + mui_canvas_draw_glyph(p_canvas, 0, canvas_height - 2, 0xe10b); + mui_canvas_draw_glyph(p_canvas, canvas_width - 12, canvas_height - 2, 0xe10a); +} + +static void app_list_view_on_input(mui_view_t *p_view, mui_input_event_t *event) { + app_list_view_t *p_app_list_view = p_view->user_data; + uint8_t size = ptr_array_size(p_app_list_view->items); + if (event->type == INPUT_TYPE_SHORT) { + switch (event->key) { + case INPUT_KEY_RIGHT: { + if (p_app_list_view->focus + 1 < size) { + p_app_list_view->focus++; + mui_anim_set_values(&p_app_list_view->icon_anim, -ICON_GROUP_WIDTH, 0); + mui_anim_set_time(&p_app_list_view->icon_anim, ICON_ANIM_SHORT_TIME); + } else { + p_app_list_view->focus = 0; + int32_t scroll_offset = 1 * size * ICON_GROUP_WIDTH; + mui_anim_set_values(&p_app_list_view->icon_anim, scroll_offset, 0); + mui_anim_set_time(&p_app_list_view->icon_anim, ICON_ANIM_LONG_TIME); + } + if (mui_list_view_anim_enabled()) { + mui_anim_start(&p_app_list_view->icon_anim); + mui_anim_set_values(&p_app_list_view->name_anim, FONT_HEIGHT, 0); + mui_anim_start(&p_app_list_view->name_anim); + } + } break; + + case INPUT_KEY_LEFT: { + if (p_app_list_view->focus - 1 >= 0) { + p_app_list_view->focus--; + mui_anim_set_values(&p_app_list_view->icon_anim, ICON_GROUP_WIDTH, 0); + mui_anim_set_time(&p_app_list_view->icon_anim, ICON_ANIM_SHORT_TIME); + + } else { + p_app_list_view->focus = size - 1; + int32_t scroll_offset = -1 * size * ICON_GROUP_WIDTH; + mui_anim_set_values(&p_app_list_view->icon_anim, scroll_offset, 0); + mui_anim_set_time(&p_app_list_view->icon_anim, ICON_ANIM_LONG_TIME); + } + if (mui_list_view_anim_enabled()) { + mui_anim_set_values(&p_app_list_view->name_anim, FONT_HEIGHT, 0); + mui_anim_start(&p_app_list_view->icon_anim); + mui_anim_start(&p_app_list_view->name_anim); + } + } + + break; + case INPUT_KEY_CENTER: + if (p_app_list_view->event_cb) { + p_app_list_view->event_cb(APP_LIST_ITEM_SELECTED, p_app_list_view); + } + break; + } + } +} + +static void app_list_view_on_enter(mui_view_t *p_view) { + app_list_view_t *p_app_list_view = p_view->user_data; + if (mui_list_view_anim_enabled()) { + mui_anim_set_values(&p_app_list_view->icon_anim, -ICON_GROUP_WIDTH, 0); + mui_anim_start(&p_app_list_view->icon_anim); + mui_anim_set_values(&p_app_list_view->name_anim, -FONT_HEIGHT, 0); + mui_anim_start(&p_app_list_view->name_anim); + } +} + +static void app_list_view_on_exit(mui_view_t *p_view) { + app_list_view_t *p_app_list_view = p_view->user_data; + if (mui_list_view_anim_enabled()) { + mui_anim_stop(&p_app_list_view->icon_anim); + mui_anim_stop(&p_app_list_view->name_anim); + } +} + +app_list_view_t *app_list_view_create() { + app_list_view_t *p_app_list_view = mui_mem_malloc(sizeof(app_list_view_t)); + + ptr_array_init(p_app_list_view->items); + p_app_list_view->focus = 0; + p_app_list_view->icon_anim_value = 0; + p_app_list_view->name_anim_value = 0; + + mui_anim_init(&p_app_list_view->icon_anim); + mui_anim_set_var(&p_app_list_view->icon_anim, p_app_list_view); + mui_anim_set_path_cb(&p_app_list_view->icon_anim, lv_anim_path_ease_in_out); + mui_anim_set_values(&p_app_list_view->icon_anim, 0, ICON_GROUP_WIDTH); + mui_anim_set_exec_cb(&p_app_list_view->icon_anim, app_list_view_icon_anim_exec); + mui_anim_set_time(&p_app_list_view->icon_anim, ICON_ANIM_SHORT_TIME); + + mui_anim_init(&p_app_list_view->name_anim); + mui_anim_set_var(&p_app_list_view->name_anim, p_app_list_view); + mui_anim_set_path_cb(&p_app_list_view->name_anim, lv_anim_path_ease_in_out); + mui_anim_set_values(&p_app_list_view->name_anim, FONT_HEIGHT, 0); + mui_anim_set_exec_cb(&p_app_list_view->name_anim, app_list_view_name_anim_exec); + mui_anim_set_time(&p_app_list_view->name_anim, ICON_ANIM_SHORT_TIME); + + mui_view_t *p_view = mui_view_create(); + p_view->user_data = p_app_list_view; + p_view->draw_cb = app_list_view_on_draw; + p_view->input_cb = app_list_view_on_input; + p_view->enter_cb = app_list_view_on_enter; + p_view->exit_cb = app_list_view_on_exit; + + p_app_list_view->p_view = p_view; + + return p_app_list_view; +} +void app_list_view_free(app_list_view_t *p_view) { + ptr_array_clear(p_view->items); + mui_view_free(p_view->p_view); + mui_mem_free(p_view); +} +mui_view_t *app_list_view_get_view(app_list_view_t *p_view) { return p_view->p_view; } \ No newline at end of file diff --git a/fw/application/src/app/desktop/view/app_list_view.h b/fw/application/src/app/desktop/view/app_list_view.h new file mode 100644 index 00000000..ef46d901 --- /dev/null +++ b/fw/application/src/app/desktop/view/app_list_view.h @@ -0,0 +1,56 @@ +#ifndef APP_LIST_VIEW_H +#define APP_LIST_VIEW_H + +#include "mui_include.h" +#include "mini_app_defines.h" + + +struct app_list_view_s; +typedef struct app_list_view_s app_list_view_t; + +typedef enum { + APP_LIST_ITEM_SELECTED, +} app_list_view_event_t; + +typedef void (*app_list_view_event_cb)(app_list_view_event_t event, app_list_view_t *p_view); + + struct app_list_view_s{ + mui_view_t* p_view; + app_list_view_event_cb event_cb; + uint8_t focus; + ptr_array_t items; + void* user_data; + mui_anim_t icon_anim; + int32_t icon_anim_value; + mui_anim_t name_anim; + int8_t name_anim_value; + + uint8_t canvas_height; + uint8_t canvas_width; +} ; + +app_list_view_t* app_list_view_create(); +void app_list_view_free(app_list_view_t* p_view); +mui_view_t* app_list_view_get_view(app_list_view_t* p_view); + +static inline void app_list_view_set_event_cb(app_list_view_t* p_view, app_list_view_event_cb event_cb){ + p_view->event_cb = event_cb; +} + +static inline void app_list_view_add_app(app_list_view_t* p_view, mini_app_t* p_app){ + ptr_array_push_back(p_view->items, p_app); +} + +static inline mini_app_t* app_list_view_get(app_list_view_t* p_view, uint8_t index){ + return (mini_app_t*) *ptr_array_get(p_view->items, index); +} +static inline uint8_t app_list_view_get_focus(app_list_view_t* p_view){ + return p_view->focus; +} + +static inline void app_list_view_set_user_data(app_list_view_t* p_view, void* user_data){ + p_view->user_data = user_data; +} + + +#endif \ No newline at end of file diff --git a/fw/application/src/app/settings/app_settings.c b/fw/application/src/app/settings/app_settings.c index ba0764cd..94208ebd 100644 --- a/fw/application/src/app/settings/app_settings.c +++ b/fw/application/src/app/settings/app_settings.c @@ -79,6 +79,7 @@ mini_app_t app_settings_info = {.id = MINI_APP_ID_SETTINGS, .deamon = false, .sys = false, .hibernate_enabled = false, + .icon_32x32 = &app_settings_32x32, .run_cb = app_settings_on_run, .kill_cb = app_settings_on_kill, .on_event_cb = app_settings_on_event}; diff --git a/fw/application/src/app/settings/scene/settings_scene_config.h b/fw/application/src/app/settings/scene/settings_scene_config.h index eb2377eb..f740b9ec 100644 --- a/fw/application/src/app/settings/scene/settings_scene_config.h +++ b/fw/application/src/app/settings/scene/settings_scene_config.h @@ -1,7 +1,9 @@ ADD_SCENE(settings, main, MAIN) ADD_SCENE(settings, version, VERSION) ADD_SCENE(settings, sleep_timeout, SLEEP_TIMEOUT) +#ifdef LCD_SCREEN ADD_SCENE(settings, lcd_backlight, LCD_BACKLIGHT) +#endif #ifdef OLED_SCREEN ADD_SCENE(settings, oled_contrast, OLED_CONTRAST) #endif diff --git a/fw/application/src/app/settings/scene/settings_scene_lcd_backlight.c b/fw/application/src/app/settings/scene/settings_scene_lcd_backlight.c index fa2b5921..54754069 100644 --- a/fw/application/src/app/settings/scene/settings_scene_lcd_backlight.c +++ b/fw/application/src/app/settings/scene/settings_scene_lcd_backlight.c @@ -10,6 +10,8 @@ #include "mui_u8g2.h" #include "i18n/language.h" +#ifdef LCD_SCREEN + static void settings_scene_lcd_backlight_event_cb(mui_progress_bar_event_t event, mui_progress_bar_t *p_progress_bar) { app_settings_t *app = p_progress_bar->user_data; settings_data_t *p_settings = settings_get_data(); @@ -38,4 +40,6 @@ void settings_scene_lcd_backlight_on_enter(void *user_data) { void settings_scene_lcd_backlight_on_exit(void *user_data) { app_settings_t *app = user_data; mui_progress_bar_reset(app->p_progress_bar); -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/fw/application/src/app/settings/scene/settings_scene_main.c b/fw/application/src/app/settings/scene/settings_scene_main.c index 8a3e39b5..70fdd3ba 100644 --- a/fw/application/src/app/settings/scene/settings_scene_main.c +++ b/fw/application/src/app/settings/scene/settings_scene_main.c @@ -25,6 +25,7 @@ enum settings_main_menu_t { SETTINGS_MAIN_MENU_EXIT }; +static void settings_scene_main_reload(void *user_data); static void settings_reset_default(void *user_data) { app_settings_t *app = user_data; settings_data_t *p_settings = settings_get_data(); @@ -38,7 +39,16 @@ static void settings_reset_default(void *user_data) { mui_toast_view_show(app->p_toast_view, _T(APP_SET_RESET_DEFAULT_SUCCESS)); } -static void settings_scene_main_reload(void *user_data); + +static void settings_scene_main_msg_box_reset_settings_cb(mui_msg_box_event_t event, mui_msg_box_t *p_msg_box) { + app_settings_t *app = p_msg_box->user_data; + if (event == MUI_MSG_BOX_EVENT_SELECT_LEFT) { + settings_reset(); + settings_reset_default(app); + settings_scene_main_reload(app); + } + mui_view_dispatcher_switch_to_view(app->p_view_dispatcher, SETTINGS_VIEW_ID_MAIN); +} static void settings_scene_main_list_view_on_selected(mui_list_view_event_t event, mui_list_view_t *p_list_view, mui_list_item_t *p_item) { @@ -49,9 +59,11 @@ static void settings_scene_main_list_view_on_selected(mui_list_view_event_t even uint32_t selection = (uint32_t)p_item->user_data; switch (selection) { +#ifdef LCD_SCREEN case SETTINGS_MAIN_MENU_BACK_LIGHT: mui_scene_dispatcher_next_scene(app->p_scene_dispatcher, SETTINGS_SCENE_LCD_BACKLIGHT); break; +#endif #ifdef OLED_SCREEN case SETTINGS_MAIN_MENU_OLED_CONTRAST: @@ -108,11 +120,17 @@ static void settings_scene_main_list_view_on_selected(mui_list_view_event_t even system_reboot(); break; - case SETTINGS_MAIN_MENU_RESET_DEFAULT: - settings_reset(); - settings_reset_default(app); - settings_scene_main_reload(app); - break; + case SETTINGS_MAIN_MENU_RESET_DEFAULT: { + mui_msg_box_set_header(app->p_msg_box, _T(APP_SET_RESET_DEFAULT)); + mui_msg_box_set_message(app->p_msg_box, _T(APP_SET_RESET_DEFAULT_CONFIRM)); + mui_msg_box_set_btn_text(app->p_msg_box, _T(CONFIRM), NULL, _T(CANCEL)); + mui_msg_box_set_btn_focus(app->p_msg_box, 2); + mui_msg_box_set_event_cb(app->p_msg_box, settings_scene_main_msg_box_reset_settings_cb); + + mui_view_dispatcher_switch_to_view(app->p_view_dispatcher, SETTINGS_VIEW_ID_MSG_BOX); + } + + break; } } diff --git a/fw/application/src/app/settings/scene/settings_scene_oled_contrast.c b/fw/application/src/app/settings/scene/settings_scene_oled_contrast.c index dc15cbc3..613bb3ed 100644 --- a/fw/application/src/app/settings/scene/settings_scene_oled_contrast.c +++ b/fw/application/src/app/settings/scene/settings_scene_oled_contrast.c @@ -10,6 +10,8 @@ #include "mui_u8g2.h" #include "i18n/language.h" +#ifdef OLED_SCREEN + static void settings_scene_oled_contrast_event_cb(mui_progress_bar_event_t event, mui_progress_bar_t *p_progress_bar) { app_settings_t *app = p_progress_bar->user_data; settings_data_t *p_settings = settings_get_data(); @@ -38,4 +40,6 @@ void settings_scene_oled_contrast_on_enter(void *user_data) { void settings_scene_oled_contrast_on_exit(void *user_data) { app_settings_t *app = user_data; mui_progress_bar_reset(app->p_progress_bar); -} \ No newline at end of file +} + +#endif \ No newline at end of file diff --git a/fw/application/src/app/settings/scene/settings_scene_storage.c b/fw/application/src/app/settings/scene/settings_scene_storage.c index 3ade269f..8d27996e 100644 --- a/fw/application/src/app/settings/scene/settings_scene_storage.c +++ b/fw/application/src/app/settings/scene/settings_scene_storage.c @@ -41,7 +41,7 @@ static void settings_scene_storage_on_selected(mui_list_view_event_t event, mui_ mui_msg_box_set_header(app->p_msg_box, getLangString(_L_FORMAT_STORAGE)); mui_msg_box_set_message(app->p_msg_box, getLangString(_L_DELETE_ALL_DATA)); mui_msg_box_set_btn_text(app->p_msg_box, getLangString(_L_CONFIRM), NULL, getLangString(_L_CANCEL)); - mui_msg_box_set_btn_focus(app->p_msg_box, 0); + mui_msg_box_set_btn_focus(app->p_msg_box, 2); mui_msg_box_set_event_cb(app->p_msg_box, settings_scene_storage_msg_box_format_cb); mui_view_dispatcher_switch_to_view(app->p_view_dispatcher, SETTINGS_VIEW_ID_MSG_BOX); diff --git a/fw/application/src/bat.c b/fw/application/src/bat.c index e22c98f2..da0745bb 100644 --- a/fw/application/src/bat.c +++ b/fw/application/src/bat.c @@ -40,11 +40,15 @@ void saadc_callback(nrf_drv_saadc_evt_t const *p_event) { NRF_LOG_INFO("ADC even chrg_data_t chrg = {0}; -void chrg_read(void* p_context) { - uint32_t new_stats = nrf_gpio_pin_read(CHRG_PIN); - if (new_stats == chrg.stats) return; - chrg.stats = new_stats; - if (chrg.callback != NULL) chrg.callback(); +static void bat_measure(chrg_data_t *p_chrg); + +void chrg_read(void *p_context) { + uint8_t old_stats = chrg.stats; + uint8_t old_level = chrg.level; + bat_measure(&chrg); + if ((old_level != chrg.level || old_stats != chrg.stats) && chrg.callback != NULL) { + chrg.callback(); + } } void chrg_set_callback(void *cb) { chrg.callback = cb; } @@ -61,13 +65,16 @@ void chrg_init(void) { if (settings_get_data()->bat_mode) { nrf_gpio_cfg_input(CHRG_PIN, NRF_GPIO_PIN_PULLUP); + } - err_code = app_timer_create(&m_chrg_timer, APP_TIMER_MODE_REPEATED, chrg_read); - APP_ERROR_CHECK(err_code); + // measure once + bat_measure(&chrg); - err_code = app_timer_start(m_chrg_timer, APP_TIMER_TICKS(200), NULL); - APP_ERROR_CHECK(err_code); - } + err_code = app_timer_create(&m_chrg_timer, APP_TIMER_MODE_REPEATED, chrg_read); + APP_ERROR_CHECK(err_code); + + err_code = app_timer_start(m_chrg_timer, APP_TIMER_TICKS(1000), NULL); + APP_ERROR_CHECK(err_code); } void saadc_init(void) { @@ -88,7 +95,9 @@ void saadc_uninit(void) { nrf_drv_saadc_uninit(); } -uint8_t bat_get_level(void) { +uint8_t bat_get_level(void) { return chrg.level; } + +void bat_measure(chrg_data_t *p_chrg) { nrf_saadc_value_t adc_value; ret_code_t err_code; @@ -121,5 +130,7 @@ uint8_t bat_get_level(void) { // sprintf(txt, "BAT: %d, %.02fV, %d", adc_value, voltage, level); // NRF_LOG_INFO("%s", nrf_log_push(txt)); - return level; + p_chrg->level = level; + p_chrg->voltage = voltage; + p_chrg->stats = nrf_gpio_pin_read(CHRG_PIN); } diff --git a/fw/application/src/bat.h b/fw/application/src/bat.h index 6a4bf3ed..85da82a4 100644 --- a/fw/application/src/bat.h +++ b/fw/application/src/bat.h @@ -10,17 +10,12 @@ #include #include -typedef enum { - EMPTY, - LEVEL_1, - LEVEL_2, - LEVEL_3, - FULL -} bat_level_t; typedef void (*chrg_data_cb_t)(void); typedef struct chrg { - uint32_t stats; + uint8_t stats; + uint8_t level; + float voltage; chrg_data_cb_t callback; } chrg_data_t; diff --git a/fw/application/src/core/mini_app_defines.h b/fw/application/src/core/mini_app_defines.h index af46efe6..0bfdfcd2 100644 --- a/fw/application/src/core/mini_app_defines.h +++ b/fw/application/src/core/mini_app_defines.h @@ -2,6 +2,7 @@ #define MINI_APP_DEFINES_H #include +#include "mui_resource.h" #include "cache.h" @@ -45,6 +46,7 @@ struct mini_app_s { const uint8_t deamon; const uint8_t sys; const uint8_t hibernate_enabled; + const xbm_t* icon_32x32; const mini_app_run_cb_t run_cb; const mini_app_kill_cb_t kill_cb; const mini_app_post_event_cb_t on_event_cb; diff --git a/fw/application/src/i18n/de_DE.c b/fw/application/src/i18n/de_DE.c index 0e68328a..1b62f1b2 100644 --- a/fw/application/src/i18n/de_DE.c +++ b/fw/application/src/i18n/de_DE.c @@ -9,8 +9,8 @@ const char * const lang_de_DE[_L_COUNT] = { [_L_ERR_CODE] = "Fehlercode", [_L_APP_AMIIBO] = "Amiibo-Emulator", [_L_APP_AMIIBOLINK] = "AmiiboLink", - [_L_APP_BLE] = "BLE-Dateiübertragung", - [_L_APP_BLE_TITLE] = "BLE-Dateiübertragung", + [_L_APP_BLE] = "BLE-Dateitransfer", + [_L_APP_BLE_TITLE] = "BLE-Dateitransfer", [_L_APP_PLAYER] = "Videospieler", [_L_APP_SET] = "Einstellungen", [_L_APP_SET_VERSION] = "Version", @@ -30,11 +30,12 @@ const char * const lang_de_DE[_L_COUNT] = { [_L_APP_SET_REBOOT] = "System-Neustart", [_L_APP_SET_RESET_DEFAULT] = "Standardeinstellungen", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "Einstellungen zurückgesetzt!", - [_L_15S] = "15 Sek", - [_L_30S] = "30 Sek", - [_L_45S] = "45 Sek", - [_L_1MIN] = "1 Min", - [_L_2MIN] = "2 Min", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "Auf Standardeinstellungen zurücksetzen?", + [_L_15S] = "15 Sekunden", + [_L_30S] = "30 Sekunden", + [_L_45S] = "45 Sekunden", + [_L_1MIN] = "1 Minute", + [_L_2MIN] = "2 Minuten", [_L_3MIN] = "3 Min", [_L_AMIIBO_KEY_UNLOADED] = "Schlüssel nicht gefunden", [_L_UPLOAD_KEY_RETAIL_BIN] = "Laden Sie die Datei key_retail.bin in das Stammverzeichnis des Speichers.", diff --git a/fw/application/src/i18n/en_US.c b/fw/application/src/i18n/en_US.c index 5f191279..9e029e16 100644 --- a/fw/application/src/i18n/en_US.c +++ b/fw/application/src/i18n/en_US.c @@ -30,6 +30,7 @@ const char * const lang_en_US[_L_COUNT] = { [_L_APP_SET_REBOOT] = "System Reboot", [_L_APP_SET_RESET_DEFAULT] = "Reset Default Setting", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "Reset Success!", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "Confirm Reset Settings?", [_L_15S] = "15 Seconds", [_L_30S] = "30 Seconds", [_L_45S] = "45 Seconds", diff --git a/fw/application/src/i18n/es_ES.c b/fw/application/src/i18n/es_ES.c index 9ab81698..777914e9 100644 --- a/fw/application/src/i18n/es_ES.c +++ b/fw/application/src/i18n/es_ES.c @@ -30,6 +30,7 @@ const char * const lang_es_ES[_L_COUNT] = { [_L_APP_SET_REBOOT] = "Reiniciar", [_L_APP_SET_RESET_DEFAULT] = "Restablecer config.", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "¡Configuración Restablecida!", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "", [_L_15S] = "15 segundos", [_L_30S] = "30 segundos", [_L_45S] = "45 segundos", diff --git a/fw/application/src/i18n/fr_FR.c b/fw/application/src/i18n/fr_FR.c index 4f5c5694..34188da9 100644 --- a/fw/application/src/i18n/fr_FR.c +++ b/fw/application/src/i18n/fr_FR.c @@ -30,6 +30,7 @@ const char * const lang_fr_FR[_L_COUNT] = { [_L_APP_SET_REBOOT] = "Redémarrage du Système", [_L_APP_SET_RESET_DEFAULT] = "Rétablir les Paramètres par Défaut", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "Réinitialiser les Paramètres Par Défaut", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "", [_L_15S] = "15 sec.", [_L_30S] = "30 sec.", [_L_45S] = "45 sec.", diff --git a/fw/application/src/i18n/hu_HU.c b/fw/application/src/i18n/hu_HU.c index f5c8c247..4d266ef4 100644 --- a/fw/application/src/i18n/hu_HU.c +++ b/fw/application/src/i18n/hu_HU.c @@ -30,6 +30,7 @@ const char * const lang_hu_HU[_L_COUNT] = { [_L_APP_SET_REBOOT] = "Rendszer Újraindítása", [_L_APP_SET_RESET_DEFAULT] = "Alapért. Beállítás Visszaállítása", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "Alapért. Beállítások Visszaállítása", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "", [_L_15S] = "15 sec.", [_L_30S] = "30 sec.", [_L_45S] = "45 sec.", diff --git a/fw/application/src/i18n/ja_JP.c b/fw/application/src/i18n/ja_JP.c index 504b9cbf..bfce8fd9 100644 --- a/fw/application/src/i18n/ja_JP.c +++ b/fw/application/src/i18n/ja_JP.c @@ -30,6 +30,7 @@ const char * const lang_ja_JP[_L_COUNT] = { [_L_APP_SET_REBOOT] = "システム再起動", [_L_APP_SET_RESET_DEFAULT] = "デフォルト設定に戻す", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "設定を初期化", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "", [_L_15S] = "15秒", [_L_30S] = "30秒", [_L_45S] = "45秒", diff --git a/fw/application/src/i18n/nl_NL.c b/fw/application/src/i18n/nl_NL.c index bafe5729..42ffe7a1 100644 --- a/fw/application/src/i18n/nl_NL.c +++ b/fw/application/src/i18n/nl_NL.c @@ -30,6 +30,7 @@ const char * const lang_nl_NL[_L_COUNT] = { [_L_APP_SET_REBOOT] = "Systeem Herstarten", [_L_APP_SET_RESET_DEFAULT] = "Terugzetten Naar Standaardwaarden", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "Standaardinstellingen Herstellen", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "", [_L_15S] = "15 sec.", [_L_30S] = "30 sec.", [_L_45S] = "45 sec.", diff --git a/fw/application/src/i18n/pt_BR.c b/fw/application/src/i18n/pt_BR.c index c60f301e..2ec6525a 100644 --- a/fw/application/src/i18n/pt_BR.c +++ b/fw/application/src/i18n/pt_BR.c @@ -30,6 +30,7 @@ const char * const lang_pt_BR[_L_COUNT] = { [_L_APP_SET_REBOOT] = "Reinicialização do Sistema", [_L_APP_SET_RESET_DEFAULT] = "Restaurar Configurações Padrão", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "Redefinir a Configuração Padrão", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "", [_L_15S] = "15 seg.", [_L_30S] = "30 seg.", [_L_45S] = "45 seg.", diff --git a/fw/application/src/i18n/string_id.h b/fw/application/src/i18n/string_id.h index 3fb6d778..2e118085 100644 --- a/fw/application/src/i18n/string_id.h +++ b/fw/application/src/i18n/string_id.h @@ -31,6 +31,7 @@ typedef enum { _L_APP_SET_REBOOT, _L_APP_SET_RESET_DEFAULT, _L_APP_SET_RESET_DEFAULT_SUCCESS, + _L_APP_SET_RESET_DEFAULT_CONFIRM, _L_15S, _L_30S, _L_45S, diff --git a/fw/application/src/i18n/zh_Hans.c b/fw/application/src/i18n/zh_Hans.c index 08a5f6ef..7b06ce96 100644 --- a/fw/application/src/i18n/zh_Hans.c +++ b/fw/application/src/i18n/zh_Hans.c @@ -30,6 +30,7 @@ const char * const lang_zh_Hans[_L_COUNT] = { [_L_APP_SET_REBOOT] = "重启设备", [_L_APP_SET_RESET_DEFAULT] = "重置默认配置", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "重置成功", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "确认重置默认设置?", [_L_15S] = "15秒", [_L_30S] = "30秒", [_L_45S] = "45秒", diff --git a/fw/application/src/i18n/zh_TW.c b/fw/application/src/i18n/zh_TW.c index 1f2635f9..2efe1a8c 100644 --- a/fw/application/src/i18n/zh_TW.c +++ b/fw/application/src/i18n/zh_TW.c @@ -30,6 +30,7 @@ const char * const lang_zh_TW[_L_COUNT] = { [_L_APP_SET_REBOOT] = "重啟設備", [_L_APP_SET_RESET_DEFAULT] = "重置默認配置", [_L_APP_SET_RESET_DEFAULT_SUCCESS] = "重置成功", + [_L_APP_SET_RESET_DEFAULT_CONFIRM] = "确认重置默认设置?", [_L_15S] = "15秒", [_L_30S] = "30秒", [_L_45S] = "45秒", diff --git a/fw/application/src/mui/mlib_common.h b/fw/application/src/mui/mlib_common.h index 65960071..5d2a94f9 100644 --- a/fw/application/src/mui/mlib_common.h +++ b/fw/application/src/mui/mlib_common.h @@ -15,5 +15,6 @@ #include "m-deque.h" ARRAY_DEF(string_array, string_t, STRING_OPLIST) +ARRAY_DEF(ptr_array, void*, M_BASIC_OPLIST ) #endif \ No newline at end of file diff --git a/fw/application/src/mui/mui_anim.c b/fw/application/src/mui/mui_anim.c index 003f6e24..e52a4ebc 100644 --- a/fw/application/src/mui/mui_anim.c +++ b/fw/application/src/mui/mui_anim.c @@ -235,6 +235,12 @@ void mui_anim_start(mui_anim_t *p_anim) { int32_t err_code; mui_anim_remove_ptr(p_anim); mui_anim_ptr_array_push_back(m_anim_ptr_array, p_anim); + + //fire cb first to set value + if(p_anim->exec_cb != NULL){ + p_anim->exec_cb(p_anim->var, p_anim->start_value); + } + p_anim->run_cnt = 0; p_anim->act_time = 0; NRF_LOG_INFO("anim start"); diff --git a/fw/application/src/mui/mui_anim.h b/fw/application/src/mui/mui_anim.h index b45953e2..ddf9ec21 100644 --- a/fw/application/src/mui/mui_anim.h +++ b/fw/application/src/mui/mui_anim.h @@ -63,7 +63,7 @@ static inline void mui_anim_set_auto_restart(mui_anim_t* p_anim, bool auto_resta p_anim->auto_restart = auto_restart; } -static inline void mui_anim_set_values(mui_anim_t* p_anim, int16_t start, int16_t end){ +static inline void mui_anim_set_values(mui_anim_t* p_anim, int32_t start, int32_t end){ p_anim->start_value = start; p_anim->end_value = end; p_anim->current_value = start; diff --git a/fw/application/src/mui/mui_canvas.c b/fw/application/src/mui/mui_canvas.c index f9dd8c11..6b99a744 100644 --- a/fw/application/src/mui/mui_canvas.c +++ b/fw/application/src/mui/mui_canvas.c @@ -44,7 +44,7 @@ int32_t mui_canvas_draw_utf8_clip(mui_canvas_t *p_canvas, int32_t x, int32_t y, w += utf8_w; } else { uint8_t utf8_x = mui_canvas_get_utf8_width(p_canvas, utf8); - xi += utf8_x + 1; //1 pix for margin + xi += utf8_x + 1; // 1 pix for margin w += utf8_x + 1; } p += utf8_size; @@ -59,6 +59,36 @@ uint8_t mui_canvas_draw_glyph(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint u8g2_DrawGlyph(p_canvas->fb, x, y, encoding); } +uint16_t mui_canvas_draw_utf8_truncate(mui_canvas_t* p_canvas, uint8_t x, uint8_t y, uint8_t max_width, const char *str) { + char *p = str; + char utf8[5]; + + if (max_width < mui_canvas_get_utf8_width(p_canvas, str)) { + while (*p != 0) { + uint8_t utf8_size = mui_canvas_get_utf8_bytes(p); + memcpy(utf8, p, utf8_size); + utf8[utf8_size] = '\0'; + if (x >= 0 && x <= max_width - 8) { + uint8_t utf8_w = mui_canvas_draw_utf8(p_canvas, x, y, utf8); + x += utf8_w; + } else { + uint8_t *font = u8g2_GetFont(p_canvas->fb); + u8g2_SetFont(p_canvas->fb, u8g2_font_siji_t_6x10); + uint8_t utf8_w = mui_canvas_draw_glyph(p_canvas, x, y - 1, 0xe21f); + u8g2_SetFont(p_canvas->fb, font); + x += utf8_w + 1; + + break; + } + p += utf8_size; + } + } else { + x = mui_canvas_draw_utf8(p_canvas, x, y, str) + 1; + } + + return x; +} + uint16_t mui_canvas_get_utf8_width(mui_canvas_t *p_canvas, const char *s) { return u8g2_GetUTF8Width(p_canvas->fb, s); } void mui_canvas_set_frame(mui_canvas_t *p_canvas, uint8_t offset_x, uint8_t offset_y, uint8_t width, uint8_t height) { @@ -89,6 +119,12 @@ void mui_canvas_draw_box(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t w u8g2_DrawBox(p_canvas->fb, x, y, w, h); } +void mui_canvas_draw_rbox(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t radius) { + x += p_canvas->offset_x; + y += p_canvas->offset_y; + u8g2_DrawRBox(p_canvas->fb, x, y, w, h, radius); +} + void mui_canvas_draw_dot(mui_canvas_t *p_canvas, uint8_t x, uint8_t y) { x += p_canvas->offset_x; y += p_canvas->offset_y; @@ -102,12 +138,19 @@ void mui_canvas_draw_rframe(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_ u8g2_DrawRFrame(p_canvas->fb, x, y, width, height, radius); } -void mui_canvas_draw_xbm(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t *bitmap) { +void mui_canvas_draw_xbm(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height, const uint8_t *bitmap) { x += p_canvas->offset_x; y += p_canvas->offset_y; u8g2_DrawXBM(p_canvas->fb, x, y, width, height, bitmap); } +void mui_canvas_draw_bitmap(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height, + const uint8_t *bitmap) { + x += p_canvas->offset_x; + y += p_canvas->offset_y; + u8g2_DrawBitmap(p_canvas->fb, x, y, width, height, bitmap); +} + uint16_t mui_canvas_string_width(mui_canvas_t *p_canvas, const char *str) { if (!str) return 0; return u8g2_GetStrWidth(p_canvas->fb, str); diff --git a/fw/application/src/mui/mui_canvas.h b/fw/application/src/mui/mui_canvas.h index d1e69fe2..f90b3d32 100644 --- a/fw/application/src/mui/mui_canvas.h +++ b/fw/application/src/mui/mui_canvas.h @@ -23,24 +23,29 @@ void mui_canvas_clear(mui_canvas_t *p_canvas); uint8_t mui_canvas_get_utf8_bytes(const char *p); - void mui_canvas_set_font(mui_canvas_t *p_canvas, const uint8_t *font); +void mui_canvas_set_font(mui_canvas_t *p_canvas, const uint8_t *font); uint8_t mui_canvas_draw_utf8(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, const char *str); int32_t mui_canvas_draw_utf8_clip(mui_canvas_t *p_canvas, int32_t x, int32_t y, const char *text); uint8_t mui_canvas_draw_glyph(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint16_t encoding); +uint16_t mui_canvas_draw_utf8_truncate(mui_canvas_t* p_canvas, uint8_t x, uint8_t y, uint8_t max_width, const char *str); uint16_t mui_canvas_get_utf8_width(mui_canvas_t *p_canvas, const char *s); void mui_canvas_set_frame(mui_canvas_t *p_canvas, uint8_t offset_x, uint8_t offset_y, uint8_t width, uint8_t height); -void mui_canvas_get_clip_window(mui_canvas_t *p_canvas, mui_rect_t* p_rect); -void mui_canvas_set_clip_window(mui_canvas_t *p_canvas, mui_rect_t* p_rect); +void mui_canvas_get_clip_window(mui_canvas_t *p_canvas, mui_rect_t *p_rect); +void mui_canvas_set_clip_window(mui_canvas_t *p_canvas, mui_rect_t *p_rect); uint8_t mui_canvas_get_draw_color(mui_canvas_t *p_canvas); void mui_canvas_set_draw_color(mui_canvas_t *p_canvas, uint8_t color); void mui_canvas_draw_box(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t w, uint8_t h); +void mui_canvas_draw_rbox(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t w, uint8_t h, uint8_t radius); void mui_canvas_draw_dot(mui_canvas_t *p_canvas, uint8_t x, uint8_t y); void mui_canvas_draw_rframe(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t radius); -void mui_canvas_draw_xbm(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height, uint8_t *bitmap); +void mui_canvas_draw_xbm(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height, + const uint8_t *bitmap); +void mui_canvas_draw_bitmap(mui_canvas_t *p_canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height, + const uint8_t *bitmap); uint16_t mui_canvas_string_width(mui_canvas_t *p_canvas, const char *str); diff --git a/fw/application/src/mui/mui_include.h b/fw/application/src/mui/mui_include.h index 71120406..514cea16 100644 --- a/fw/application/src/mui/mui_include.h +++ b/fw/application/src/mui/mui_include.h @@ -15,5 +15,6 @@ #include "mui_event.h" #include "mui_math.h" #include "mui_element.h" +#include "mui_resource.h" #endif \ No newline at end of file diff --git a/fw/application/src/mui/mui_resource.c b/fw/application/src/mui/mui_resource.c new file mode 100644 index 00000000..d637f93c --- /dev/null +++ b/fw/application/src/mui/mui_resource.c @@ -0,0 +1,105 @@ + +#include "mui_resource.h" +//************************************************************************ +//** /resources/bmp/app_amiibo_database_32x32.bmp +//************************************************************************ +const uint8_t app_amiibo_database_32x32_data[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x1f,0x00,0x80,0xff,0xff, +0x01,0xc0,0x0f,0xf0,0x03,0xf0,0x00,0x00,0x0f,0x78,0x00,0x00,0x1e,0x18,0x00, +0x38,0x18,0x18,0x00,0x38,0x18,0x18,0x00,0x38,0x18,0x78,0x00,0x00,0x1e,0xf8, +0x00,0x00,0x1f,0xd8,0x0f,0xf0,0x1b,0x98,0xff,0xff,0x19,0x18,0xf8,0x1f,0x18, +0x18,0x00,0x00,0x18,0x18,0x00,0x00,0x18,0x78,0x00,0x00,0x1e,0xf8,0x00,0x00, +0x1f,0xd8,0x0f,0xf0,0x1b,0x98,0xff,0xff,0x19,0x18,0xf8,0x1f,0x18,0x18,0x00, +0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00,0x00,0x18,0x78,0x00,0x00,0x1e,0xf0, +0x00,0x00,0x0f,0xc0,0x0f,0xf0,0x03,0x80,0xff,0xff,0x01,0x00,0xf8,0x1f,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +const xbm_t app_amiibo_database_32x32 = {.width = 32, .height = 32, .data = app_amiibo_database_32x32_data}; + + +//************************************************************************ +//** /resources/bmp/app_amiibo_emulator_32x32.bmp +//************************************************************************ +const uint8_t app_amiibo_emulator_32x32_data[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x30,0x00,0x00,0x0c,0x78,0x00,0x00,0x1e,0x78,0xe0,0x07,0x1e,0x70, +0xf8,0x1f,0x0e,0x00,0xf8,0x1f,0x00,0x00,0x3c,0x3c,0x00,0x70,0x1c,0x38,0x0e, +0xf8,0x1c,0x38,0x1f,0xf8,0x1c,0x38,0x1f,0x78,0x1c,0x38,0x0e,0x00,0x3c,0x38, +0x00,0x00,0xf8,0x3b,0x00,0x70,0xf8,0x3b,0x0e,0x78,0xe0,0x3b,0x1e,0x78,0x00, +0x00,0x1e,0x30,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +const xbm_t app_amiibo_emulator_32x32 = {.width = 32, .height = 32, .data = app_amiibo_emulator_32x32_data}; + + +//************************************************************************ +//** /resources/bmp/app_amiibo_link_32x32.bmp +//************************************************************************ +const uint8_t app_amiibo_link_32x32_data[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x00,0x00, +0x00,0x10,0x40,0xc0,0x07,0x90,0x22,0xf0,0x0f,0xb0,0x4a,0x7c,0x1c,0x00,0x00, +0x3f,0x18,0x00,0xc0,0x3f,0x18,0x00,0xf0,0x3f,0x18,0x00,0xfc,0x7f,0x1c,0x00, +0xff,0xff,0x1f,0x80,0xff,0xff,0x0f,0xc0,0xff,0xff,0x0f,0xe0,0x83,0xff,0x07, +0xe0,0x7d,0xff,0x07,0xf0,0xfe,0xfe,0x03,0x70,0xff,0xfd,0x03,0xb8,0xff,0xfb, +0x01,0xb8,0xff,0xfb,0x00,0xb8,0xff,0xfb,0x00,0xb8,0xff,0x7b,0x00,0xb8,0xff, +0x7b,0x00,0x70,0xff,0x3d,0x00,0xf0,0xfe,0x3e,0x00,0xe0,0x7d,0x1f,0x00,0xe0, +0x83,0x0f,0x00,0xc0,0xff,0x07,0x00,0x00,0xff,0x01,0x00,0x00,0x7c,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +const xbm_t app_amiibo_link_32x32 = {.width = 32, .height = 32, .data = app_amiibo_link_32x32_data}; + + +//************************************************************************ +//** /resources/bmp/app_ble_transfer_32x32.bmp +//************************************************************************ +const uint8_t app_ble_transfer_32x32_data[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03, +0x00,0x00,0xc0,0x0f,0x00,0x00,0xc0,0x1f,0x00,0x00,0xc0,0x7f,0x00,0x00,0xc3, +0xff,0x00,0x80,0xc7,0xfb,0x01,0x80,0xcf,0xf3,0x01,0x00,0xdf,0xfb,0x00,0x00, +0xfe,0x7f,0x00,0x40,0xfc,0x3f,0x02,0x20,0xf8,0x1f,0x04,0x90,0xf0,0x0f,0x09, +0x50,0xe0,0x07,0x0a,0x50,0xe0,0x07,0x0a,0x90,0xf0,0x0f,0x09,0x20,0xf8,0x1f, +0x04,0x40,0xfc,0x3f,0x02,0x00,0xfe,0x7f,0x00,0x00,0xdf,0xfb,0x00,0x80,0xcf, +0xf3,0x01,0x80,0xc7,0xfb,0x01,0x00,0xc3,0xff,0x00,0x00,0xc0,0x7f,0x00,0x00, +0xc0,0x1f,0x00,0x00,0xc0,0x0f,0x00,0x00,0x80,0x03,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +const xbm_t app_ble_transfer_32x32 = {.width = 32, .height = 32, .data = app_ble_transfer_32x32_data}; + + +//************************************************************************ +//** /resources/bmp/app_card_emulator_32x32.bmp +//************************************************************************ +const uint8_t app_card_emulator_32x32_data[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xc0,0xff,0xff,0x03,0x30,0x00,0x00,0x0c,0x18,0x00, +0x00,0x18,0x88,0xff,0xff,0x11,0x48,0x00,0x00,0x12,0x28,0xc0,0xb7,0x14,0x28, +0x00,0x00,0x14,0xa8,0xff,0xff,0x15,0x48,0x00,0x00,0x12,0x28,0xc7,0x7f,0x14, +0x28,0x09,0x00,0x14,0xa8,0xc8,0x6a,0x14,0x38,0x06,0x00,0x1c,0x78,0x00,0x00, +0x1e,0xf8,0x3f,0xfc,0x1f,0xf8,0x7f,0xfe,0x1f,0xf8,0xff,0xff,0x1f,0xf8,0xff, +0xff,0x1f,0xf8,0xff,0xff,0x1f,0xf8,0xff,0xff,0x1f,0xf0,0xff,0xff,0x0f,0x80, +0xff,0xff,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +const xbm_t app_card_emulator_32x32 = {.width = 32, .height = 32, .data = app_card_emulator_32x32_data}; + + +//************************************************************************ +//** /resources/bmp/app_settings_32x32.bmp +//************************************************************************ +const uint8_t app_settings_32x32_data[] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xc0,0x03,0x00,0x00,0xf0,0x07,0x00,0x00,0xf8,0x07,0x00,0x00, +0xfe,0x06,0x00,0x80,0x7f,0x03,0x00,0xc0,0xdf,0x01,0x00,0xf0,0xaf,0x00,0x00, +0xfc,0x57,0x00,0x00,0xfe,0x2b,0x00,0x80,0xff,0x12,0x00,0xe0,0xbf,0x09,0x00, +0xf0,0x5f,0x04,0x00,0xb0,0x2f,0x02,0x00,0x70,0x0b,0x01,0x00,0xf0,0x86,0x00, +0x00,0xf0,0x41,0x00,0x00,0xf0,0x20,0x00,0x00,0x70,0x10,0x00,0x00,0xf0,0x0f, +0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xfd,0xff,0x07,0xf0,0xfd,0xff,0x0f,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 +}; +const xbm_t app_settings_32x32 = {.width = 32, .height = 32, .data = app_settings_32x32_data}; + + + diff --git a/fw/application/src/mui/mui_resource.h b/fw/application/src/mui/mui_resource.h new file mode 100644 index 00000000..cc1c96e7 --- /dev/null +++ b/fw/application/src/mui/mui_resource.h @@ -0,0 +1,19 @@ + +#ifndef MUI_RESOURCE_H +#define MUI_RESOURCE_H + +#include + +typedef struct { + const uint8_t width; + const uint8_t height; + const uint8_t *data; +} xbm_t; +extern const xbm_t app_amiibo_database_32x32; +extern const xbm_t app_amiibo_emulator_32x32; +extern const xbm_t app_amiibo_link_32x32; +extern const xbm_t app_ble_transfer_32x32; +extern const xbm_t app_card_emulator_32x32; +extern const xbm_t app_settings_32x32; + +#endif diff --git a/fw/application/src/mui/mui_u8g2.c b/fw/application/src/mui/mui_u8g2.c index c666c182..f023c0dc 100644 --- a/fw/application/src/mui/mui_u8g2.c +++ b/fw/application/src/mui/mui_u8g2.c @@ -83,6 +83,8 @@ u8g2_t u8g2; static spi_device_t m_dev; uint8_t m_u8g2_initialized = 0; + +#ifdef LCD_SCREEN APP_PWM_INSTANCE(pwm1, 1); // Create the instance "PWM1" using TIMER1. static ret_code_t pwm_init(void) { @@ -106,12 +108,13 @@ static ret_code_t pwm_init(void) { app_pwm_enable(&pwm1); while (app_pwm_channel_duty_set(&pwm1, 0, init_duty) == NRF_ERROR_BUSY) ; - } return NRF_SUCCESS; } +#endif + uint8_t u8x8_HW_com_spi_nrf52832(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); uint8_t u8g2_nrf_gpio_and_delay_spi_cb(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr); @@ -184,35 +187,41 @@ void mui_u8g2_init(u8g2_t *p_u8g2) { nrf_gpio_cfg_output(LCD_RESET_PIN); nrf_gpio_cfg_output(LCD_DC_PIN); + +#ifdef LCD_SCREEN nrf_gpio_cfg_output(LCD_BL_PIN); nrf_gpio_pin_clear(LCD_BL_PIN); - #ifdef OLED_TYPE_SH1106 - u8g2_Setup_sh1106_128x64_noname_f(p_u8g2, U8G2_R0, u8x8_HW_com_spi_nrf52832, u8g2_nrf_gpio_and_delay_spi_cb); - #else - u8g2_Setup_st7567_enh_dg128064_f(p_u8g2, U8G2_R0, u8x8_HW_com_spi_nrf52832, u8g2_nrf_gpio_and_delay_spi_cb); - #endif + u8g2_Setup_st7567_enh_dg128064_f(p_u8g2, U8G2_R0, u8x8_HW_com_spi_nrf52832, u8g2_nrf_gpio_and_delay_spi_cb); + u8g2_InitDisplay(p_u8g2); + u8g2_SetPowerSave(p_u8g2, 0); + + pwm_init(); +#endif +#ifdef OLED_SCREEN + u8g2_Setup_sh1106_128x64_noname_f(p_u8g2, U8G2_R0, u8x8_HW_com_spi_nrf52832, u8g2_nrf_gpio_and_delay_spi_cb); u8g2_InitDisplay(p_u8g2); - #ifdef OLED_SCREEN - settings_data_t *p_settings = settings_get_data(); - mui_u8g2_set_oled_contrast_level(p_settings->oled_contrast); - #endif + settings_data_t *p_settings = settings_get_data(); + mui_u8g2_set_oled_contrast_level(p_settings->oled_contrast); u8g2_SetPowerSave(p_u8g2, 0); - pwm_init(); +#endif } void mui_u8g2_deinit(u8g2_t *p_u8g2) { u8g2_SetPowerSave(p_u8g2, 1); +#ifdef LCD_SCREEN mui_u8g2_set_backlight_level(0); nrf_gpio_pin_clear(LCD_BL_PIN); nrf_gpio_cfg_default(LCD_BL_PIN); +#endif } +#ifdef LCD_SCREEN void mui_u8g2_set_backlight(uint8_t bl) { nrf_gpio_pin_write(LCD_BL_PIN, bl); } uint8_t mui_u8g2_get_backlight() { return nrf_gpio_pin_out_read(LCD_BL_PIN); } @@ -228,9 +237,13 @@ void mui_u8g2_set_backlight_level(uint8_t value) { ; } } -int8_t mui_u8g2_get_backlight_level(void) { return (int8_t) app_pwm_channel_duty_get(&pwm1, 0); } +int8_t mui_u8g2_get_backlight_level(void) { return (int8_t)app_pwm_channel_duty_get(&pwm1, 0); } + +#endif +#ifdef OLED_SCREEN void mui_u8g2_set_oled_contrast_level(uint8_t value) { mui_t *p_mui = mui(); - u8g2_SetContrast(&p_mui->u8g2,(value - 1) * (255.0 / 99.0)); -} \ No newline at end of file + u8g2_SetContrast(&p_mui->u8g2, (value - 1) * (255.0 / 99.0)); +} +#endif \ No newline at end of file diff --git a/fw/components/u8g2/csrc/u8g2.h b/fw/components/u8g2/csrc/u8g2.h index a76b6cec..f435abc4 100644 --- a/fw/components/u8g2/csrc/u8g2.h +++ b/fw/components/u8g2/csrc/u8g2.h @@ -1670,6 +1670,7 @@ u8g2_uint_t u8g2_DrawExtUTF8(u8g2_t *u8g2, u8g2_uint_t x, u8g2_uint_t y, uint8_t #define u8g2_GetDescent(u8g2) ((u8g2)->font_ref_descent) #define u8g2_GetFontAscent(u8g2) ((u8g2)->font_ref_ascent) #define u8g2_GetFontDescent(u8g2) ((u8g2)->font_ref_descent) +#define u8g2_GetFont(u8g2) ((u8g2)->font) uint8_t u8g2_IsAllValidUTF8(u8g2_t *u8g2, const char *str); // checks whether all codes are valid diff --git a/fw/data/i18n.csv b/fw/data/i18n.csv index 3e2649cf..2a1de92a 100644 --- a/fw/data/i18n.csv +++ b/fw/data/i18n.csv @@ -8,8 +8,8 @@ _L_ERR,Error,错误,錯誤,Error,Hiba,Fehler,Erreur,Fout,Erro,エラー _L_ERR_CODE,Error Code,错误码,錯誤碼,Código error,Hibakód,Fehlercode,Code d'Erreur,Foutcode,Código de Erro,エラーコード _L_APP_AMIIBO,Amiibo Emulator,Amiibo模拟器,Amiibo模擬器,Emulador de amiibo,Amiibo Emulátor,Amiibo-Emulator,Emulateur Amiibo,Amiibo-Emulator,Emulador de Amiibo,Amiiboエミュレータ _L_APP_AMIIBOLINK,AmiiboLink,AmiiboLink,AmiiboLink,AmiiboLink,AmiiboLink,AmiiboLink,AmiiboLink,AmiiboLink,AmiiboLink,AmiiboLink -_L_APP_BLE,BLE File Transfer,蓝牙传输,藍牙傳送,Transferencia BLE,BLE Fájltovábbítás,BLE-Dateiübertragung,Transfert de Fichiers BLE,BLE Bestandsoverdracht,Transferência de Arquivos BLE,BLEファイル転送 -_L_APP_BLE_TITLE,BLE File Transfer,蓝牙传输,藍牙傳送,Transferencia BLE,BLE Fájltovábbítás,BLE-Dateiübertragung,Transfert de Fichiers BLE,BLE Bestandsoverdracht,Transferência de Arquivos BLE,BLEファイル転送 +_L_APP_BLE,BLE File Transfer,蓝牙传输,藍牙傳送,Transferencia BLE,BLE Fájltovábbítás,BLE-Dateitransfer,Transfert de Fichiers BLE,BLE Bestandsoverdracht,Transferência de Arquivos BLE,BLEファイル転送 +_L_APP_BLE_TITLE,BLE File Transfer,蓝牙传输,藍牙傳送,Transferencia BLE,BLE Fájltovábbítás,BLE-Dateitransfer,Transfert de Fichiers BLE,BLE Bestandsoverdracht,Transferência de Arquivos BLE,BLEファイル転送 _L_APP_PLAYER,Video Player,动画播放器,動畫播放器,Reproductor vídeo,Video Lejátszó,Videospieler,Lecteur Vidéo,Videospeler,Reprodutor de Vídeo,ビデオプレーヤー _L_APP_SET,Settings,系统设置,系統設定,Configuraciones,Beállítások,Einstellungen,Paramètres,Instellingen,Configurações,設定 _L_APP_SET_VERSION,Version,版本,版本,Versión,Verzió,Version,Version,Versie,Versão,バージョン @@ -29,11 +29,12 @@ _L_APP_SET_DFU,Firmware Update,固件更新,軟體升級,Actualizar firmware,Fir _L_APP_SET_REBOOT,System Reboot,重启设备,重啟設備,Reiniciar,Rendszer Újraindítása,System-Neustart,Redémarrage du Système,Systeem Herstarten,Reinicialização do Sistema,システム再起動 _L_APP_SET_RESET_DEFAULT,Reset Default Setting,重置默认配置,重置默認配置,Restablecer config.,Alapért. Beállítás Visszaállítása,Standardeinstellungen,Rétablir les Paramètres par Défaut,Terugzetten Naar Standaardwaarden,Restaurar Configurações Padrão,デフォルト設定に戻す _L_APP_SET_RESET_DEFAULT_SUCCESS,Reset Success!,重置成功,重置成功,¡Configuración Restablecida!,Alapért. Beállítások Visszaállítása,Einstellungen zurückgesetzt!,Réinitialiser les Paramètres Par Défaut,Standaardinstellingen Herstellen,Redefinir a Configuração Padrão,設定を初期化 -_L_15S,15 Seconds,15秒,15秒,15 segundos,15 sec.,15 Sek,15 sec.,15 sec.,15 seg.,15秒 -_L_30S,30 Seconds,30秒,30秒,30 segundos,30 sec.,30 Sek,30 sec.,30 sec.,30 seg.,30秒 -_L_45S,45 Seconds,45秒,45秒,45 segundos,45 sec.,45 Sek,45 sec.,45 sec.,45 seg.,45秒 -_L_1MIN,1 Minute,1分钟,1分鐘,1 minuto,1 min.,1 Min,1 min.,1 min.,1 min.,1分 -_L_2MIN,2 Minutes,2分钟,2分鐘,2 minutos,2 min.,2 Min,2 min.,2 min.,2 min.,2分 +_L_APP_SET_RESET_DEFAULT_CONFIRM,Confirm Reset Settings?,确认重置默认设置?,确认重置默认设置?,,,Auf Standardeinstellungen zurücksetzen?,,,, +_L_15S,15 Seconds,15秒,15秒,15 segundos,15 sec.,15 Sekunden,15 sec.,15 sec.,15 seg.,15秒 +_L_30S,30 Seconds,30秒,30秒,30 segundos,30 sec.,30 Sekunden,30 sec.,30 sec.,30 seg.,30秒 +_L_45S,45 Seconds,45秒,45秒,45 segundos,45 sec.,45 Sekunden,45 sec.,45 sec.,45 seg.,45秒 +_L_1MIN,1 Minute,1分钟,1分鐘,1 minuto,1 min.,1 Minute,1 min.,1 min.,1 min.,1分 +_L_2MIN,2 Minutes,2分钟,2分鐘,2 minutos,2 min.,2 Minuten,2 min.,2 min.,2 min.,2分 _L_3MIN,3 Minutes,3分钟,3分鐘,3 minutos,3 min.,3 Min,3 min.,3 min.,3 min.,3分 _L_AMIIBO_KEY_UNLOADED,Amiibo Key not loaded,Amiibo Key未加载,Amiibo Key未載入,Sin llave amiibo,Amiibo kulcs nincs betöltve,Schlüssel nicht gefunden,Clé Amiibo Non Chargée,Amiibo-Sleutel Niet Geladen,A chave Amiibo não foi carregada,Amiiboキーが読み込まれない _L_UPLOAD_KEY_RETAIL_BIN,Upload the file key_retail.bin to the root directory of the storage.,上传文件 key_retail.bin\n到存储根目录下。,上傳檔案 key_retail.bin\n到儲存根目錄下。,Suba el archivo\nkey_retail.bin\nal directorio raíz.,Töltse fel a key_retail.bin fájlt a gyökérkönyvtárába.,Laden Sie die Datei key_retail.bin in das Stammverzeichnis des Speichers.,Téléchargez le fichier key_retail.bin dans le répertoire racine du stockage.,Upload het bestand key_retail.bin naar de hoofdmap van de opslag.,Carregue o arquivo key_retail.bin no diretório raiz do armazenamento.,key_retail.binファイルをストレージのルートディレクトリにアップロードする。 @@ -46,7 +47,7 @@ _L_DELETE_TAG_CONFIRM,Confirm Delete %s ?,确认删除 %s ?,確認刪除 %s ?,¿ _L_BACK_TO_DETAILS,Back to Tag Details,返回详情,返回詳情,[Detalles amiibo],Vissza a Címke Részletkhez,Zurück zu Tag-Details,Retour Aux Détails de L'étiquette,Terug naar Tag Details,Voltar Aos Detalhes da Tag,タグの詳細に戻る _L_BACK_TO_FILE_LIST,Back to File List,返回文件列表,返回檔案清單,[Lista Archivos],Vissza a Fájl Listához,[Zurück zur Liste],Retour à La Liste Des Fichiers,Terug naar Bestandslijst,Voltar Para a Lista de Arquivos,ファイル一覧に戻る _L_BACK_TO_MAIN_MENU,Back to Main Menu,返回主菜单,返回主選單,[Menú Principal],Vissza a Főmenübe,[Hauptmenü],Retour au Menu Principal,Terug naar Hoofdmenu,Voltar ao Menu Principal,メインメニューに戻る -_L_FORMAT,Format,格式化,格式化,Formatear..,Formátum ,Formatieren,Format,Formatteren,Formatar,フォーマット +_L_FORMAT,Format,格式化,格式化,Formatear..,"Formátum ",Formatieren,Format,Formatteren,Formatar,フォーマット _L_FORMAT_STORAGE,Format Storage,格式化存储,格式化儲存,Formatear mem. Flash,Formátum Tárolás,Speicher formatieren,Format de Stockage,Opslag Formatteren,Formatar Armazenamento,保存領域フォーマット _L_DELETE_ALL_DATA,This will delete all data. Confirm format?,将删除所有数据。\n确认格式化?,將刪除所有資料。\n確認格式化?,Se borrará todos los\ndatos.,Minden adatot töröl. Formázás megerősítése?,Alle Daten löschen?,Cette opération efface toutes les données. Confirmer le formatage?,Hierdoor worden alle gegevens gewist. Formatteren bevestigen?,Isso excluirá todos os dados. Confirmar a formatação?,これですべてのデータが削除されます。よろしいですか? _L_DELETING_MESSAGE,Formatting ..,格式化中..,格式化中..,Formateando..,Formázás ..,Formatierung..,Formatage ..,Formatteren ..,Formatando ..,書式設定 .. @@ -74,7 +75,7 @@ _L_CREATE_TOO_MANY_NUM,Only max %d tags created in a batch.,一次最多只能 _L_CREATING_TAG_BATCH,Creating tag,创建标签,創建標簽,Creando,Címke létrehozása,Tag erstellen,Création d'une balise,Tag aanmaken,Criando tag,タグの作成 _L_CREATING_TAG_FAILED,Create tag %s failed!,写入 %s 标签失败,寫入 %s 標簽失敗,¡Error al crear %s!,Címke létrehozása %s sikertelen!,Erstellen von Tag %s fehlgeschlagen!,La création de la balise %s a échoué!,Aanmaken tag %s mislukt!,Falha ao criar a tag %s!,タグ %s の作成に失敗しました! _L_RENAME,Rename,重命名,重新命名,Renombrar,Átnevezés,Umbenennen,Renommer,Hernoem,Renomear,名前の変更 -_L_OPEN_FOLDER_FAILED,Failed to open folder,打开文件夹失败,開啟資料夾失敗,Fallo al abrir carpeta,Mappa megnyitása sikertelen ,Ordner konnte nicht geöffnet werden,Échec de l'ouverture du dossier,Kan map niet openen,Falha ao abrir a pasta,フォルダを開けませんでした +_L_OPEN_FOLDER_FAILED,Failed to open folder,打开文件夹失败,開啟資料夾失敗,Fallo al abrir carpeta,"Mappa megnyitása sikertelen ",Ordner konnte nicht geöffnet werden,Échec de l'ouverture du dossier,Kan map niet openen,Falha ao abrir a pasta,フォルダを開けませんでした _L_RENAME_FAILED,Failed to rename\nError code,重命名失败,重新命名失敗,Fallo al renombrar\nCódigo de error,Átnevezés Sikertelen\nHibakód,Umbenennen fehlgeschlagen\nFehlercode,Échec du renommage.\nCode d'Erreur,Hernoemen mislukt.\nFoutcode,Falha ao renomear\nCódigo de erro,名前の変更に失敗しました。\nエラーコード _L_MAIN_RETURN,[RETURN],[返回],[返回],[Volver],[VISSZA],[Zurück],[RETOUR],[TERUG],[RETORNO],[リターン] _L_RANDOM_MODE_MANUAL,Randomize (Manual),随机模式(手动),隨機模式(手動),Aleatorio (Manual),Randomizálás (Kézi),Zufällig (Manuell),Randomiser (Manuel),Willekeurig (Handmatig),Randomizar (Manual),ランダム化 (手動) @@ -124,7 +125,7 @@ _L_APP_AMIIDB_FAV_NEW_HEAD,New Fav. Folder:,新建收藏夹:,新建收藏夾:,Nu _L_APP_AMIIDB_FAV_EMPTY_MSG,Empty Fav. Folder?,确认清空收藏夹?,確認清空收藏夾?,¿Vaciar Carp. Favoritos?,Üres Kedvenc Mappa?,Favoritenordner leeren?,Vider le Dossier Favori?,Favoriete Map Leegmaken?,Esvaziar Pasta de Favoritos?,お気に入りフォルダを空にしますか? _L_APP_AMIIDB_FAV_DELETE_MSG,Confirm Delete?,确认删除?,確認刪除?,¿Confirma borrado?,Törlés Megerősítése?,Favoritenordner löschen?,Confirmer la Suppression?,Verwijderen Bevestigen?,Confirmar Exclusão?,削除してよろしいですか? _L_APP_AMIIDB_FAV_SELECT_FOLDER,Select Fav. Folder..,选择收藏夹..,選擇收藏夾..,Selec. carp. favoritos..,Kedvenc Mappa Kiválasztása..,Fav.-Ordner auswählen..,Sélectionner le Dossier Favori..,Selecteer Favoriete Map..,Selecionar Pasta Favorita..,お気に入りフォルダを選択.. -_L_APP_AMIIDB_FAV_SUCCESS,Favorite Success,收藏成功,收藏成功,¡Favorito correcto!,Kedvenc Sikeres,Favorit erstellt ,Succès du Favori,Favoriet Geslaagd,Favorito Bem-Sucedido,お気に入りに追加されました +_L_APP_AMIIDB_FAV_SUCCESS,Favorite Success,收藏成功,收藏成功,¡Favorito correcto!,Kedvenc Sikeres,"Favorit erstellt ",Succès du Favori,Favoriet Geslaagd,Favorito Bem-Sucedido,お気に入りに追加されました _L_APP_AMIIDB_FAV_FAILED,Favorite Failed!,收藏失败,收藏失敗,¡Favorito fallido!,Kedvenc Sikertelen!,Favorit fehlgeschlagen!,Échec du Favori!,Favoriet Mislukt!,Favorito Falhou!,お気に入りに追加できませんでした! _L_APP_AMIIDB_SLOT_SAVE_SUCCESS,Save Success,保存成功,保存成功,Asignación correcta,Sikeresen Mentve,Speichern erfolgreich,Sauvegarder Succès,Opslaan Succes,Salvar Com Êxito,保存されました _L_APP_AMIIDB_SLOT_SAVE_FAILED,Save Failed!,保存失败,保存失敗,¡Asignación fallida!,Mentés Sikertelen!,Speichern fehlgeschlagen!,Sauvegarde Échouée!,Opslaan Mislukt!,Falha ao Salvar!,保存に失敗しました! diff --git a/fw/resources/aseprite/app_amiibo_database_32x32.aseprite b/fw/resources/aseprite/app_amiibo_database_32x32.aseprite new file mode 100644 index 00000000..635d49e4 Binary files /dev/null and b/fw/resources/aseprite/app_amiibo_database_32x32.aseprite differ diff --git a/fw/resources/aseprite/app_amiibo_link_32x32.aseprite b/fw/resources/aseprite/app_amiibo_link_32x32.aseprite new file mode 100644 index 00000000..17fe2f25 Binary files /dev/null and b/fw/resources/aseprite/app_amiibo_link_32x32.aseprite differ diff --git a/fw/resources/aseprite/app_ble_transfer_32x32.aseprite b/fw/resources/aseprite/app_ble_transfer_32x32.aseprite new file mode 100644 index 00000000..2eb6e423 Binary files /dev/null and b/fw/resources/aseprite/app_ble_transfer_32x32.aseprite differ diff --git a/fw/resources/aseprite/app_card_emulator_32x32.aseprite b/fw/resources/aseprite/app_card_emulator_32x32.aseprite new file mode 100644 index 00000000..1cc0dae1 Binary files /dev/null and b/fw/resources/aseprite/app_card_emulator_32x32.aseprite differ diff --git a/fw/resources/aseprite/app_settings_32x32.aseprite b/fw/resources/aseprite/app_settings_32x32.aseprite new file mode 100644 index 00000000..6b25645d Binary files /dev/null and b/fw/resources/aseprite/app_settings_32x32.aseprite differ diff --git a/fw/resources/bmp/app_amiibo_database_32x32.bmp b/fw/resources/bmp/app_amiibo_database_32x32.bmp new file mode 100644 index 00000000..b97dd973 Binary files /dev/null and b/fw/resources/bmp/app_amiibo_database_32x32.bmp differ diff --git a/fw/resources/bmp/app_amiibo_emulator_32x32.bmp b/fw/resources/bmp/app_amiibo_emulator_32x32.bmp new file mode 100644 index 00000000..249ffd9d Binary files /dev/null and b/fw/resources/bmp/app_amiibo_emulator_32x32.bmp differ diff --git a/fw/resources/bmp/app_amiibo_link_32x32.bmp b/fw/resources/bmp/app_amiibo_link_32x32.bmp new file mode 100644 index 00000000..4934414d Binary files /dev/null and b/fw/resources/bmp/app_amiibo_link_32x32.bmp differ diff --git a/fw/resources/bmp/app_ble_transfer_32x32.bmp b/fw/resources/bmp/app_ble_transfer_32x32.bmp new file mode 100644 index 00000000..a795a93b Binary files /dev/null and b/fw/resources/bmp/app_ble_transfer_32x32.bmp differ diff --git a/fw/resources/bmp/app_card_emulator_32x32.bmp b/fw/resources/bmp/app_card_emulator_32x32.bmp new file mode 100644 index 00000000..90076545 Binary files /dev/null and b/fw/resources/bmp/app_card_emulator_32x32.bmp differ diff --git a/fw/resources/bmp/app_settings_32x32.bmp b/fw/resources/bmp/app_settings_32x32.bmp new file mode 100644 index 00000000..194dd5a9 Binary files /dev/null and b/fw/resources/bmp/app_settings_32x32.bmp differ diff --git a/fw/scripts/requirements.txt b/fw/scripts/requirements.txt new file mode 100644 index 00000000..d90fb7f4 --- /dev/null +++ b/fw/scripts/requirements.txt @@ -0,0 +1 @@ +imageio \ No newline at end of file diff --git a/fw/scripts/resource_gen.py b/fw/scripts/resource_gen.py new file mode 100644 index 00000000..99534cca --- /dev/null +++ b/fw/scripts/resource_gen.py @@ -0,0 +1,104 @@ +#!/usr/bin/python3 + +import sys +import io +import os +from PIL import Image, ImageOps +from struct import * + +RESOURCE_H_HEADER = ''' +#ifndef MUI_RESOURCE_H +#define MUI_RESOURCE_H + +#include + +typedef struct { + const uint8_t width; + const uint8_t height; + const uint8_t *data; +} xbm_t; +''' + +RESOURCE_H_TAILER = ''' +#endif +''' + +RESOURCE_C_HEADER = ''' +#include "mui_resource.h" +''' + +RESOURCE_C_TAILER = ''' +''' + +def get_prorject_directory(): + return os.path.abspath(os.path.dirname(__file__)+"/../") + +def get_im_size(file): + with Image.open(file) as im: + return im.size + + +def write_xbm(data, fp): + lines = str(data).split("\\n") + for line in lines: + if line.startswith("0x"): + fp.write(line) + fp.write("\n") + + +def get_xbm(file): + with Image.open(file) as im: + with io.BytesIO() as output: + bw = im.convert("1") + bw = ImageOps.invert(bw) + bw.save(output, format="xbm") + return output.getvalue() + +def gen_bmp(): + + project_dir = get_prorject_directory() + c_file_name = project_dir + "/application/src/mui/mui_resource.c" + c_file = open(c_file_name, "w+", newline="\n", encoding="utf8") + c_file.write(RESOURCE_C_HEADER) + + h_file_name = project_dir + "/application/src/mui/mui_resource.h" + h_file = open(h_file_name, "w+", newline="\n", encoding="utf8") + h_file.write(RESOURCE_H_HEADER) + + files = os.listdir(project_dir + "/resources/bmp") + files.sort() + + for file in files: + + file_name_abs = project_dir + "/resources/bmp/" + file + if os.path.isdir(file_name_abs): + continue + + img_size = get_im_size(file_name_abs) + xbm_data = get_xbm(file_name_abs) + + file_name, file_extension = os.path.splitext(file) + + h_file.write("extern const xbm_t "+file_name+";\n") + + c_file.write("//************************************************************************\n") + c_file.write("//** /resources/bmp/%s\n" % (file)) + c_file.write("//************************************************************************\n") + + c_file.write("const uint8_t %s_data[] = {\n" % (file_name)) + write_xbm(xbm_data, c_file) + c_file.write("};\n") + c_file.write("const xbm_t %s = {.width = %d, .height = %d, .data = %s_data};\n\n\n" % (file_name, img_size[0], img_size[1], file_name)) + + + c_file.write(RESOURCE_C_TAILER) + h_file.write(RESOURCE_H_TAILER) + + c_file.close() + h_file.close() + +def main(): + gen_bmp() + +###### +main() \ No newline at end of file