From 74cda02368252fa50d9c3dc2c0a78749572b6e01 Mon Sep 17 00:00:00 2001 From: gornekich Date: Fri, 29 Mar 2024 01:32:15 +0000 Subject: [PATCH 1/5] [FL-3803] NFC: Fix mf desfire detect (#3548) --- lib/nfc/protocols/mf_desfire/mf_desfire_poller.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c b/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c index 246107616d1..c9d8bbab603 100644 --- a/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c +++ b/lib/nfc/protocols/mf_desfire/mf_desfire_poller.c @@ -225,9 +225,17 @@ static bool mf_desfire_poller_detect(NfcGenericEvent event, void* context) { bool protocol_detected = false; if(iso14443_4a_event->type == Iso14443_4aPollerEventTypeReady) { - MfDesfireKeyVersion key_version = {0}; - MfDesfireError error = mf_desfire_poller_read_key_version(instance, 0, &key_version); - protocol_detected = (error == MfDesfireErrorNone); + do { + MfDesfireKeyVersion key_version = 0; + MfDesfireError error = mf_desfire_poller_read_key_version(instance, 0, &key_version); + if(error != MfDesfireErrorNone) break; + + MfDesfireVersion version = {}; + error = mf_desfire_poller_read_version(instance, &version); + if(error != MfDesfireErrorNone) break; + + protocol_detected = true; + } while(false); } return protocol_detected; From 538422e2a9b8601959d0c08758967151073684cc Mon Sep 17 00:00:00 2001 From: hedger Date: Fri, 29 Mar 2024 05:47:43 +0400 Subject: [PATCH 2/5] ufbt: fixes for generated vscode project (#3547) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: あく --- .vscode/example/settings.json | 2 +- scripts/ufbt/SConstruct | 4 +++- .../ufbt/project_template/.vscode/tasks.json | 18 ++++++------------ 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/.vscode/example/settings.json b/.vscode/example/settings.json index 00da3af2f81..a5919490133 100644 --- a/.vscode/example/settings.json +++ b/.vscode/example/settings.json @@ -14,7 +14,7 @@ "*.scons": "python", "SConscript": "python", "SConstruct": "python", - "*.fam": "python", + "*.fam": "python" }, "clangd.arguments": [ // We might be able to tighten this a bit more to only include the correct toolchain. diff --git a/scripts/ufbt/SConstruct b/scripts/ufbt/SConstruct index 11fefd22b59..784d6616121 100644 --- a/scripts/ufbt/SConstruct +++ b/scripts/ufbt/SConstruct @@ -393,7 +393,9 @@ for template_file in project_template_dir.Dir(".vscode").glob("*"): ), "@UFBT_APP_DIR@": PosixPathWrapper.fix_path(original_app_dir.abspath), "@UFBT_ROOT_DIR@": PosixPathWrapper.fix_path(Dir("#").abspath), - "@UFBT_DEBUG_DIR@": dist_env.subst("FBT_DEBUG_DIR"), + "@UFBT_DEBUG_DIR@": PosixPathWrapper.fix_path( + dist_env.subst("$FBT_DEBUG_DIR") + ), "@UFBT_DEBUG_ELF_DIR@": PosixPathWrapper.fix_path( dist_env["FBT_FAP_DEBUG_ELF_ROOT"].abspath ), diff --git a/scripts/ufbt/project_template/.vscode/tasks.json b/scripts/ufbt/project_template/.vscode/tasks.json index 65c749e07b9..16ef12836b1 100644 --- a/scripts/ufbt/project_template/.vscode/tasks.json +++ b/scripts/ufbt/project_template/.vscode/tasks.json @@ -31,28 +31,22 @@ "command": "ufbt -c" }, { - "label": "Flash FW (ST-Link)", + "label": "Flash FW (SWD)", "group": "build", "type": "shell", "command": "ufbt FORCE=1 flash" }, { - "label": "Flash FW (blackmagic)", - "group": "build", - "type": "shell", - "command": "ufbt flash_blackmagic" - }, - { - "label": "Flash FW (JLink)", + "label": "Flash FW (USB, with resources)", "group": "build", "type": "shell", - "command": "ufbt FORCE=1 jflash" + "command": "ufbt FORCE=1 flash_usb" }, { - "label": "Flash FW (USB, with resources)", + "label": "Open Flipper CLI session", "group": "build", "type": "shell", - "command": "ufbt FORCE=1 flash_usb" + "command": "ufbt cli" }, { "label": "Update uFBT SDK", @@ -61,7 +55,7 @@ "command": "ufbt update" }, { - "label": "Update VSCode config for current SDK", + "label": "Update VSCode config", "group": "build", "type": "shell", "command": "ufbt vscode_dist" From c353182353895daa3470f486c7c8123d280ee350 Mon Sep 17 00:00:00 2001 From: RebornedBrain <138568282+RebornedBrain@users.noreply.github.com> Date: Fri, 29 Mar 2024 05:45:01 +0300 Subject: [PATCH 3/5] [FL-3800, FL-3801] Fixed plugins and UI (#3543) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fixed some UI mismatches in plugin and nfc app * Fixed nameing mismatches in mosgortrans_util * Fix ultralight naming display Co-authored-by: gornekich Co-authored-by: あく --- .../main/nfc/api/mosgortrans/mosgortrans_util.c | 14 +++++++------- .../protocol_support/mf_ultralight/mf_ultralight.c | 2 ++ .../protocol_support/st25tb/st25tb_render.c | 13 +++++++++---- applications/main/nfc/nfc_app.c | 2 +- .../main/nfc/plugins/supported_cards/mykey.c | 7 +++---- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/applications/main/nfc/api/mosgortrans/mosgortrans_util.c b/applications/main/nfc/api/mosgortrans/mosgortrans_util.c index f2484a2af56..ef1e18f8d57 100644 --- a/applications/main/nfc/api/mosgortrans/mosgortrans_util.c +++ b/applications/main/nfc/api/mosgortrans/mosgortrans_util.c @@ -464,21 +464,21 @@ void parse_transport_type(BlockData* data_block, FuriString* transport) { bool mosgortrans_parse_transport_block(const MfClassicBlock* block, FuriString* result) { BlockData data_block = {}; const uint16_t valid_departments[] = {0x106, 0x108, 0x10A, 0x10E, 0x110, 0x117}; - uint16_t transport_departament = bit_lib_get_bits_16(block->data, 0, 10); + uint16_t transport_department = bit_lib_get_bits_16(block->data, 0, 10); if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - furi_string_cat_printf(result, "Transport departament: %x\n", transport_departament); + furi_string_cat_printf(result, "Transport department: %x\n", transport_department); } - bool departament_valid = false; + bool department_valid = false; for(uint8_t i = 0; i < 6; i++) { - if(transport_departament == valid_departments[i]) { - departament_valid = true; + if(transport_department == valid_departments[i]) { + department_valid = true; break; } } - if(!departament_valid) { + if(!department_valid) { return false; } - FURI_LOG_D(TAG, "Transport departament: %x", transport_departament); + FURI_LOG_D(TAG, "Transport department: %x", transport_department); uint16_t layout_type = bit_lib_get_bits_16(block->data, 52, 4); if(layout_type == 0xE) { layout_type = bit_lib_get_bits_16(block->data, 52, 9); diff --git a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c index c2aaac5bee5..0fe5a7664e0 100644 --- a/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c +++ b/applications/main/nfc/helpers/protocol_support/mf_ultralight/mf_ultralight.c @@ -30,6 +30,8 @@ static void nfc_scene_info_on_enter_mf_ultralight(NfcApp* instance) { furi_string_cat_printf( temp_str, "\e#%s\n", nfc_device_get_name(device, NfcDeviceNameTypeFull)); + furi_string_replace(temp_str, "Mifare", "MIFARE"); + nfc_render_mf_ultralight_info(data, NfcProtocolFormatTypeFull, temp_str); widget_add_text_scroll_element( diff --git a/applications/main/nfc/helpers/protocol_support/st25tb/st25tb_render.c b/applications/main/nfc/helpers/protocol_support/st25tb/st25tb_render.c index e3a0f3c50f8..6764f99a3df 100644 --- a/applications/main/nfc/helpers/protocol_support/st25tb/st25tb_render.c +++ b/applications/main/nfc/helpers/protocol_support/st25tb/st25tb_render.c @@ -1,22 +1,27 @@ #include "st25tb_render.h" #include +#include void nfc_render_st25tb_info( const St25tbData* data, NfcProtocolFormatType format_type, FuriString* str) { - furi_string_cat_printf(str, "UID"); + furi_string_cat_printf(str, "UID:"); for(size_t i = 0; i < ST25TB_UID_SIZE; i++) { furi_string_cat_printf(str, " %02X", data->uid[i]); } if(format_type == NfcProtocolFormatTypeFull) { - furi_string_cat_printf(str, "\nSys. OTP: %08lX", data->system_otp_block); - furi_string_cat_printf(str, "\nBlocks:"); + furi_string_cat_printf(str, "\nSys. OTP: %08lX", __bswap32(data->system_otp_block)); + furi_string_cat_printf(str, "\n::::::::::::::::::::::[Blocks]::::::::::::::::::::::"); for(size_t i = 0; i < st25tb_get_block_count(data->type); i += 2) { furi_string_cat_printf( - str, "\n %02X %08lX %08lX", i, data->blocks[i], data->blocks[i + 1]); + str, + "\n %02X %08lX %08lX", + i, + __bswap32(data->blocks[i]), + __bswap32(data->blocks[i + 1])); } } } diff --git a/applications/main/nfc/nfc_app.c b/applications/main/nfc/nfc_app.c index 26821c8f71b..02f852e3460 100644 --- a/applications/main/nfc/nfc_app.c +++ b/applications/main/nfc/nfc_app.c @@ -453,7 +453,7 @@ void nfc_append_filename_string_when_present(NfcApp* instance, FuriString* strin furi_assert(string); if(!furi_string_empty(instance->file_name)) { - furi_string_cat_printf(string, "Name:%s\n", furi_string_get_cstr(instance->file_name)); + furi_string_cat_printf(string, "Name: %s\n", furi_string_get_cstr(instance->file_name)); } } diff --git a/applications/main/nfc/plugins/supported_cards/mykey.c b/applications/main/nfc/plugins/supported_cards/mykey.c index ac5fec97c24..ed4c4cf9a5f 100644 --- a/applications/main/nfc/plugins/supported_cards/mykey.c +++ b/applications/main/nfc/plugins/supported_cards/mykey.c @@ -85,11 +85,10 @@ static bool mykey_parse(const NfcDevice* device, FuriString* parsed_data) { bool is_blank = mykey_is_blank(data); furi_string_cat_printf(parsed_data, "Serial#: %08lX\n", (uint32_t)__bswap32(data->blocks[7])); - furi_string_cat_printf(parsed_data, "Blank: %s\n", is_blank ? "yes" : "no"); - furi_string_cat_printf(parsed_data, "LockID: %s\n", mykey_has_lockid(data) ? "maybe" : "no"); - furi_string_cat_printf( - parsed_data, "Prod. date: %02X/%02X/%04X", mfg_day, mfg_month, mfg_year); + parsed_data, "Prod. date: %02X/%02X/%04X\n", mfg_day, mfg_month, mfg_year); + furi_string_cat_printf(parsed_data, "Blank: %s\n", is_blank ? "yes" : "no"); + furi_string_cat_printf(parsed_data, "LockID: %s", mykey_has_lockid(data) ? "maybe" : "no"); if(!is_blank) { furi_string_cat_printf( From 64bd2f9c84b7ac33a2b1dff5be4d357c8848ebbd Mon Sep 17 00:00:00 2001 From: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Date: Fri, 29 Mar 2024 06:32:43 +0300 Subject: [PATCH 4/5] [FL-3677, FL-3798] RFID Improvements (#3524) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update saved_info and read_success scenes * Update EM4100 rendering * Update HIDExt rendering * Update Gallagher rendering * Update HidProx rendering * Update IOProx rendering * Update H10301 rendering * Update PAC/Stanley rendering * Add strcasecmp() to API, better manufacturer/name handling * Update Viking rendering * Update FDX-A rendering * Update Pyramid rendering * Update Indala26 rendering * Update Idteck rendering * Update Keri rendering * Update Nexwatch rendering * Update Jablotron rendering * Update Paradox rendering * Truncate long Hex string on scene_read_suceess * Fix formatting * Update AWID rendering * Update FDX-B rendering * Tweak string formatting in various screens * More read_success view tweaks * Fix formatting * Fix Pyramid brief rendering * Reset saved key menu when going back * Reset other menus on back where applicable * Update confirmation scenes * Update emulation scene * Update delete scene * Update raw read info screen * Update raw read scene, fix crash * Update raw read success scene * Update write scene * Always return to SceneSelectKey after saving * Update SceneWriteSuccess and SceneDeleteSuccess * Replace closing parens with dots * FL-3798: Fix special formatting in text_box * Simplify SceneReadSuccess * Fix crash when having a trailing newline in text_box * Bump API symbols version * Make PVS happy * Format sources Co-authored-by: あく --- applications/main/lfrfid/lfrfid_i.h | 7 ++ .../scenes/lfrfid_scene_delete_confirm.c | 59 +++++++++-------- .../scenes/lfrfid_scene_delete_success.c | 7 +- .../main/lfrfid/scenes/lfrfid_scene_emulate.c | 29 ++++---- .../lfrfid/scenes/lfrfid_scene_exit_confirm.c | 4 +- .../scenes/lfrfid_scene_extra_actions.c | 3 + .../lfrfid/scenes/lfrfid_scene_raw_info.c | 34 +++++----- .../lfrfid/scenes/lfrfid_scene_raw_read.c | 66 ++++++++++++------- .../lfrfid/scenes/lfrfid_scene_raw_success.c | 22 +++++-- .../scenes/lfrfid_scene_read_key_menu.c | 3 + .../lfrfid/scenes/lfrfid_scene_read_success.c | 65 +++++++++--------- .../scenes/lfrfid_scene_retry_confirm.c | 7 +- .../lfrfid/scenes/lfrfid_scene_save_success.c | 13 +--- .../lfrfid/scenes/lfrfid_scene_saved_info.c | 56 ++++++++-------- .../scenes/lfrfid_scene_saved_key_menu.c | 3 + .../lfrfid/scenes/lfrfid_scene_select_key.c | 4 +- .../main/lfrfid/scenes/lfrfid_scene_start.c | 38 +++++------ .../main/lfrfid/scenes/lfrfid_scene_write.c | 30 +++++---- .../scenes/lfrfid_scene_write_success.c | 12 ++-- .../protocol_support/st25tb/st25tb_render.c | 7 +- applications/services/gui/elements.c | 48 +++++++------- lib/lfrfid/protocols/protocol_awid.c | 27 +++++--- lib/lfrfid/protocols/protocol_em4100.c | 3 +- lib/lfrfid/protocols/protocol_fdx_a.c | 14 ++-- lib/lfrfid/protocols/protocol_fdx_b.c | 45 ++++++++----- lib/lfrfid/protocols/protocol_gallagher.c | 43 +++++++++--- lib/lfrfid/protocols/protocol_h10301.c | 6 +- .../protocols/protocol_hid_ex_generic.c | 10 ++- lib/lfrfid/protocols/protocol_hid_generic.c | 4 +- lib/lfrfid/protocols/protocol_idteck.c | 28 +++----- lib/lfrfid/protocols/protocol_indala26.c | 19 +++--- lib/lfrfid/protocols/protocol_io_prox_xsf.c | 12 ++-- lib/lfrfid/protocols/protocol_jablotron.c | 4 +- lib/lfrfid/protocols/protocol_keri.c | 35 ++++++++-- lib/lfrfid/protocols/protocol_nexwatch.c | 40 +++++++++-- lib/lfrfid/protocols/protocol_pac_stanley.c | 3 +- lib/lfrfid/protocols/protocol_paradox.c | 29 +++++--- lib/lfrfid/protocols/protocol_pyramid.c | 6 +- lib/lfrfid/protocols/protocol_viking.c | 5 +- targets/f18/api_symbols.csv | 4 +- targets/f7/api_symbols.csv | 4 +- 41 files changed, 509 insertions(+), 349 deletions(-) diff --git a/applications/main/lfrfid/lfrfid_i.h b/applications/main/lfrfid/lfrfid_i.h index d94a5f865a8..70623154505 100644 --- a/applications/main/lfrfid/lfrfid_i.h +++ b/applications/main/lfrfid/lfrfid_i.h @@ -122,6 +122,13 @@ typedef enum { LfRfidViewRead, } LfRfidView; +typedef enum { + LfRfidMenuIndexRead, + LfRfidMenuIndexSaved, + LfRfidMenuIndexAddManually, + LfRfidMenuIndexExtraActions, +} LfRfidMenuIndex; + bool lfrfid_save_key(LfRfid* app); bool lfrfid_load_key_from_file_select(LfRfid* app); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c b/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c index b7702e26915..17d024d3615 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_delete_confirm.c @@ -1,45 +1,50 @@ #include "../lfrfid_i.h" +#define LFRFID_SCENE_DELETE_MAX_HEX_WIDTH (7UL) + void lfrfid_scene_delete_confirm_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - FuriString* tmp_string; - tmp_string = furi_string_alloc(); + FuriString* display_text = furi_string_alloc_printf( + "\e#Delete %s?\e#\n" + "Hex: ", + furi_string_get_cstr(app->file_name)); - widget_add_button_element(widget, GuiButtonTypeLeft, "Back", lfrfid_widget_callback, app); - widget_add_button_element(widget, GuiButtonTypeRight, "Delete", lfrfid_widget_callback, app); + const size_t data_size = protocol_dict_get_data_size(app->dict, app->protocol_id); + uint8_t* data = malloc(data_size); + + protocol_dict_get_data(app->dict, app->protocol_id, data, data_size); - furi_string_printf(tmp_string, "Delete %s?", furi_string_get_cstr(app->file_name)); - widget_add_string_element( - widget, 64, 0, AlignCenter, AlignTop, FontPrimary, furi_string_get_cstr(tmp_string)); - - furi_string_reset(tmp_string); - size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); - uint8_t* data = (uint8_t*)malloc(size); - protocol_dict_get_data(app->dict, app->protocol_id, data, size); - for(uint8_t i = 0; i < MIN(size, (size_t)8); i++) { - if(i != 0) { - furi_string_cat_printf(tmp_string, " "); + for(size_t i = 0; i < data_size; i++) { + if(i == LFRFID_SCENE_DELETE_MAX_HEX_WIDTH) { + furi_string_cat(display_text, " ..."); + break; } - furi_string_cat_printf(tmp_string, "%02X", data[i]); + furi_string_cat_printf(display_text, "%s%02X", i != 0 ? " " : "", data[i]); } + + furi_string_push_back(display_text, '\n'); + free(data); - widget_add_string_element( - widget, 64, 19, AlignCenter, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); - widget_add_string_element( - widget, - 64, - 49, - AlignCenter, - AlignBottom, - FontSecondary, - protocol_dict_get_name(app->dict, app->protocol_id)); + const char* protocol = protocol_dict_get_name(app->dict, app->protocol_id); + const char* manufacturer = protocol_dict_get_manufacturer(app->dict, app->protocol_id); + + if(strcasecmp(protocol, manufacturer) != 0 && strcasecmp(manufacturer, "N/A") != 0) { + furi_string_cat_printf(display_text, "%s ", manufacturer); + } + + furi_string_cat(display_text, protocol); + + widget_add_text_box_element( + widget, 0, 0, 128, 64, AlignCenter, AlignTop, furi_string_get_cstr(display_text), true); + widget_add_button_element(widget, GuiButtonTypeLeft, "Cancel", lfrfid_widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeRight, "Delete", lfrfid_widget_callback, app); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - furi_string_free(tmp_string); + furi_string_free(display_text); } bool lfrfid_scene_delete_confirm_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c index abb173a73d7..9c9b39d3d04 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_delete_success.c @@ -18,10 +18,9 @@ bool lfrfid_scene_delete_success_on_event(void* context, SceneManagerEvent event LfRfid* app = context; bool consumed = false; - if((event.type == SceneManagerEventTypeBack) || - ((event.type == SceneManagerEventTypeCustom) && (event.event == LfRfidEventPopupClosed))) { - scene_manager_search_and_switch_to_previous_scene( - app->scene_manager, LfRfidSceneSelectKey); + if(event.type == SceneManagerEventTypeBack || event.type == SceneManagerEventTypeCustom) { + // Always return to SceneSelectKey from here + scene_manager_search_and_switch_to_another_scene(app->scene_manager, LfRfidSceneSelectKey); consumed = true; } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c index dc39189942f..049c24d002a 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_emulate.c @@ -2,27 +2,28 @@ void lfrfid_scene_emulate_on_enter(void* context) { LfRfid* app = context; - Popup* popup = app->popup; + Widget* widget = app->widget; - popup_set_header(popup, "Emulating", 89, 30, AlignCenter, AlignTop); - if(!furi_string_empty(app->file_name)) { - popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); + FuriString* display_text = furi_string_alloc_set("\e#Emulating\e#\n"); + + if(furi_string_empty(app->file_name)) { + furi_string_cat(display_text, "Unsaved\n"); + furi_string_cat(display_text, protocol_dict_get_name(app->dict, app->protocol_id)); } else { - popup_set_text( - popup, - protocol_dict_get_name(app->dict, app->protocol_id), - 89, - 43, - AlignCenter, - AlignTop); + furi_string_cat(display_text, app->file_name); } - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); + + widget_add_icon_element(widget, 0, 0, &I_NFC_dolphin_emulation_51x64); + widget_add_text_box_element( + widget, 55, 16, 67, 48, AlignCenter, AlignTop, furi_string_get_cstr(display_text), true); + + furi_string_free(display_text); lfrfid_worker_start_thread(app->lfworker); lfrfid_worker_emulate_start(app->lfworker, (LFRFIDProtocol)app->protocol_id); notification_message(app->notifications, &sequence_blink_start_magenta); - view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); + view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); } bool lfrfid_scene_emulate_on_event(void* context, SceneManagerEvent event) { @@ -35,7 +36,7 @@ bool lfrfid_scene_emulate_on_event(void* context, SceneManagerEvent event) { void lfrfid_scene_emulate_on_exit(void* context) { LfRfid* app = context; notification_message(app->notifications, &sequence_blink_stop); - popup_reset(app->popup); + widget_reset(app->widget); lfrfid_worker_stop(app->lfworker); lfrfid_worker_stop_thread(app->lfworker); } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_exit_confirm.c b/applications/main/lfrfid/scenes/lfrfid_scene_exit_confirm.c index e8ab481c6fa..55f02d7402f 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_exit_confirm.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_exit_confirm.c @@ -7,9 +7,9 @@ void lfrfid_scene_exit_confirm_on_enter(void* context) { widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", lfrfid_widget_callback, app); widget_add_button_element(widget, GuiButtonTypeRight, "Stay", lfrfid_widget_callback, app); widget_add_string_element( - widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Exit to RFID Menu?"); + widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Exit to RFID Menu?"); widget_add_string_element( - widget, 64, 31, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost!"); + widget, 64, 13, AlignCenter, AlignTop, FontSecondary, "All unsaved data will be lost"); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c index 1aed9a03c37..f2e09982866 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_extra_actions.c @@ -70,6 +70,9 @@ bool lfrfid_scene_extra_actions_on_event(void* context, SceneManagerEvent event) consumed = true; } scene_manager_set_scene_state(app->scene_manager, LfRfidSceneExtraActions, event.event); + + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneExtraActions, 0); } return consumed; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c index f403c1f38ed..ba85c6ca1fd 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_info.c @@ -4,37 +4,39 @@ void lfrfid_scene_raw_info_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - // FuriString* tmp_string; - // tmp_string = furi_string_alloc(); - - bool sd_exist = storage_sd_status(app->storage) == FSE_OK; - if(!sd_exist) { - widget_add_icon_element(widget, 0, 0, &I_SDQuestion_35x43); + if(storage_sd_status(app->storage) != FSE_OK) { + widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42); + widget_add_string_element( + widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "No SD Card!"); widget_add_string_multiline_element( widget, - 81, - 4, - AlignCenter, + 0, + 13, + AlignLeft, AlignTop, FontSecondary, - "No SD card found.\nThis function will not\nwork without\nSD card."); + "Insert an SD card\n" + "to use this function"); - widget_add_button_element(widget, GuiButtonTypeLeft, "Back", lfrfid_widget_callback, app); } else { - widget_add_string_multiline_element( + widget_add_text_box_element( widget, 0, - 1, + 0, + 128, + 64, AlignLeft, AlignTop, - FontSecondary, - "RAW RFID data reader\n1) Put the Flipper on your card\n2) Press OK\n3) Wait until data is read"); + "\e#RAW RFID Data Reader\e#\n" + "1. Hold card next to Flipper\n" + "2. Press OK\n" + "3. Wait until data is read", + false); widget_add_button_element(widget, GuiButtonTypeCenter, "OK", lfrfid_widget_callback, app); } view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - //furi_string_free(tmp_string); } bool lfrfid_scene_raw_info_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c index b2c7c364e10..b86b86b217e 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_read.c @@ -1,6 +1,6 @@ #include "../lfrfid_i.h" -#define RAW_READ_TIME 5000 +#define RAW_READ_TIME_MS (5000UL) typedef struct { FuriString* string_file_name; @@ -29,24 +29,28 @@ void lfrfid_scene_raw_read_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - LfRfidReadRawState* state = malloc(sizeof(LfRfidReadRawState)); - scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawRead, (uint32_t)state); - state->string_file_name = furi_string_alloc(); + popup_set_icon(popup, 0, 0, &I_NFC_dolphin_emulation_51x64); + popup_set_header(popup, "Reading ASK", 91, 16, AlignCenter, AlignTop); + popup_set_text(popup, "Don't move\nfor 5 sec.", 91, 29, AlignCenter, AlignTop); - popup_set_icon(popup, 0, 3, &I_RFIDDolphinReceive_97x61); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); - lfrfid_worker_start_thread(app->lfworker); - lfrfid_make_app_folder(app); + LfRfidReadRawState* state = malloc(sizeof(LfRfidReadRawState)); + state->string_file_name = furi_string_alloc(); state->timer = furi_timer_alloc(timer_callback, FuriTimerTypeOnce, app); - furi_timer_start(state->timer, RAW_READ_TIME); + + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneRawRead, (uint32_t)state); + furi_string_printf( state->string_file_name, "%s/%s%s", LFRFID_SD_FOLDER, furi_string_get_cstr(app->raw_file_name), LFRFID_APP_RAW_ASK_EXTENSION); - popup_set_header(popup, "Reading\nRAW RFID\nASK", 89, 30, AlignCenter, AlignTop); + + lfrfid_make_app_folder(app); + + lfrfid_worker_start_thread(app->lfworker); lfrfid_worker_read_raw_start( app->lfworker, furi_string_get_cstr(state->string_file_name), @@ -54,6 +58,7 @@ void lfrfid_scene_raw_read_on_enter(void* context) { lfrfid_read_callback, app); + furi_timer_start(state->timer, RAW_READ_TIME_MS); notification_message(app->notifications, &sequence_blink_start_cyan); state->is_psk = false; @@ -70,41 +75,53 @@ bool lfrfid_scene_raw_read_on_event(void* context, SceneManagerEvent event) { furi_assert(state); if(event.type == SceneManagerEventTypeCustom) { - if(event.event == LfRfidEventReadError) { - consumed = true; - state->error = true; - popup_set_header( - popup, "Reading\nRAW RFID\nFile error", 89, 30, AlignCenter, AlignTop); - notification_message(app->notifications, &sequence_blink_start_red); + if(event.event == LfRfidEventReadError || event.event == LfRfidEventReadOverrun) { furi_timer_stop(state->timer); + + popup_set_icon(popup, 83, 22, &I_WarningDolphinFlip_45x42); + popup_set_header(popup, "RAW Reading error!", 64, 0, AlignCenter, AlignTop); + popup_set_text( + popup, "This may be\ncaused by SD\ncard issues", 0, 13, AlignLeft, AlignTop); + + notification_message(app->notifications, &sequence_blink_start_red); + state->error = true; + } else if(event.event == LfRfidEventReadDone) { - consumed = true; if(!state->error) { if(state->is_psk) { notification_message(app->notifications, &sequence_success); scene_manager_next_scene(app->scene_manager, LfRfidSceneRawSuccess); + } else { - popup_set_header( - popup, "Reading\nRAW RFID\nPSK", 89, 30, AlignCenter, AlignTop); - notification_message(app->notifications, &sequence_blink_start_yellow); lfrfid_worker_stop(app->lfworker); + lfrfid_worker_stop_thread(app->lfworker); + + state->is_psk = true; + furi_string_printf( state->string_file_name, "%s/%s%s", LFRFID_SD_FOLDER, furi_string_get_cstr(app->raw_file_name), LFRFID_APP_RAW_PSK_EXTENSION); + + lfrfid_worker_start_thread(app->lfworker); lfrfid_worker_read_raw_start( app->lfworker, furi_string_get_cstr(state->string_file_name), LFRFIDWorkerReadTypePSKOnly, lfrfid_read_callback, app); - furi_timer_start(state->timer, RAW_READ_TIME); - state->is_psk = true; + + furi_timer_start(state->timer, RAW_READ_TIME_MS); + + popup_set_header(popup, "Reading PSK", 91, 16, AlignCenter, AlignTop); + notification_message(app->notifications, &sequence_blink_start_yellow); } } } + + consumed = true; } return consumed; @@ -115,12 +132,13 @@ void lfrfid_scene_raw_read_on_exit(void* context) { LfRfidReadRawState* state = (LfRfidReadRawState*)scene_manager_get_scene_state(app->scene_manager, LfRfidSceneRawRead); - notification_message(app->notifications, &sequence_blink_stop); - popup_reset(app->popup); lfrfid_worker_stop(app->lfworker); lfrfid_worker_stop_thread(app->lfworker); - furi_timer_free(state->timer); + furi_timer_free(state->timer); furi_string_free(state->string_file_name); free(state); + + popup_reset(app->popup); + notification_message(app->notifications, &sequence_blink_stop); } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_raw_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_raw_success.c index 09a005298f6..3fca9e3f128 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_raw_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_raw_success.c @@ -4,16 +4,20 @@ void lfrfid_scene_raw_success_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - widget_add_button_element(widget, GuiButtonTypeCenter, "OK", lfrfid_widget_callback, app); - - widget_add_string_multiline_element( + widget_add_text_box_element( widget, 0, - 1, + 0, + 128, + 64, AlignLeft, AlignTop, - FontSecondary, - "RAW RFID read success!\nNow you can analyze files\nOr send them to developers"); + "\e#RAW RFID Read Success\e#\n" + "Now you can analyze files or\n" + "send them to developers", + false); + + widget_add_button_element(widget, GuiButtonTypeCenter, "OK", lfrfid_widget_callback, app); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); } @@ -24,12 +28,16 @@ bool lfrfid_scene_raw_success_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - consumed = true; if(event.event == GuiButtonTypeCenter) { scene_manager_search_and_switch_to_previous_scene( scene_manager, LfRfidSceneExtraActions); } + consumed = true; + + } else if(event.type == SceneManagerEventTypeBack) { + consumed = true; } + return consumed; } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c b/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c index 36f0d6d93a3..22b083c76bf 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_read_key_menu.c @@ -48,6 +48,9 @@ bool lfrfid_scene_read_key_menu_on_event(void* context, SceneManagerEvent event) consumed = true; } scene_manager_set_scene_state(app->scene_manager, LfRfidSceneReadKeyMenu, event.event); + + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneReadKeyMenu, 0); } return consumed; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c index b83ef4a3992..dbd3192294c 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_read_success.c @@ -1,54 +1,53 @@ #include "../lfrfid_i.h" +#define LFRFID_SCENE_READ_SUCCESS_MAX_HEX_WIDTH (7UL) + void lfrfid_scene_read_success_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; + FuriString* display_text = furi_string_alloc(); - FuriString* tmp_string; - tmp_string = furi_string_alloc(); + const char* protocol = protocol_dict_get_name(app->dict, app->protocol_id); + const char* manufacturer = protocol_dict_get_manufacturer(app->dict, app->protocol_id); - widget_add_button_element(widget, GuiButtonTypeLeft, "Retry", lfrfid_widget_callback, app); - widget_add_button_element(widget, GuiButtonTypeRight, "More", lfrfid_widget_callback, app); + if(strcasecmp(protocol, manufacturer) != 0 && strcasecmp(manufacturer, "N/A") != 0) { + furi_string_printf(display_text, "\e#%s %s\e#", manufacturer, protocol); + } else { + furi_string_printf(display_text, "\e#%s\e#", protocol); + } + + furi_string_cat(display_text, "\nHex: "); + + const size_t data_size = protocol_dict_get_data_size(app->dict, app->protocol_id); + uint8_t* data = malloc(data_size); - furi_string_printf( - tmp_string, - "%s[%s]", - protocol_dict_get_name(app->dict, app->protocol_id), - protocol_dict_get_manufacturer(app->dict, app->protocol_id)); - - widget_add_string_element( - widget, 0, 2, AlignLeft, AlignTop, FontPrimary, furi_string_get_cstr(tmp_string)); - - furi_string_reset(tmp_string); - size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); - uint8_t* data = (uint8_t*)malloc(size); - protocol_dict_get_data(app->dict, app->protocol_id, data, size); - for(uint8_t i = 0; i < size; i++) { - if(i >= 9) { - furi_string_cat_printf(tmp_string, ".."); + protocol_dict_get_data(app->dict, app->protocol_id, data, data_size); + + for(size_t i = 0; i < data_size; i++) { + if(i == LFRFID_SCENE_READ_SUCCESS_MAX_HEX_WIDTH) { + furi_string_cat(display_text, " ..."); break; - } else { - if(i != 0) { - furi_string_cat_printf(tmp_string, " "); - } - furi_string_cat_printf(tmp_string, "%02X", data[i]); } + + furi_string_cat_printf(display_text, "%s%02X", i != 0 ? " " : "", data[i]); } + free(data); - FuriString* render_data; - render_data = furi_string_alloc(); - protocol_dict_render_brief_data(app->dict, render_data, app->protocol_id); - furi_string_cat_printf(tmp_string, "\r\n%s", furi_string_get_cstr(render_data)); - furi_string_free(render_data); + FuriString* rendered_data = furi_string_alloc(); + protocol_dict_render_brief_data(app->dict, rendered_data, app->protocol_id); + furi_string_cat_printf(display_text, "\n%s", furi_string_get_cstr(rendered_data)); + furi_string_free(rendered_data); - widget_add_string_multiline_element( - widget, 0, 16, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); + widget_add_text_box_element( + widget, 0, 0, 128, 52, AlignLeft, AlignTop, furi_string_get_cstr(display_text), true); + widget_add_button_element(widget, GuiButtonTypeLeft, "Retry", lfrfid_widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeRight, "More", lfrfid_widget_callback, app); notification_message_block(app->notifications, &sequence_set_green_255); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - furi_string_free(tmp_string); + furi_string_free(display_text); } bool lfrfid_scene_read_success_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_retry_confirm.c b/applications/main/lfrfid/scenes/lfrfid_scene_retry_confirm.c index ddac3e8ba55..41ff9afed90 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_retry_confirm.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_retry_confirm.c @@ -4,12 +4,11 @@ void lfrfid_scene_retry_confirm_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - widget_add_button_element(widget, GuiButtonTypeLeft, "Exit", lfrfid_widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeLeft, "Retry", lfrfid_widget_callback, app); widget_add_button_element(widget, GuiButtonTypeRight, "Stay", lfrfid_widget_callback, app); + widget_add_string_element(widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Retry Reading?"); widget_add_string_element( - widget, 64, 19, AlignCenter, AlignBottom, FontPrimary, "Retry Reading?"); - widget_add_string_element( - widget, 64, 29, AlignCenter, AlignBottom, FontSecondary, "All unsaved data will be lost!"); + widget, 64, 13, AlignCenter, AlignTop, FontSecondary, "All unsaved data will be lost"); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c index 2f5d5ae9ff8..4eb21e9421f 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_save_success.c @@ -21,16 +21,9 @@ bool lfrfid_scene_save_success_on_event(void* context, SceneManagerEvent event) LfRfid* app = context; bool consumed = false; - const uint32_t prev_scenes[] = {LfRfidSceneReadKeyMenu, LfRfidSceneSelectKey}; - - if((event.type == SceneManagerEventTypeBack) || - ((event.type == SceneManagerEventTypeCustom) && (event.event == LfRfidEventPopupClosed))) { - bool result = scene_manager_search_and_switch_to_previous_scene_one_of( - app->scene_manager, prev_scenes, COUNT_OF(prev_scenes)); - if(!result) { - scene_manager_search_and_switch_to_another_scene( - app->scene_manager, LfRfidSceneSelectKey); - } + if(event.type == SceneManagerEventTypeBack || event.type == SceneManagerEventTypeCustom) { + // Always return to SceneSelectKey from here + scene_manager_search_and_switch_to_another_scene(app->scene_manager, LfRfidSceneSelectKey); consumed = true; } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c b/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c index 3f1c2d400e4..a057b7a71a9 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_saved_info.c @@ -4,38 +4,42 @@ void lfrfid_scene_saved_info_on_enter(void* context) { LfRfid* app = context; Widget* widget = app->widget; - FuriString* tmp_string; - tmp_string = furi_string_alloc(); - - furi_string_printf( - tmp_string, - "%s [%s]\r\n", - furi_string_get_cstr(app->file_name), - protocol_dict_get_name(app->dict, app->protocol_id)); - - size_t size = protocol_dict_get_data_size(app->dict, app->protocol_id); - uint8_t* data = (uint8_t*)malloc(size); - protocol_dict_get_data(app->dict, app->protocol_id, data, size); - for(uint8_t i = 0; i < size; i++) { - if(i != 0) { - furi_string_cat_printf(tmp_string, " "); - } - - furi_string_cat_printf(tmp_string, "%02X", data[i]); + FuriString* display_text = furi_string_alloc(); + + furi_string_printf(display_text, "Name: %s\n", furi_string_get_cstr(app->file_name)); + + const char* protocol = protocol_dict_get_name(app->dict, app->protocol_id); + const char* manufacturer = protocol_dict_get_manufacturer(app->dict, app->protocol_id); + + if(strcasecmp(protocol, manufacturer) != 0 && strcasecmp(manufacturer, "N/A") != 0) { + furi_string_cat_printf(display_text, "\e#%s %s", manufacturer, protocol); + } else { + furi_string_cat_printf(display_text, "\e#%s", protocol); } + + furi_string_cat(display_text, "\nHex: "); + + const size_t data_size = protocol_dict_get_data_size(app->dict, app->protocol_id); + uint8_t* data = malloc(data_size); + + protocol_dict_get_data(app->dict, app->protocol_id, data, data_size); + + for(size_t i = 0; i < data_size; i++) { + furi_string_cat_printf(display_text, "%s%02X", i != 0 ? " " : "", data[i]); + } + free(data); - FuriString* render_data; - render_data = furi_string_alloc(); - protocol_dict_render_data(app->dict, render_data, app->protocol_id); - furi_string_cat_printf(tmp_string, "\r\n%s", furi_string_get_cstr(render_data)); - furi_string_free(render_data); + FuriString* rendered_data; + rendered_data = furi_string_alloc(); + protocol_dict_render_data(app->dict, rendered_data, app->protocol_id); + furi_string_cat_printf(display_text, "\n%s", furi_string_get_cstr(rendered_data)); + furi_string_free(rendered_data); - widget_add_string_multiline_element( - widget, 0, 1, AlignLeft, AlignTop, FontSecondary, furi_string_get_cstr(tmp_string)); + widget_add_text_scroll_element(widget, 0, 0, 128, 64, furi_string_get_cstr(display_text)); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewWidget); - furi_string_free(tmp_string); + furi_string_free(display_text); } bool lfrfid_scene_saved_info_on_event(void* context, SceneManagerEvent event) { diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_saved_key_menu.c b/applications/main/lfrfid/scenes/lfrfid_scene_saved_key_menu.c index 206074e9b08..f687cd0a294 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_saved_key_menu.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_saved_key_menu.c @@ -59,6 +59,9 @@ bool lfrfid_scene_saved_key_menu_on_event(void* context, SceneManagerEvent event consumed = true; } scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSavedKeyMenu, event.event); + + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneSavedKeyMenu, 0); } return consumed; diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_select_key.c b/applications/main/lfrfid/scenes/lfrfid_scene_select_key.c index 2a9cc1c634a..505985c26a3 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_select_key.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_select_key.c @@ -6,7 +6,9 @@ void lfrfid_scene_select_key_on_enter(void* context) { if(lfrfid_load_key_from_file_select(app)) { scene_manager_next_scene(app->scene_manager, LfRfidSceneSavedKeyMenu); } else { - scene_manager_previous_scene(app->scene_manager); + // Always select "Saved" menu item when returning from this scene + scene_manager_set_scene_state(app->scene_manager, LfRfidSceneStart, LfRfidMenuIndexSaved); + scene_manager_search_and_switch_to_previous_scene(app->scene_manager, LfRfidSceneStart); } } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_start.c b/applications/main/lfrfid/scenes/lfrfid_scene_start.c index 8a01fc707b1..5d0e6112a69 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_start.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_start.c @@ -1,13 +1,6 @@ #include "../lfrfid_i.h" #include -typedef enum { - SubmenuIndexRead, - SubmenuIndexSaved, - SubmenuIndexAddManually, - SubmenuIndexExtraActions, -} SubmenuIndex; - static void lfrfid_scene_start_submenu_callback(void* context, uint32_t index) { LfRfid* app = context; @@ -18,15 +11,20 @@ void lfrfid_scene_start_on_enter(void* context) { LfRfid* app = context; Submenu* submenu = app->submenu; - submenu_add_item(submenu, "Read", SubmenuIndexRead, lfrfid_scene_start_submenu_callback, app); submenu_add_item( - submenu, "Saved", SubmenuIndexSaved, lfrfid_scene_start_submenu_callback, app); + submenu, "Read", LfRfidMenuIndexRead, lfrfid_scene_start_submenu_callback, app); submenu_add_item( - submenu, "Add Manually", SubmenuIndexAddManually, lfrfid_scene_start_submenu_callback, app); + submenu, "Saved", LfRfidMenuIndexSaved, lfrfid_scene_start_submenu_callback, app); + submenu_add_item( + submenu, + "Add Manually", + LfRfidMenuIndexAddManually, + lfrfid_scene_start_submenu_callback, + app); submenu_add_item( submenu, "Extra Actions", - SubmenuIndexExtraActions, + LfRfidMenuIndexExtraActions, lfrfid_scene_start_submenu_callback, app); @@ -46,26 +44,28 @@ bool lfrfid_scene_start_on_event(void* context, SceneManagerEvent event) { bool consumed = false; if(event.type == SceneManagerEventTypeCustom) { - if(event.event == SubmenuIndexRead) { - scene_manager_set_scene_state(app->scene_manager, LfRfidSceneStart, SubmenuIndexRead); + if(event.event == LfRfidMenuIndexRead) { + scene_manager_set_scene_state( + app->scene_manager, LfRfidSceneStart, LfRfidMenuIndexRead); scene_manager_next_scene(app->scene_manager, LfRfidSceneRead); dolphin_deed(DolphinDeedRfidRead); consumed = true; - } else if(event.event == SubmenuIndexSaved) { + } else if(event.event == LfRfidMenuIndexSaved) { // Like in the other apps, explicitly save the scene state // in each branch in case the user cancels loading a file. - scene_manager_set_scene_state(app->scene_manager, LfRfidSceneStart, SubmenuIndexSaved); + scene_manager_set_scene_state( + app->scene_manager, LfRfidSceneStart, LfRfidMenuIndexSaved); furi_string_set(app->file_path, LFRFID_APP_FOLDER); scene_manager_next_scene(app->scene_manager, LfRfidSceneSelectKey); consumed = true; - } else if(event.event == SubmenuIndexAddManually) { + } else if(event.event == LfRfidMenuIndexAddManually) { scene_manager_set_scene_state( - app->scene_manager, LfRfidSceneStart, SubmenuIndexAddManually); + app->scene_manager, LfRfidSceneStart, LfRfidMenuIndexAddManually); scene_manager_next_scene(app->scene_manager, LfRfidSceneSaveType); consumed = true; - } else if(event.event == SubmenuIndexExtraActions) { + } else if(event.event == LfRfidMenuIndexExtraActions) { scene_manager_set_scene_state( - app->scene_manager, LfRfidSceneStart, SubmenuIndexExtraActions); + app->scene_manager, LfRfidSceneStart, LfRfidMenuIndexExtraActions); scene_manager_next_scene(app->scene_manager, LfRfidSceneExtraActions); consumed = true; } diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_write.c b/applications/main/lfrfid/scenes/lfrfid_scene_write.c index f6e762e4d8d..55973d09d72 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_write.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_write.c @@ -21,19 +21,19 @@ void lfrfid_scene_write_on_enter(void* context) { LfRfid* app = context; Popup* popup = app->popup; - popup_set_header(popup, "Writing", 89, 30, AlignCenter, AlignTop); + popup_set_icon(popup, 0, 8, &I_NFC_manual_60x50); + popup_set_header(popup, "Writing", 94, 16, AlignCenter, AlignTop); + if(!furi_string_empty(app->file_name)) { - popup_set_text(popup, furi_string_get_cstr(app->file_name), 89, 43, AlignCenter, AlignTop); + popup_set_text(popup, furi_string_get_cstr(app->file_name), 94, 29, AlignCenter, AlignTop); } else { - popup_set_text( - popup, - protocol_dict_get_name(app->dict, app->protocol_id), - 89, - 43, - AlignCenter, - AlignTop); + snprintf( + app->text_store, + LFRFID_TEXT_STORE_SIZE, + "Unsaved\n%s", + protocol_dict_get_name(app->dict, app->protocol_id)); + popup_set_text(popup, app->text_store, 94, 29, AlignCenter, AlignTop); } - popup_set_icon(popup, 0, 3, &I_RFIDDolphinSend_97x61); view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidViewPopup); @@ -66,12 +66,14 @@ bool lfrfid_scene_write_on_event(void* context, SceneManagerEvent event) { (event.event == LfRfidEventWriteFobCannotBeWritten) || (event.event == LfRfidEventWriteTooLongToWrite)) { popup_set_icon(popup, 83, 22, &I_WarningDolphinFlip_45x42); - popup_set_header(popup, "Still trying to write...", 64, 3, AlignCenter, AlignTop); + popup_set_header(popup, "Still Trying to Write...", 64, 0, AlignCenter, AlignTop); popup_set_text( popup, - "Make sure this\ncard is writable\nand not\nprotected.", - 3, - 17, + "Make sure this\n" + "card is writable\n" + "and not protected", + 0, + 13, AlignLeft, AlignTop); notification_message(app->notifications, &sequence_blink_start_yellow); diff --git a/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c b/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c index 78ba4813701..cc407bdcc25 100644 --- a/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c +++ b/applications/main/lfrfid/scenes/lfrfid_scene_write_success.c @@ -19,12 +19,12 @@ bool lfrfid_scene_write_success_on_event(void* context, SceneManagerEvent event) LfRfid* app = context; bool consumed = false; - const uint32_t prev_scenes[] = {LfRfidSceneReadKeyMenu, LfRfidSceneSelectKey}; - - if((event.type == SceneManagerEventTypeBack) || - ((event.type == SceneManagerEventTypeCustom) && (event.event == LfRfidEventPopupClosed))) { - scene_manager_search_and_switch_to_previous_scene_one_of( - app->scene_manager, prev_scenes, COUNT_OF(prev_scenes)); + if(event.type == SceneManagerEventTypeBack || event.type == SceneManagerEventTypeCustom) { + if(!scene_manager_search_and_switch_to_previous_scene( + app->scene_manager, LfRfidSceneReadKeyMenu)) { + scene_manager_search_and_switch_to_another_scene( + app->scene_manager, LfRfidSceneSelectKey); + } consumed = true; } diff --git a/applications/main/nfc/helpers/protocol_support/st25tb/st25tb_render.c b/applications/main/nfc/helpers/protocol_support/st25tb/st25tb_render.c index 6764f99a3df..0b5cb08d868 100644 --- a/applications/main/nfc/helpers/protocol_support/st25tb/st25tb_render.c +++ b/applications/main/nfc/helpers/protocol_support/st25tb/st25tb_render.c @@ -13,15 +13,16 @@ void nfc_render_st25tb_info( } if(format_type == NfcProtocolFormatTypeFull) { - furi_string_cat_printf(str, "\nSys. OTP: %08lX", __bswap32(data->system_otp_block)); + furi_string_cat_printf( + str, "\nSys. OTP: %08lX", (uint32_t)__bswap32(data->system_otp_block)); furi_string_cat_printf(str, "\n::::::::::::::::::::::[Blocks]::::::::::::::::::::::"); for(size_t i = 0; i < st25tb_get_block_count(data->type); i += 2) { furi_string_cat_printf( str, "\n %02X %08lX %08lX", i, - __bswap32(data->blocks[i]), - __bswap32(data->blocks[i + 1])); + (uint32_t)__bswap32(data->blocks[i]), + (uint32_t)__bswap32(data->blocks[i + 1])); } } } diff --git a/applications/services/gui/elements.c b/applications/services/gui/elements.c index d488cbfc6ec..06b63fd902f 100644 --- a/applications/services/gui/elements.c +++ b/applications/services/gui/elements.c @@ -746,10 +746,9 @@ void elements_text_box( } line[line_num].y = total_height_min; line_num++; - if(text[i + 1]) { + if(!full_text_processed) { line[line_num].text = &text[i + 1]; } - line_leading_min = font_params->leading_min; line_height = font_params->height; line_descender = font_params->descender; @@ -792,29 +791,32 @@ void elements_text_box( for(size_t i = 0; i < line_num; i++) { for(size_t j = 0; j < line[i].len; j++) { // Process format symbols - if(line[i].text[j] == ELEMENTS_BOLD_MARKER) { - if(bold) { - current_font = FontSecondary; - } else { - current_font = FontPrimary; + if(line[i].text[j] == '\e' && j < line[i].len - 1) { + ++j; + if(line[i].text[j] == ELEMENTS_BOLD_MARKER) { + if(bold) { + current_font = FontSecondary; + } else { + current_font = FontPrimary; + } + canvas_set_font(canvas, current_font); + bold = !bold; + continue; } - canvas_set_font(canvas, current_font); - bold = !bold; - continue; - } - if(line[i].text[j] == ELEMENTS_MONO_MARKER) { - if(mono) { - current_font = FontSecondary; - } else { - current_font = FontKeyboard; + if(line[i].text[j] == ELEMENTS_MONO_MARKER) { + if(mono) { + current_font = FontSecondary; + } else { + current_font = FontKeyboard; + } + canvas_set_font(canvas, current_font); + mono = !mono; + continue; + } + if(line[i].text[j] == ELEMENTS_INVERSE_MARKER) { + inverse = !inverse; + continue; } - canvas_set_font(canvas, current_font); - mono = !mono; - continue; - } - if(line[i].text[j] == ELEMENTS_INVERSE_MARKER) { - inverse = !inverse; - continue; } if(inverse) { canvas_draw_box( diff --git a/lib/lfrfid/protocols/protocol_awid.c b/lib/lfrfid/protocols/protocol_awid.c index 914f2f01b73..b3e92245e42 100644 --- a/lib/lfrfid/protocols/protocol_awid.c +++ b/lib/lfrfid/protocols/protocol_awid.c @@ -164,7 +164,8 @@ void protocol_awid_render_data(ProtocolAwid* protocol, FuriString* result) { uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - furi_string_cat_printf(result, "Format: %d\r\n", format_length); + furi_string_printf(result, "Format: %hhu\n", format_length); + if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 9); @@ -172,13 +173,17 @@ void protocol_awid_render_data(ProtocolAwid* protocol, FuriString* result) { uint16_t card_id; bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 17); bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 25); - furi_string_cat_printf(result, "Facility: %d\r\n", facility); - furi_string_cat_printf(result, "Card: %d", card_id); + furi_string_cat_printf( + result, + "FC: %hhu\n" + "Card: %hu", + facility, + card_id); } else { // print 66 bits as hex furi_string_cat_printf(result, "Data: "); for(size_t i = 0; i < AWID_DECODED_DATA_SIZE; i++) { - furi_string_cat_printf(result, "%02X", decoded_data[i]); + furi_string_cat_printf(result, "%02hhX", decoded_data[i]); } } }; @@ -187,7 +192,8 @@ void protocol_awid_render_brief_data(ProtocolAwid* protocol, FuriString* result) uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - furi_string_cat_printf(result, "Format: %d\r\n", format_length); + furi_string_printf(result, "Format: %hhu", format_length); + if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 9); @@ -195,9 +201,14 @@ void protocol_awid_render_brief_data(ProtocolAwid* protocol, FuriString* result) uint16_t card_id; bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 17); bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 25); - furi_string_cat_printf(result, "ID: %03u,%05u", facility, card_id); + furi_string_cat_printf( + result, + "; FC: %hhu\n" + "Card: %hu", + facility, + card_id); } else { - furi_string_cat_printf(result, "Data: unknown"); + furi_string_cat(result, "\nData: Unknown"); } }; @@ -252,4 +263,4 @@ const ProtocolBase protocol_awid = { .render_data = (ProtocolRenderData)protocol_awid_render_data, .render_brief_data = (ProtocolRenderData)protocol_awid_render_brief_data, .write_data = (ProtocolWriteData)protocol_awid_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_em4100.c b/lib/lfrfid/protocols/protocol_em4100.c index 38452007f3b..055d06d8684 100644 --- a/lib/lfrfid/protocols/protocol_em4100.c +++ b/lib/lfrfid/protocols/protocol_em4100.c @@ -330,7 +330,8 @@ void protocol_em4100_render_data(ProtocolEM4100* protocol, FuriString* result) { uint8_t* data = protocol->data; furi_string_printf( result, - "FC: %03u, Card: %05u (RF/%u)", + "FC: %03u\n" + "Card: %05hu (RF/%hhu)", data[2], (uint16_t)((data[3] << 8) | (data[4])), protocol->clock_per_bit); diff --git a/lib/lfrfid/protocols/protocol_fdx_a.c b/lib/lfrfid/protocols/protocol_fdx_a.c index 667c4f88db4..f7852eb1013 100644 --- a/lib/lfrfid/protocols/protocol_fdx_a.c +++ b/lib/lfrfid/protocols/protocol_fdx_a.c @@ -217,14 +217,10 @@ void protocol_fdx_a_render_data(ProtocolFDXA* protocol, FuriString* result) { furi_string_printf( result, - "ID: %02X%02X%02X%02X%02X\r\n" - "Parity: %s", - data[0], - data[1], - data[2], - data[3], - data[4], - parity_sum == 0 ? "+" : "-"); + "ID: %010llX\n" + "Parity: %c", + bit_lib_get_bits_64(data, 0, 40), + parity_sum == 0 ? '+' : '-'); }; const ProtocolBase protocol_fdx_a = { @@ -249,4 +245,4 @@ const ProtocolBase protocol_fdx_a = { .render_data = (ProtocolRenderData)protocol_fdx_a_render_data, .render_brief_data = (ProtocolRenderData)protocol_fdx_a_render_data, .write_data = (ProtocolWriteData)protocol_fdx_a_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_fdx_b.c b/lib/lfrfid/protocols/protocol_fdx_b.c index 18ccfa70294..a5af855e484 100644 --- a/lib/lfrfid/protocols/protocol_fdx_b.c +++ b/lib/lfrfid/protocols/protocol_fdx_b.c @@ -288,21 +288,33 @@ void protocol_fdx_b_render_data(ProtocolFDXB* protocol, FuriString* result) { uint8_t replacement_number = bit_lib_get_bits(protocol->data, 60, 3); bool animal_flag = bit_lib_get_bit(protocol->data, 63); - furi_string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); - furi_string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); + furi_string_printf( + result, + "ID: %03hu-%012llu\n" + "Country Code: %hu\n" + "Temperature: ", + country_code, + national_code, + country_code); float temperature; if(protocol_fdx_b_get_temp(protocol->data, &temperature)) { - float temperature_c = (temperature - 32) / 1.8; - furi_string_cat_printf( - result, "T: %.2fF, %.2fC\r\n", (double)temperature, (double)temperature_c); + if(furi_hal_rtc_get_locale_units() == FuriHalRtcLocaleUnitsMetric) { + float temperature_c = (temperature - 32.0f) / 1.8f; + furi_string_cat_printf(result, "%.2fC", (double)temperature_c); + } else { + furi_string_cat_printf(result, "%.2fF", (double)temperature); + } } else { - furi_string_cat_printf(result, "T: ---\r\n"); + furi_string_cat(result, "---"); } furi_string_cat_printf( result, - "Bits: %X-%X-%X-%X-%X", + "\n" + "Animal: %s\n" + "Bits: %hhX-%hhX-%hhX-%hhX-%hhX", + animal_flag ? "Yes" : "No", block_status, rudi_bit, reserved, @@ -317,21 +329,24 @@ void protocol_fdx_b_render_brief_data(ProtocolFDXB* protocol, FuriString* result // 10 bit of country code uint16_t country_code = protocol_fdx_b_get_country_code(protocol->data); - bool animal_flag = bit_lib_get_bit(protocol->data, 63); - - furi_string_printf(result, "ID: %03u-%012llu\r\n", country_code, national_code); - furi_string_cat_printf(result, "Animal: %s, ", animal_flag ? "Yes" : "No"); + furi_string_printf( + result, + "ID: %03hu-%012llu\n" + "Country: %hu; Temp.: ", + country_code, + national_code, + country_code); float temperature; if(protocol_fdx_b_get_temp(protocol->data, &temperature)) { if(furi_hal_rtc_get_locale_units() == FuriHalRtcLocaleUnitsMetric) { float temperature_c = (temperature - 32.0f) / 1.8f; - furi_string_cat_printf(result, "T: %.2fC", (double)temperature_c); + furi_string_cat_printf(result, "%.2fC", (double)temperature_c); } else { - furi_string_cat_printf(result, "T: %.2fF", (double)temperature); + furi_string_cat_printf(result, "%.2fF", (double)temperature); } } else { - furi_string_cat_printf(result, "T: ---"); + furi_string_cat(result, "---"); } }; @@ -380,4 +395,4 @@ const ProtocolBase protocol_fdx_b = { .render_data = (ProtocolRenderData)protocol_fdx_b_render_data, .render_brief_data = (ProtocolRenderData)protocol_fdx_b_render_brief_data, .write_data = (ProtocolWriteData)protocol_fdx_b_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_gallagher.c b/lib/lfrfid/protocols/protocol_gallagher.c index 15bebb90bdb..b00c14acd16 100644 --- a/lib/lfrfid/protocols/protocol_gallagher.c +++ b/lib/lfrfid/protocols/protocol_gallagher.c @@ -268,17 +268,44 @@ bool protocol_gallagher_write_data(ProtocolGallagher* protocol, void* data) { return result; }; -void protocol_gallagher_render_data(ProtocolGallagher* protocol, FuriString* result) { - UNUSED(protocol); - uint8_t rc = bit_lib_get_bits(protocol->data, 0, 4); - uint8_t il = bit_lib_get_bits(protocol->data, 4, 4); +static void protocol_gallagher_render_data_internal( + ProtocolGallagher* protocol, + FuriString* result, + bool brief) { + uint8_t region = bit_lib_get_bits(protocol->data, 0, 4); + uint8_t issue_level = bit_lib_get_bits(protocol->data, 4, 4); uint32_t fc = bit_lib_get_bits_32(protocol->data, 8, 24); uint32_t card_id = bit_lib_get_bits_32(protocol->data, 32, 32); - furi_string_cat_printf(result, "Region: %u, Issue Level: %u\r\n", rc, il); - furi_string_cat_printf(result, "FC: %lu, C: %lu\r\n", fc, card_id); + if(brief) { + furi_string_printf( + result, + "FC: %lu\n" + "Card: %lu", + fc, + card_id); + } else { + furi_string_printf( + result, + "FC: %lu\n" + "Card: %lu\n" + "Region: %u\n" + "Issue Level: %u", + fc, + card_id, + region, + issue_level); + } }; +void protocol_gallagher_render_data(ProtocolGallagher* protocol, FuriString* result) { + protocol_gallagher_render_data_internal(protocol, result, false); +} + +void protocol_gallagher_render_brief_data(ProtocolGallagher* protocol, FuriString* result) { + protocol_gallagher_render_data_internal(protocol, result, true); +} + const ProtocolBase protocol_gallagher = { .name = "Gallagher", .manufacturer = "Gallagher", @@ -299,6 +326,6 @@ const ProtocolBase protocol_gallagher = { .yield = (ProtocolEncoderYield)protocol_gallagher_encoder_yield, }, .render_data = (ProtocolRenderData)protocol_gallagher_render_data, - .render_brief_data = (ProtocolRenderData)protocol_gallagher_render_data, + .render_brief_data = (ProtocolRenderData)protocol_gallagher_render_brief_data, .write_data = (ProtocolWriteData)protocol_gallagher_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_h10301.c b/lib/lfrfid/protocols/protocol_h10301.c index 2d7a3e669e2..6c6d5771ac8 100644 --- a/lib/lfrfid/protocols/protocol_h10301.c +++ b/lib/lfrfid/protocols/protocol_h10301.c @@ -359,8 +359,8 @@ void protocol_h10301_render_data(ProtocolH10301* protocol, FuriString* result) { uint8_t* data = protocol->data; furi_string_printf( result, - "FC: %u\r\n" - "Card: %u", + "FC: %hhu\n" + "Card: %hu", data[0], (uint16_t)((data[1] << 8) | (data[2]))); }; @@ -387,4 +387,4 @@ const ProtocolBase protocol_h10301 = { .render_data = (ProtocolRenderData)protocol_h10301_render_data, .render_brief_data = (ProtocolRenderData)protocol_h10301_render_data, .write_data = (ProtocolWriteData)protocol_h10301_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_hid_ex_generic.c b/lib/lfrfid/protocols/protocol_hid_ex_generic.c index 194e153289e..efc7a5190ca 100644 --- a/lib/lfrfid/protocols/protocol_hid_ex_generic.c +++ b/lib/lfrfid/protocols/protocol_hid_ex_generic.c @@ -193,9 +193,13 @@ bool protocol_hid_ex_generic_write_data(ProtocolHIDEx* protocol, void* data) { }; void protocol_hid_ex_generic_render_data(ProtocolHIDEx* protocol, FuriString* result) { - // TODO FL-3518: parser and render functions UNUSED(protocol); - furi_string_printf(result, "Generic HID Extended\r\nData: Unknown"); + + // TODO FL-3518: parser and render functions + furi_string_set( + result, + "Type: Generic HID Extended\n" + "Data: Unknown"); }; const ProtocolBase protocol_hid_ex_generic = { @@ -220,4 +224,4 @@ const ProtocolBase protocol_hid_ex_generic = { .render_data = (ProtocolRenderData)protocol_hid_ex_generic_render_data, .render_brief_data = (ProtocolRenderData)protocol_hid_ex_generic_render_data, .write_data = (ProtocolWriteData)protocol_hid_ex_generic_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_hid_generic.c b/lib/lfrfid/protocols/protocol_hid_generic.c index e24b5ade71d..1a95288855a 100644 --- a/lib/lfrfid/protocols/protocol_hid_generic.c +++ b/lib/lfrfid/protocols/protocol_hid_generic.c @@ -245,7 +245,7 @@ void protocol_hid_generic_render_data(ProtocolHID* protocol, FuriString* result) if(protocol_size == HID_PROTOCOL_SIZE_UNKNOWN) { furi_string_printf( result, - "Generic HID Proximity\r\n" + "Generic HID Proximity\n" "Data: %02X%02X%02X%02X%02X%X", protocol->data[0], protocol->data[1], @@ -256,7 +256,7 @@ void protocol_hid_generic_render_data(ProtocolHID* protocol, FuriString* result) } else { furi_string_printf( result, - "%hhu-bit HID Proximity\r\n" + "%hhu-bit HID Proximity\n" "Data: ", protocol_size); protocol_hid_generic_string_cat_protocol_bits(protocol, protocol_size, result); diff --git a/lib/lfrfid/protocols/protocol_idteck.c b/lib/lfrfid/protocols/protocol_idteck.c index 6de8de2060f..2075576bae8 100644 --- a/lib/lfrfid/protocols/protocol_idteck.c +++ b/lib/lfrfid/protocols/protocol_idteck.c @@ -205,26 +205,16 @@ static uint32_t get_card(const uint8_t* data) { return cn; } -void protocol_idteck_render_data_internal(ProtocolIdteck* protocol, FuriString* result, bool brief) { +void protocol_idteck_render_data(ProtocolIdteck* protocol, FuriString* result) { const uint32_t fc = get_fc(protocol->data); const uint32_t card = get_card(protocol->data); - if(brief) { - furi_string_printf(result, "FC: %08lX\r\nCard: %08lX", fc, card); - } else { - furi_string_printf( - result, - "FC: %08lX\r\n" - "Card: %08lX\r\n", - fc, - card); - } -} -void protocol_idteck_render_data(ProtocolIdteck* protocol, FuriString* result) { - protocol_idteck_render_data_internal(protocol, result, false); -} -void protocol_idteck_render_brief_data(ProtocolIdteck* protocol, FuriString* result) { - protocol_idteck_render_data_internal(protocol, result, true); + furi_string_printf( + result, + "FC: %08lX\n" + "Card: %08lX", + fc, + card); } bool protocol_idteck_write_data(ProtocolIdteck* protocol, void* data) { @@ -264,6 +254,6 @@ const ProtocolBase protocol_idteck = { .yield = (ProtocolEncoderYield)protocol_idteck_encoder_yield, }, .render_data = (ProtocolRenderData)protocol_idteck_render_data, - .render_brief_data = (ProtocolRenderData)protocol_idteck_render_brief_data, + .render_brief_data = (ProtocolRenderData)protocol_idteck_render_data, .write_data = (ProtocolWriteData)protocol_idteck_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_indala26.c b/lib/lfrfid/protocols/protocol_indala26.c index 7ce83af7fa4..893361abb2c 100644 --- a/lib/lfrfid/protocols/protocol_indala26.c +++ b/lib/lfrfid/protocols/protocol_indala26.c @@ -289,22 +289,21 @@ void protocol_indala26_render_data_internal( if(brief) { furi_string_printf( result, - "FC: %u\r\nCard: %u, Parity:%s%s", + "FC: %u\n" + "Card: %u", fc, - card, - (checksum_correct ? "+" : "-"), - (wiegand_correct ? "+" : "-")); + card); } else { furi_string_printf( result, - "FC: %u\r\n" - "Card: %u\r\n" - "Checksum: %s\r\n" - "W26 Parity: %s", + "FC: %u\n" + "Card: %u\n" + "Parity: %c\n" + "Checksum: %c", fc, card, - (checksum_correct ? "+" : "-"), - (wiegand_correct ? "+" : "-")); + (wiegand_correct ? '+' : '-'), + (checksum_correct ? '+' : '-')); } } void protocol_indala26_render_data(ProtocolIndala* protocol, FuriString* result) { diff --git a/lib/lfrfid/protocols/protocol_io_prox_xsf.c b/lib/lfrfid/protocols/protocol_io_prox_xsf.c index 5cdc9064c78..b41cb66f3da 100644 --- a/lib/lfrfid/protocols/protocol_io_prox_xsf.c +++ b/lib/lfrfid/protocols/protocol_io_prox_xsf.c @@ -236,9 +236,9 @@ void protocol_io_prox_xsf_render_data(ProtocolIOProxXSF* protocol, FuriString* r uint8_t* data = protocol->data; furi_string_printf( result, - "FC: %u\r\n" - "VС: %u\r\n" - "Card: %u", + "FC: %hhu\n" + "V: %hhu\n" + "Card: %hu", data[0], data[1], (uint16_t)((data[2] << 8) | (data[3]))); @@ -248,8 +248,8 @@ void protocol_io_prox_xsf_render_brief_data(ProtocolIOProxXSF* protocol, FuriStr uint8_t* data = protocol->data; furi_string_printf( result, - "FC: %u, VС: %u\r\n" - "Card: %u", + "FC: %hhu, V: %hhu\n" + "Card: %hu", data[0], data[1], (uint16_t)((data[2] << 8) | (data[3]))); @@ -298,4 +298,4 @@ const ProtocolBase protocol_io_prox_xsf = { .render_data = (ProtocolRenderData)protocol_io_prox_xsf_render_data, .render_brief_data = (ProtocolRenderData)protocol_io_prox_xsf_render_brief_data, .write_data = (ProtocolWriteData)protocol_io_prox_xsf_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_jablotron.c b/lib/lfrfid/protocols/protocol_jablotron.c index 467002c7e0a..c2cbb417443 100644 --- a/lib/lfrfid/protocols/protocol_jablotron.c +++ b/lib/lfrfid/protocols/protocol_jablotron.c @@ -162,7 +162,7 @@ LevelDuration protocol_jablotron_encoder_yield(ProtocolJablotron* protocol) { void protocol_jablotron_render_data(ProtocolJablotron* protocol, FuriString* result) { uint64_t id = protocol_jablotron_card_id(protocol->data); - furi_string_printf(result, "ID: %llX\r\n", id); + furi_string_printf(result, "Card: %llX", id); }; bool protocol_jablotron_write_data(ProtocolJablotron* protocol, void* data) { @@ -208,4 +208,4 @@ const ProtocolBase protocol_jablotron = { .render_data = (ProtocolRenderData)protocol_jablotron_render_data, .render_brief_data = (ProtocolRenderData)protocol_jablotron_render_data, .write_data = (ProtocolWriteData)protocol_jablotron_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_keri.c b/lib/lfrfid/protocols/protocol_keri.c index d994229d99e..2cc7e8cdfcb 100644 --- a/lib/lfrfid/protocols/protocol_keri.c +++ b/lib/lfrfid/protocols/protocol_keri.c @@ -212,13 +212,40 @@ LevelDuration protocol_keri_encoder_yield(ProtocolKeri* protocol) { return level_duration; }; -void protocol_keri_render_data(ProtocolKeri* protocol, FuriString* result) { +static void + protocol_keri_render_data_internal(ProtocolKeri* protocol, FuriString* result, bool brief) { uint32_t data = bit_lib_get_bits_32(protocol->data, 0, 32); uint32_t internal_id = data & 0x7FFFFFFF; uint32_t fc = 0; uint32_t cn = 0; protocol_keri_descramble(&fc, &cn, &data); - furi_string_printf(result, "Internal ID: %lu\r\nFC: %lu, Card: %lu\r\n", internal_id, fc, cn); + + if(brief) { + furi_string_printf( + result, + "Internal ID: %lu\n" + "FC: %lu; Card: %lu", + internal_id, + fc, + cn); + } else { + furi_string_printf( + result, + "Internal ID: %lu\n" + "FC: %lu\n" + "Card: %lu", + internal_id, + fc, + cn); + } +} + +void protocol_keri_render_data(ProtocolKeri* protocol, FuriString* result) { + protocol_keri_render_data_internal(protocol, result, false); +} + +void protocol_keri_render_brief_data(ProtocolKeri* protocol, FuriString* result) { + protocol_keri_render_data_internal(protocol, result, true); } bool protocol_keri_write_data(ProtocolKeri* protocol, void* data) { @@ -262,6 +289,6 @@ const ProtocolBase protocol_keri = { .yield = (ProtocolEncoderYield)protocol_keri_encoder_yield, }, .render_data = (ProtocolRenderData)protocol_keri_render_data, - .render_brief_data = (ProtocolRenderData)protocol_keri_render_data, + .render_brief_data = (ProtocolRenderData)protocol_keri_render_brief_data, .write_data = (ProtocolWriteData)protocol_keri_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_nexwatch.c b/lib/lfrfid/protocols/protocol_nexwatch.c index 938ef273d0a..3df83be7ac2 100644 --- a/lib/lfrfid/protocols/protocol_nexwatch.c +++ b/lib/lfrfid/protocols/protocol_nexwatch.c @@ -263,7 +263,10 @@ LevelDuration protocol_nexwatch_encoder_yield(ProtocolNexwatch* protocol) { return level_duration; }; -void protocol_nexwatch_render_data(ProtocolNexwatch* protocol, FuriString* result) { +static void protocol_nexwatch_render_data_internal( + ProtocolNexwatch* protocol, + FuriString* result, + bool brief) { uint32_t id = 0; uint32_t scrambled = bit_lib_get_bits_32(protocol->data, 8, 32); protocol_nexwatch_descramble(&id, &scrambled); @@ -272,13 +275,42 @@ void protocol_nexwatch_render_data(ProtocolNexwatch* protocol, FuriString* resul uint8_t mode = bit_lib_get_bits(protocol->data, 40, 4); uint8_t parity = bit_lib_get_bits(protocol->data, 44, 4); uint8_t chk = bit_lib_get_bits(protocol->data, 48, 8); - for(m_idx = 0; m_idx < 3; m_idx++) { + + for(m_idx = 0; m_idx < COUNT_OF(magic_items); m_idx++) { magic_items[m_idx].chk = protocol_nexwatch_checksum(magic_items[m_idx].magic, id, parity); if(magic_items[m_idx].chk == chk) { break; } } - furi_string_printf(result, "ID: %lu, M:%u\r\nType: %s\r\n", id, mode, magic_items[m_idx].desc); + + const char* type = m_idx < COUNT_OF(magic_items) ? magic_items[m_idx].desc : "Unknown"; + + if(brief) { + furi_string_printf( + result, + "ID: %lu\n" + "Mode: %hhu; Type: %s", + id, + mode, + type); + } else { + furi_string_printf( + result, + "ID: %lu\n" + "Mode: %hhu\n" + "Type: %s", + id, + mode, + type); + } +} + +void protocol_nexwatch_render_data(ProtocolNexwatch* protocol, FuriString* result) { + protocol_nexwatch_render_data_internal(protocol, result, false); +} + +void protocol_nexwatch_render_brief_data(ProtocolNexwatch* protocol, FuriString* result) { + protocol_nexwatch_render_data_internal(protocol, result, true); } bool protocol_nexwatch_write_data(ProtocolNexwatch* protocol, void* data) { @@ -318,6 +350,6 @@ const ProtocolBase protocol_nexwatch = { .yield = (ProtocolEncoderYield)protocol_nexwatch_encoder_yield, }, .render_data = (ProtocolRenderData)protocol_nexwatch_render_data, - .render_brief_data = (ProtocolRenderData)protocol_nexwatch_render_data, + .render_brief_data = (ProtocolRenderData)protocol_nexwatch_render_brief_data, .write_data = (ProtocolWriteData)protocol_nexwatch_write_data, }; diff --git a/lib/lfrfid/protocols/protocol_pac_stanley.c b/lib/lfrfid/protocols/protocol_pac_stanley.c index dc9eaaf493b..67bc3bf48b3 100644 --- a/lib/lfrfid/protocols/protocol_pac_stanley.c +++ b/lib/lfrfid/protocols/protocol_pac_stanley.c @@ -202,8 +202,7 @@ bool protocol_pac_stanley_write_data(ProtocolPACStanley* protocol, void* data) { } void protocol_pac_stanley_render_data(ProtocolPACStanley* protocol, FuriString* result) { - uint8_t* data = protocol->data; - furi_string_printf(result, "CIN: %02X%02X%02X%02X", data[0], data[1], data[2], data[3]); + furi_string_printf(result, "CIN: %08lX", bit_lib_get_bits_32(protocol->data, 0, 32)); } const ProtocolBase protocol_pac_stanley = { diff --git a/lib/lfrfid/protocols/protocol_paradox.c b/lib/lfrfid/protocols/protocol_paradox.c index b716acf7a3b..bb52f0529c0 100644 --- a/lib/lfrfid/protocols/protocol_paradox.c +++ b/lib/lfrfid/protocols/protocol_paradox.c @@ -171,10 +171,20 @@ void protocol_paradox_render_data(ProtocolParadox* protocol, FuriString* result) uint8_t card_crc = bit_lib_get_bits_16(decoded_data, 34, 8); uint8_t calc_crc = protocol_paradox_calculate_checksum(fc, card_id); - furi_string_cat_printf(result, "Facility: %u\r\n", fc); - furi_string_cat_printf(result, "Card: %u\r\n", card_id); - furi_string_cat_printf(result, "CRC: %u Calc CRC: %u\r\n", card_crc, calc_crc); - if(card_crc != calc_crc) furi_string_cat_printf(result, "CRC Mismatch, Invalid Card!\r\n"); + furi_string_printf( + result, + "FC: %hhu\n" + "Card: %hu\n" + "CRC: %hhu\n" + "Calc CRC: %hhu", + fc, + card_id, + card_crc, + calc_crc); + + if(card_crc != calc_crc) { + furi_string_cat(result, "\nCRC Mismatch, Invalid Card!"); + } }; void protocol_paradox_render_brief_data(ProtocolParadox* protocol, FuriString* result) { @@ -185,11 +195,10 @@ void protocol_paradox_render_brief_data(ProtocolParadox* protocol, FuriString* r uint8_t card_crc = bit_lib_get_bits_16(decoded_data, 34, 8); uint8_t calc_crc = protocol_paradox_calculate_checksum(fc, card_id); - furi_string_cat_printf(result, "FC: %03u, Card: %05u\r\n", fc, card_id); - if(calc_crc == card_crc) { - furi_string_cat_printf(result, "CRC : %03u", card_crc); - } else { - furi_string_cat_printf(result, "Card is Invalid!"); + furi_string_printf(result, "FC: %hhu; Card: %hu", fc, card_id); + + if(calc_crc != card_crc) { + furi_string_cat(result, "\nCRC Mismatch, Invalid Card!"); } }; @@ -237,4 +246,4 @@ const ProtocolBase protocol_paradox = { .render_data = (ProtocolRenderData)protocol_paradox_render_data, .render_brief_data = (ProtocolRenderData)protocol_paradox_render_brief_data, .write_data = (ProtocolWriteData)protocol_paradox_write_data, -}; \ No newline at end of file +}; diff --git a/lib/lfrfid/protocols/protocol_pyramid.c b/lib/lfrfid/protocols/protocol_pyramid.c index f0a506eb39e..8711fe13a08 100644 --- a/lib/lfrfid/protocols/protocol_pyramid.c +++ b/lib/lfrfid/protocols/protocol_pyramid.c @@ -243,7 +243,7 @@ void protocol_pyramid_render_data(ProtocolPyramid* protocol, FuriString* result) uint8_t* decoded_data = protocol->data; uint8_t format_length = decoded_data[0]; - furi_string_cat_printf(result, "Format: %d\r\n", format_length); + furi_string_printf(result, "Format: %hhu\n", format_length); if(format_length == 26) { uint8_t facility; bit_lib_copy_bits(&facility, 0, 8, decoded_data, 8); @@ -251,9 +251,9 @@ void protocol_pyramid_render_data(ProtocolPyramid* protocol, FuriString* result) uint16_t card_id; bit_lib_copy_bits((uint8_t*)&card_id, 8, 8, decoded_data, 16); bit_lib_copy_bits((uint8_t*)&card_id, 0, 8, decoded_data, 24); - furi_string_cat_printf(result, "FC: %03u, Card: %05u", facility, card_id); + furi_string_cat_printf(result, "FC: %03hhu; Card: %05hu", facility, card_id); } else { - furi_string_cat_printf(result, "Data: unknown"); + furi_string_cat_printf(result, "Data: Unknown"); } }; diff --git a/lib/lfrfid/protocols/protocol_viking.c b/lib/lfrfid/protocols/protocol_viking.c index f5697012af6..4989e4e6813 100644 --- a/lib/lfrfid/protocols/protocol_viking.c +++ b/lib/lfrfid/protocols/protocol_viking.c @@ -176,8 +176,7 @@ bool protocol_viking_write_data(ProtocolViking* protocol, void* data) { }; void protocol_viking_render_data(ProtocolViking* protocol, FuriString* result) { - uint32_t id = bit_lib_get_bits_32(protocol->data, 0, 32); - furi_string_printf(result, "ID: %08lX\r\n", id); + furi_string_printf(result, "ID: %08lX", bit_lib_get_bits_32(protocol->data, 0, 32)); }; const ProtocolBase protocol_viking = { @@ -202,4 +201,4 @@ const ProtocolBase protocol_viking = { .render_data = (ProtocolRenderData)protocol_viking_render_data, .render_brief_data = (ProtocolRenderData)protocol_viking_render_data, .write_data = (ProtocolWriteData)protocol_viking_write_data, -}; \ No newline at end of file +}; diff --git a/targets/f18/api_symbols.csv b/targets/f18/api_symbols.csv index 7a813670596..f6199445d19 100644 --- a/targets/f18/api_symbols.csv +++ b/targets/f18/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,60.3,, +Version,+,60.4,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -2450,7 +2450,7 @@ Function,+,storage_simply_remove,_Bool,"Storage*, const char*" Function,+,storage_simply_remove_recursive,_Bool,"Storage*, const char*" Function,-,stpcpy,char*,"char*, const char*" Function,-,stpncpy,char*,"char*, const char*, size_t" -Function,-,strcasecmp,int,"const char*, const char*" +Function,+,strcasecmp,int,"const char*, const char*" Function,-,strcasecmp_l,int,"const char*, const char*, locale_t" Function,+,strcasestr,char*,"const char*, const char*" Function,-,strcat,char*,"char*, const char*" diff --git a/targets/f7/api_symbols.csv b/targets/f7/api_symbols.csv index bfc0507995a..6e65b947198 100644 --- a/targets/f7/api_symbols.csv +++ b/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,60.3,, +Version,+,60.4,, Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, @@ -3058,7 +3058,7 @@ Function,+,storage_simply_remove,_Bool,"Storage*, const char*" Function,+,storage_simply_remove_recursive,_Bool,"Storage*, const char*" Function,-,stpcpy,char*,"char*, const char*" Function,-,stpncpy,char*,"char*, const char*, size_t" -Function,-,strcasecmp,int,"const char*, const char*" +Function,+,strcasecmp,int,"const char*, const char*" Function,-,strcasecmp_l,int,"const char*, const char*, locale_t" Function,+,strcasestr,char*,"const char*, const char*" Function,-,strcat,char*,"char*, const char*" From 3084469d83e3a2c3edf8f85c6707418026138476 Mon Sep 17 00:00:00 2001 From: Kuronons <110337784+Kuronons@users.noreply.github.com> Date: Fri, 29 Mar 2024 04:40:26 +0100 Subject: [PATCH 5/5] L1_Mods animation update : adding VGM visual (#3502) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update images * Update meta.txt * Reverting to MOD 9999 Co-authored-by: あく --- .../external/L1_Mods_128x64/frame_21.png | Bin 4357 -> 2648 bytes .../external/L1_Mods_128x64/frame_22.png | Bin 4320 -> 2733 bytes .../external/L1_Mods_128x64/frame_23.png | Bin 4332 -> 3084 bytes .../external/L1_Mods_128x64/frame_24.png | Bin 4284 -> 3236 bytes .../external/L1_Mods_128x64/frame_25.png | Bin 4149 -> 3298 bytes .../external/L1_Mods_128x64/frame_26.png | Bin 4260 -> 3363 bytes .../external/L1_Mods_128x64/frame_27.png | Bin 4376 -> 3423 bytes .../external/L1_Mods_128x64/frame_28.png | Bin 4393 -> 3371 bytes .../external/L1_Mods_128x64/frame_29.png | Bin 4380 -> 3106 bytes .../external/L1_Mods_128x64/frame_30.png | Bin 4390 -> 3051 bytes .../external/L1_Mods_128x64/frame_31.png | Bin 4383 -> 3072 bytes .../external/L1_Mods_128x64/frame_32.png | Bin 4402 -> 3000 bytes .../external/L1_Mods_128x64/frame_33.png | Bin 4340 -> 4149 bytes .../external/L1_Mods_128x64/frame_34.png | Bin 4253 -> 4260 bytes .../external/L1_Mods_128x64/frame_35.png | Bin 4342 -> 4376 bytes .../external/L1_Mods_128x64/frame_36.png | Bin 4315 -> 4393 bytes .../external/L1_Mods_128x64/frame_37.png | Bin 4267 -> 4380 bytes .../external/L1_Mods_128x64/frame_38.png | Bin 4301 -> 4390 bytes .../external/L1_Mods_128x64/frame_39.png | Bin 4326 -> 4383 bytes .../external/L1_Mods_128x64/frame_40.png | Bin 4313 -> 4402 bytes .../external/L1_Mods_128x64/frame_41.png | Bin 0 -> 4340 bytes .../external/L1_Mods_128x64/frame_42.png | Bin 0 -> 4253 bytes .../external/L1_Mods_128x64/frame_43.png | Bin 0 -> 4342 bytes .../external/L1_Mods_128x64/frame_44.png | Bin 0 -> 4315 bytes .../external/L1_Mods_128x64/frame_45.png | Bin 0 -> 4267 bytes .../external/L1_Mods_128x64/frame_46.png | Bin 0 -> 4301 bytes .../external/L1_Mods_128x64/frame_47.png | Bin 0 -> 4326 bytes .../external/L1_Mods_128x64/frame_48.png | Bin 0 -> 4313 bytes .../dolphin/external/L1_Mods_128x64/meta.txt | 6 +++--- 29 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 assets/dolphin/external/L1_Mods_128x64/frame_41.png create mode 100644 assets/dolphin/external/L1_Mods_128x64/frame_42.png create mode 100644 assets/dolphin/external/L1_Mods_128x64/frame_43.png create mode 100644 assets/dolphin/external/L1_Mods_128x64/frame_44.png create mode 100644 assets/dolphin/external/L1_Mods_128x64/frame_45.png create mode 100644 assets/dolphin/external/L1_Mods_128x64/frame_46.png create mode 100644 assets/dolphin/external/L1_Mods_128x64/frame_47.png create mode 100644 assets/dolphin/external/L1_Mods_128x64/frame_48.png diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_21.png b/assets/dolphin/external/L1_Mods_128x64/frame_21.png index 900cc7d12099f0141c1e0c27cd29025fb1645f3b..00a7a6e99c02f28a51350e2ebd079919b2b17a1f 100644 GIT binary patch literal 2648 zcmcImdsGuw8ovRfAc2aCT6@+`qs972GLv^w0)&J|#83n(Xtg+*Okhfq2}y)N1%Y<8 zP_ZbKQWsX()wTFqt$NxmJ!{m~)vm9K0!7`jf(HQ+MB0M#*c%|!?rB~B**WvLbLYFi z@ArM*@7_Cwu`!Xp)8|hI0QhR6)N$~c2d_{s4|rdH{O&98;cbapV*|ivmg{1GU6u0y zn3_W+B-xX+E9C@j;^KN*M{*q|3$z9xD8ymGi8RuV=*SextYG)lon#}FUcpWjX;H03 zMW#|w*;X<>J0^k1P9tP`c1SQ1@R5mw4ZT_Q26>!1 zV!{`EQ?OI*c8i?H%goH=W(v5pHHC-CWHKJg=kfU*Xu+{%neDiPW40}HBdAFmVWli~ ziZ&xIL|jL2v@6(<>39ex%OtGXHjyTnFrEXq@Gvgw3dwD#)jr+SWSX?L*~2rSmkGYV z3T#WrvXHzu(nfEz5@dJ=X|^wPJF}$HcG{Lo{|2|o&%a=(Cng8i>CqEB(ny*h zwhh{1WBe>~m6gQpv^9aIjqXClx;-L%J{Ln?Nu=+P@KRxB7ukOXZTq1+4M7UJX zG3bN>4la@!IAT;pVwlh%CIuK9`Pr|EHqurtt%unaJlU^Nsba0Pfil7mwz$YJL=&zO zV=}Rr18c-a^n~0%TTM6=8fC&$NS?)<;*ve20mF@=Y_P^z6B8+(OrK~ODP&BYa-48Y z3I&^Rse#n9C%UO$N%OM>G!C1YN@q=74m+IybaHII`wB$ z$p4Z0L|Tbd+?+zf6_&?#1;cZ#MdL-`{dc{77KU3~N+^3*HEk1V2*Xn*6B6uJU4$AF zM~I~o5g!f1uyD0ht;QlEFf2lVDkZ82@wiVT<@P=f!h5>6F`iGXq3*$OVRkhqcLew{ zxu=k37^W5O7@>*k&D^&l=&54Cm5&3l2W4X$6dy$I-gcP4^4-I=*IVUdd2T?cI}&A2rr%wl1GK^!c=rj)Hi`dz&ly&Z6qx@R?Jj zIn6OOm237fj(!m_w{R=-)}{V_WgV!9E2+t2p2w#nx*Z;uwO=C&?>9ay40tu!(Xx(;An7I@=;k{!i|=MgZ?ca)vN;NewVKX zD}7YLyO(@lK3#vN6rIIbu&nHa|Gw8A40yg?S((4Xx$6o)E@>9mOZ?`IF;o^y%_ENH=w>4x&ciajcZ_@ z_WOitjsJZ}^ar;CGd!xxgI3GSkG=mx|FkAeablX()9B$mVm#Hl=c{gRkT=LLSl!N2 z%u9Nqb;GB%04XoHw&=nVZr4lR`{o}6p(5o@*51oaYlnYg0A${kqOibq%b16RA8hj3 ztSR%$+c!|ut;^27l-t-brP}|U>kVnogLf1&0$yb7-|~VorR|O&Fi{!{qD~l zvoARPsKGKvc#&FlN_ zt!xRX@7&GYl3to+A9}lZ*`hOy>aOccx;H%sNUNZz_E72fH9!vfLGQG~jRzL@2|i4A P{rhRcW7LPkHWd5^f;iH2 delta 3772 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 delta 3760 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 Ky-FSDNB;qnnE;#s diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_24.png b/assets/dolphin/external/L1_Mods_128x64/frame_24.png index d7c614902b6491d32e08a005c97c1f5bbc87fb2a..53d7b07a5eac0fd2b94d210954210c6fe46654a2 100644 GIT binary patch literal 3236 zcmcIn3se->86I3kK`>SzDk_eH4?H-#^V*%6738tY3XxSrjMh_4XJ_uhM0RJ{Sz$p_ z5Zd^tN2umBN5E&mM@!nAsP!Eon$%)qeWdD%4^)m3s{(q^p9)CvvcRp z|9}5?|Nr~%%&thAJ~cQnJP<*U;FM%@Iy@J_BYr?1_&a}BQxrS}xRQUaBFMlH-{FUp zR}Mpv0T<0FQur9obIR=#9lXaE);6o7Q1yhlyul zESBI4h|aa9p(e!*P=l7hMS`GFme-O7Mo+PmP>P@k9SOgBoMep*XQU~#>x02)Zpm&; zH(R=5!K+v-%j0nwb-KK~JZ&DWRot06lIM9HLFp(8hZeY+@AL>>+^I%(Bbb3Ix@DI~ zR-C90QLrhCJh2#L+PMUWs|VJpcBKg>Oy?C`I#Nscmeg%%wZ7cc;pnkeJxRGRN*CW= zfz^zB7to~xRaxW~K~gSodLp}nxv~_GqGl;S!L8@^3k)T(C!lMQJG&!2lBfgOzyYyU zXiIkRa~Vx;Ab1pahN5J57b>kgB1%zO5{;T8J0&Ggo#!_5MuO-xwL%?8f=77KnBp=B%1E(BntZ`nkz{-R>zG=t#uTUO5u74OF~?$% zlvb7{BP|LH5I6!SX_m!Bo{?}~5)3#;>j^;HDM_S32QTPvR>VcVO!)jeWh*Hn#OTSU zk+Rzb5zsttV@U%}+874s7&syTPw4G>)-KRwH`)xh3_C~2eje4wN`i=@-9~W~!Quu% zU~s@P1TF}AJx+@@&aNj7fM)F&`eR&^lC8L{iUhMuKR=&hGNri{yPOSgsOeJ^(Uc^U zf#eMa9M%X!CDCYC+ztT>O?C*GK<9F1`eYAjz~v^(Dy(sSS0l{=IbEY{8SPM~Q4oDi z5sQgFH2?|gnwEP>^Xo0B6E-gkK+u<{q|;1Q?4CTq4H7b8NnWW!-A|EMh1{1@hj|xx zULbJ*2o9I*48R2gXUBP1OM(NmNCBpM>Hin%U1=4w1ZO6IJFE_S^ToWL+|viY)vlT*3Yk6Cozi<_!mgnip5bwUB5k+?d<{ha zJq}1#VkC|SlEEI+!6I9J6_#Mrvw&d)oDf73hqxlnk(`JVB*hA>4TvJkye<~tX--cW zc(_+c6i$**TyS8+fxwEajSvOGuK#bW?rnn5QT3vz9sot!|_KKTz#k4 z9X>ZxQ>#uIgWN9Piy;?A1%LDCU~6S5vi$Lr7WK^0Pj_%%^hI3T`xk{G+=u^4ynA-G zW^dVheM`(?ZI6}&`mYPFolfnVa_0VsB)`vQO?WEZC_i8L&cjvVWtTs31lArHKj9L2 zzqF;?ujT9>|DwDr&kBZIZ&-GtqEDLT?3h8z9vqmAd^H?-wlZMM#%&Km3;mGa6$e>C z1ifT5;z;uDUhr#8?L^Z~FZPF!yP=j_tu^5pBX`IT8RU~ETadvsCoTB;hoviSS$3A* z`1Zi15$mI{*-JM3*6S%{2YYp`7TeQ#cN-}rIL&3LzgTtqv0PnW6;AlYr;HpoZd*{~ zKd;9Gr6NtM7if^mkq^H4RZaP-m2DA$_tFYC9jyr{JTyK!$1r=(lApaR9cfB0{h)er zP2Zx=W)w)Ae#Eje|@vf{F+eA761 zC%$@U=mJgre4^i`?*^ETkryuAuCJnI46R3&4E$*AxG(2}dHaS=uKQTdO+T`+dBm3O zK{dnwaiM-o&9^&FyB?p8tOzeWCUb`Gkn;7P`j1_)(MHYRcAoH5P9^2oB} zgfkP9*KD@k)(tAc+H0qc(ZmO3C2bDTS`%zq_l(uY_?dyLwVT^7HXr>>)TvVsathyS zS+xq8yua;8Kx6fskbb9-ru~LP{!!N>E;e0x8lyQ~Q{Csv-;qBqKioF#;K0jiMK{;@ z*Ty}moHBm)No?c$1FFzg;9NMmXzazxt0QjVSMRCRMyEnE(I) delta 3716 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 X+Rzc3$jHOL2ML%MT-UGF^@#r$oHEJ` diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_25.png b/assets/dolphin/external/L1_Mods_128x64/frame_25.png index 768030b3c5614c681e3e2af785c662695bc9296f..2838804e566049d8593108f52f572d6f6f185dcf 100644 GIT binary patch literal 3298 zcmb_e3se->8NLf@EYXU_CWuDIQP4z&otd3C5=E93Dyz6+lqA^9&fJ9+c4ysLU_k>b zo=DZCdVE9$50Ew*M1zf*#Hhztd~5KL6RP$kkxEjlMyXo0jS0QWE860tp6=P5xpU|L zzyG`c|NVFGg0zX_dxu4a0RVcZB%5vM9zegbJwwnnbL+*C==KXwa)u7T)6WEd22j2x z0?qYyrcd`xx28&p=8Bb7%?@MzE)TK>VDuQjM^c(%{yk&MQIf`ZrrQ>^CAGE$-_8cEtn(*&|0^g_2!_7iS>SOWbIt@i{d& z7DSZoTAnW+M@-w6;PQ0By7l%np@bRzvd2iplEEc)7+S3lH+8u>t#w~gK8n)Lw@Y9> zz0d=VHmGZPUIixQL$_~OM=(#e=F{|S?E&06U*E@2RXPKD^1QjN=}{FU%!Mw5ts`5i zm7hmS^g`LEdDAs5x1&&L9T72_j-{}X)0}QqE6`sEGHQ2#X4wbhaa1*iAWa0xq|+ve z7DkbjM3QZGRwM#d_R05K(n2~(OEfQ0?0v?X>U0!7j;YlurMPvU>{eikIUYxhVx3M^ z;wUKESw$frlpO>|Gb~}Z+etzYI2tM>LpxNql^60iYf4@)4MG1l&8nJ$FgjC-`0>y# z(vYAPks%xu0|`-NA>p7+stGa*uQ=LPiO?o_ov3Z(+ z0u>0yR7G-VUYCqi=5)zf(CBez1vQUoAcDzG9Tm8+y^E&6S?!}-C)O%WNmha#5sxcD zDL@r(pLTYU=Eqx58*D)~M4%6nNSlqWIeZ1O7baw(dOT8p#s@Li<@|^9Ht`B0QY=k4 zcn2f|kuec6qh&EOu{^TopJfU}0fi7C_Ns7?* zVvNE4v`t&a|CHU&`tInF1k}AjQR?jl9VcgXmiDEtTT*baCPrjLLZ&G@p+bfvWD>Fj zs-nuMf(TX4F}jsSuJch?vYq82!^i|FD-?ln6+)l{g&--Kmw7u>6rOopEGU`;mgYo) zva2*f1-A+`uoF<`72ZxNGU;Id8>?f3AX(ZnPDr3xnoOjqB(q>PQx*$FSxjUCpJ?G8 z>B&8@XTlSB@}z*+vj4lM#Y}M)PT-N}xJRtBwT5kiFg{#4t(N!vr=zmBPN9QBaM*c5 zK@Xj09Oy><=S3%&c{@M82terU6mvql|J?Vlo%Mc(h2Lmt(aU#zR2jMT+(4VZ`TWEY z+=lqArAOrQ)>yATDp;?JKWc_@N-IYI5l5*;}m!e?!xIBi0q)sq5RE z`$i7%OINFSLrGOV-@Q5}qip1$i`(PCfxcsBlo_bX_iy!YF$Cl=8?&Ntb>j_?J!;>E zf8ZQg!!V;Jne*_nj^YV-4(um5E!}Hw>EU5zx#gXOR0<|HbWi{{Mk^IKcDd88QCe?Uu-UeywyTAD- zu=Kg#g5_ays`vQI{0@A5>KAMAz?hJ4kN0b=-MsqK=SJ;ac~n||Rl7Ry_qG8UrrO0T zl2R)0FFcn{n^u>Xq?~$w;LLy+m(x9YV2_BvnGfFG_&h&#czwgIEA{545GwrJxuwh2 z$)H)o+{cdZT)O=3@m^tT4$7&m?;K?caSG394r;8qs6#Gc9*_C;Uz4ZoHDzZ>3aRhl!>|ruyVtMUI09 zYRZN#43xchBx%+9C5?=)XX9VM@qXZNu_>y>c7#56?sxNg_`c$zFU`@{MTLL}?awQ= zg-3^7TDGO^smeyG{@S6s>iPCMS8{>_kefbV`);pq`t^~7lFGTx2Ad%*Y3!W7#V2lm zeyk45EH^a2`kSW%rIwXff4X>LmBmn9+c;;)`IU#_E`J~o;38)Z%Ux^RAG2>^`|&`TMomG3BM{yZYSuuyOW; z2{GHU!>+qwy-ymdp9*N$ X`N*M1_L8U#0Z2)jXs#Rgdg;Fbz)FQz delta 3593 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 lv8MJxbnIUv>V}q2-WX2||MR!|k delta 3700 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 AN&o-= diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_27.png b/assets/dolphin/external/L1_Mods_128x64/frame_27.png index 9fca976de90623f1e32455e09b0efe1391403f20..7dc44d061e5e7cb6e5fa8ddfa4e0f099f0855c8f 100644 GIT binary patch literal 3423 zcmcIn3se->8J-m}NTfAtRg6c+5mQ8Gcb>a5qae#J3tLNUF6qK@*LV_-K7#X^Rht;xw}?(&GXL@noZ&(6%9 zJOBUv-~IpZpL1t*=Crh!=n>Hfg2Y(U%~|kT4v*xhKJYx}?W^(d(%+Mw<3o_A2Zs&~ z^2)2j;oKUhJ=>pcn<_}EODoE%184&-541**$x{LzQJN3@r~~9X-HF)E1BWrxDJNpH zSsP*Vm_UIueW4f3SUAltEu1g$GBza%og5G#fD8CVG~g<9`-DIu7RD9eI5e%p(6EVr zej;WJ1w^xLnW#zi0#vUhaETyj)WB;=J;PFli6})-gpP!N7AFk?!wEEncK$FJ%_}QH zmf6x73*IGS1%AIr(CJD_O0*@kR`urVNS^0)1f`=W99rPMQnz0W;BMd8E(A01NnWSN z?^NAr2vKyXMgBw#GVNG`%hL_(_I0KSCQKI)JvvfLgqGB0XtO=q)aB~7_W4tbVU$k3 zJp%jer5>Qm0zS3KD}mHv;P#L03g#(L{i?4({T6QBj~`+vOWgrIMc%@2dSpol3V{n^ z`=Biu=I0SiULg8auU%COy9$-r6%nN~sM7(MML$TyVAU9$pmBn+ zQ?x+y0%Mp!kODz;nA)HYWYI4^Y)o->f)XgbK(h}StFlumeG*ffO|ZIse$g!ft2q&a zq_j?_EEq^i;W$~3>m7OpXDNolMGk6#C0T{w^}H-eN|+b)H>*-nC=((74%y181Tng^ zDJT+0u>?=!v@G&CFESkNpaH;H2dyxApqEIp8*RGR2|GtDd=NFnN`{C)CKZ+e3hppa z4xFMH8s}Ngfb$MLBO54!RDgt`-^4Ykg{s%4$}qe1gY#CCDbuSe&O-RWmz9=+T2oDW zlGp2TSR)LTB|%ZWE)fdN=@RpS&g0Gx$sW>x%T0IsV2w*V8)*hu&^an}qG5Fkq7-V1 zL`({)0mxYAw6ljaKiPshU`q-B1bu``I?Q~k;x7@sz?ct9@>mt>zKy(3EPga~j%FE- zb{KE~WEtlHqu@Lv@wf~N1Z2HKp%u1k>Hin%ooST{M0Y-bZ&)4H`^7w&+sP3pNZIfbPep5bwkA|1F47y=gw zz~X>3$c)VKu#n2+FpEOxVLALDw?rAZTdW)VjK+lxNy}<%**z;bveOl5|VnmRLGOO8W4>W(4+vHwO3~0N5zck}= z!rKdu@B39lo5na3KiVoy?w{KpyQ@`rjzdNwXTqnz@SWa~zK!RmJk#)L?N^$HNgEHB z@#|y8HuRlxq*@c?Hw{FJV{!+Te`YaVS@h$;nS8{2_g-K(b@7$8t>ciWHx?r4nz~<# zbJJVin^#`{w_zWk6_JaRwk@+N5qk#5>{{<%v?CrV{`>N6P46CW-!>#^N59JUf-QZB zb8VHAs_y-B_cKK8Ar@J??yE22f;azi+op-nI5#HxDdEOA+kDN*$MZAJ-l<1U-9Pfj|Fp_Ewr;v5ffG^RTX%01lJL%Jw??3CkrR=fDVyVX<*hAqD(qF))?mqpB2T_N?!%dY_UUFV z)4f!bb?Nd&gLx+<)>pU88amFkcj}Rvj6cfrzBKK8!ZmeyF(>%X>g@Rf|;yg5Yfhum()kUu0OT)Z0mdh$;z zb21|925V{;ZyolJ4-N!lA{V&Xh~U0MxlvJh#-A^Ga|{vLf9{o8UuY0z&bG#EH74Qk zFIF^1{itThZ%^&ZxUe{_c~kqIRn&pmUk^C%Ut%2-iBzAH<7Q2JamTQ}$pv?}l-*Cc zzV6uN_G~7yX3^+d(vh-^jH&wzc>A7RGyhCh{9uJ~=KGV9)Yj+|9^~}hgqMq3B9db- mtv%V;ymIb#jey)iZaw|s4Ypqr6YLxM1hS@1Gw)8xTlQ~>x2bjj delta 3809 zcma)8c{CLM*ZweMM)rM42Bpnd#y*9ykG@1B`#Q#uWe{T-WCj(HbwbvJk{Xf}`C6uu zCA%UaTb6{z60-L8dzb&;bM7C{dG5XEKKGt`&b^Zo_hi$>DG&g_95l@W08T?6LqjVw zLqm8_aG;luKLLP<(L(ERd)l^$?&LOs*VbTU^?8neERdC>Lp%5!O87DX?gpO#`u)vB zPFo>i{sN3mYupegrZ91)_;kIueo~@ivW>IWPwDaUm)9eiD=T}S_Zk-p7WR9|eY{kD z0r`x1N{KJf#@@Vu8j()3#I$xcQCWpCQ*3a)`L4I#?C$|sg^(j+NY#4#EYAV~D+n4= zJR#6N{U^S`O5P5@Gr*Lrz`{|MbS&slywV{AI>bP=^$Sl}H0595ZWD`DU}d}o#dNf+A{(QMh3fDMY064%Vh3TV z_UXK6cRJ6b_U)YYU!mf%+F5GQ@j@ZnZMqb9Qv&W z%IeCjO&&JhVPyk+m-?8aZgX?Pkf3&!>d+Ry3MVjX3$9M?xTuc7iXA!oBX^R?TKnkZ zMGvexE=V2YJbHBHq{o9MP-Fr)U|SwT2y&Hi@1m8?ZO`877fNTxGuMqrVGT$9c|fYHLa z0sWRG8!MMO@aAcNxjPrq5w!Zik z25N-uWi>>im_Kitul9|K7WcxGfOG6pkmwP2v7)zPjkjQI`W;X~oD3?F-y?NIwihaz zo607O!>DCa%ixQNLYHOVcLbNQRv7qZxM1Yg5y3**DbDEK^sx>&GHE}l(NyJbY|UlJ zCss-*`t@UJiKMpTkO7h!uM0K1#BV^N_P7r9RZ024Ki@-1;CfOjo;sky<8|i?&iPJ) zvHNX%3Hf#r{G7eIZJIh>%3d=}SdvkMV?s}`CQ}8Mp{_Uh-ulO-r<>ZF+Z#SUxhz*J z&;YfA#othQdrFq}*s}Iyq`*#Vga_(*x;@2&F8@>JxJ=PW*Hb)#ZZymZp3cnKOPn$% z(~)LJ&HON97(|(MneHH;Pl37oQaZ77VisCMrNeVF>e6}BEi?Bz-_6zuq24FXn8Qj= zV9V|bTvR9M&9Obak2J_FesZ~|qUaO!Nh0dLqZzR{%u2~Rp+ZnCH1A|jzKCI08G=$e z)Su_$?X!JVX_3?b`x<}TIHx~n(C<6P;=*G5uW&BzTio&O7?0E9e&SK$O1b8b z*gxjvc3e^ZjFimvzQ=nn(8m7k*4b#`j1K}?s4Uy8n5=~-S8PIT^oGb!j$V0c!~4|L z_WC0en-^B!Dqx>Po(@$=+5B6fQPqnLr(n~p`YyYbHoG0f?c%v>ZrwB~zJ)2hg0E{6 zPmvL6LlV~P4TghlAxjE=_bfb|YIc^*!`SyE!<3@Ttqnt-c+tHwyb9;9^|0`?J)c_D z{!(zUSEiS{Hwpnk=pmjD`&N2Y##CyKMvgX*daMMmh^#D)GDCw3(S-_yn%O_3>%?PEP z89cLT9Wbi0yuZx3oVR>rMSBakb#jZi)hE?`Oh9V*Jn4LNFe$V<%s;4ciBdML_O7C} z;@zU1x1{%jkirdh(MSKJcM0T#<%n7n%ah6j?nicI%}M-h7<~D0vo!zT{PD^!#7|$l zb>3fpx@V!7FWKqxPKT-gYjxXx=34i+!t(s`w;SmTO0Hq94z7Dm$1PtJ$QKPO6FbIQ zou-<)qTErsI)vTcMTl;jF6(_t*blPhtP}h!U5sumKm0+d(>*7RV4?m)yatj(aQQ z4G4dL779B`?kac7n;#$MPrcO#o#cxNe6(Y}*!>EcIA!XeSTF4(o-4XTxh{0(Eb@us zkIS{zq-&&Yg<<-v!=86j>RMXGo!95bd|w5JdDDIUvHtkw{CaBrlls_*gx|(%IRYfX z6R?%rv#leoI=8=turB!LsTR!UUCAcltLDZ_UW?8z_I4G8UvN-&NRQUKc~2mxMsF@2 zZeXP(W;s_LU?C;Aek1>;CB?Y8B&Fo?^Sb(r7c%DyZL_wtzMj8sxO?@MrAcU;D$Ejl zj+`N$`C4wn!q#Ybg5LM#+82cO-GaLXrC4sC?AmjmmFrH|S$ds2N8_F)&l5jL(h@#w z&&utDY>Wx}-!va6t;JSZ@ral!Jw6xVB<2)Rk7>d}- zi*+AXmM}|YO9Aw4hn8oQi%q`zL;bf_xho~tQsyMxh!-bF4kl+aw;~HEE?u?a5R4< zFZ^YY<5`}!`g3niO+Jc_`eyb0LGQcqcRiE2l)6pm5{7(k5Y-Y&N0btabsjV^zuze> zlya3aZLa$h!&Lc(4{cXZvnwhtJgu{~GaE8E*}+ji&11Z5%3WwkNrm+ZF3*vYzoDs`%KOk;u$rZLZ)0+$HeT`P7Msz|>q zmd+0_KT>vm8ABnTe}7hVxle9lwk=E61;~FrR)4Z#^LNV zKR9-Ie^6=4x# zy|n4_nsULu4>7iX$V(wl7bXv8_WtR!-yc~$x|7`3Qbn%V2xdO5c!p}1YnN{9CF`s` z+OO;#yUwgZa5Ey#n}8+YJjvHO2^Ro>L}Z}uoYhoBBJj$}%5Y6>MHLSXb)2TQ zhnfN$sfwP6Vc}u>i{)sxEC?D60zaXp zrG`^gRnb7GA=T9oY6Mj;gtoG(1_G&$)K*p1(p13{v}pPeA-)J=kfNuLC(1-yO+!On zS(~N{6Qi*}jzRyI(E4w}g7w5%RYi69X$u_QCx8?fa`lX?F8spZWD5(F5h2(ojNoY! z97u$Rkp3enkWJW2LtRTlLlcKY{H;bnsNo1|2rW%5JVM*c%Tv=+RYP4xMOF5H;!&P~ z_)sDtfMjN*Bl~}X{y!baD$x>QXo{Lywff&lb6J^RG5+)C&tC|G!FYIh#&xX^0ATGi zGt$2jF*<7x3w{UZ^6dQcXS}S<#|IjCGfic1eLYScuo+7HB@2j|}gu@#3*u|#CY%1xQ-29;y{K)*7V zX2OD)mXR{sRMd+b$I;@%BWOl9-?6E|pG8W%&a=+Ww;FCc!2RRi&6h_|pG`mwx&qoO zRz)H|a)Ck<=0z!f3bVR74b+D*;yx$Y@*8KyMgcD|*9E1+h?mYmcMaLEzNl=&7dpr;~1eb7^w26VNlMkFGSJL$AA6 zvz4={y^QLmPDOrT82T}%RMN7zzuF-;&!Q=hAzDd8qxhV zb2lzIiDYvqy~@e7EV{$Ulrhm$<^Ye%GD-W|d4|RQWnv|83q@GwENyjuKw5+xr4s8fY&NKu9@0QXO<|dK0Q=a3F#xg0Ja7oWnv@%<@rb>Bvjz>TXa|Vf21QkibXer zcT&!P4HbGaN`q)xX|_u)oi7WDZel8t5)m)P1C75tNt;B@EV2yI@zLRELB%aj zwL3au;X8}2P}2gU!4M9I^L;RzP*RIDiw-kwPr(=Hg7t?w%7hDMh`@k>)>F}xIt`u9hnxC*UDhEjy%uZRJs91M(st#tvay zx{Y5zv;`5=)SydMy`7E9?Tkn;jGiXO&hYpZH5__2%BaHu*`bCkI@~pmq*#*TTnr=f zlt|O#DO#kcc2g(TfdV!7pfO{1QH;p&BF{fytSTON$>W$honodxq(Q%oGVK-}CZ+dy z6wz#yIG$z@sZfw3%`C@~(C9XikTshmfsO{*4dhp~x@BOGzRtiRhX2@_Hlt=;6W|B2= z3@JgHCS{3|5yjEGV&rwi_i=5iR}DH<1y`57e?8M?%MGe-j~71(O`V)ZWTxAUv|u!n zxJNodkwv!}^g%2%j}I0gL%?4Ul|80`)6MXNaF0tm25B1lWyh7*L$s+=gmQE!EIK)= z2BhdZmOb5+`SB8JhYc4Z4Ehk2w3~%gw-$y$WG%ogd87&rKSn+TiyuxMQ36Y`SR4|9 zh?JygFH8zg8jUn33q}Pof~hn0{|ohwvdV?fUx4r%)}ZToGLI+s?)uQp0QRI0-6vy+ zzF6B8X857_zE^qYq*(C`N2M9+=xG`(=<052_k(G6^DHND0tp#fA{B%O6H|dY4ZwU3n8ERz%<~t_7r&U*T3L3{_u@owVEnDO zj^6s5igh-HhwGjXC`EHMTB~r}o4IYEDkr zJHR0njE~!!dT{xBiQ4|DL%b}QH=r@vX3ylvt6 zmej%f?mm-v<=*M$KWqT5XUb=1J+b5)Ykby<%E>!_^0RBr)sEV}O-D}_g9YhTPfwcj ztCYgVcQ>RS?KPyXT#9MvJ#^)wtgXNQ=Ppy9)|AS%Q#g6#oQ`N)rDk6s(PPCj^#nxuqJ{}c!=#m}ymRvn>Hn(-%s->r2 z=9K2NKc9)?V)N$}TatVz{RF!7r4L%c--&{5@r%?fo zEu$AL8x@zf{)xAj*7omz>R`h*PeR$d$@wX3KLu}OEx7DDO%M5Z!KJ*v|0NqpHCu{4 zS)jp2WPENkQY!v+V<6Zx=FHrjSj+jPF_ix6#+d3G*JsrIDSuiFai-U+*7|Mxs^1@9 zId4yFSz-C;VKvu=H^rZ}0iu6xMR|DNtf6+#sD<&1o?kg2|H8F*`cKcwId=A=A~A+z z@@G}?V0GR09nZzQ{oC2r@cCOu(+-2%IiRRy*Eg${@7kUi+j1BWHu zJ5YRLck|VjgvRnomzUhGZ(1}Z>8TN?=QL|$nqKqFK63Ko+SOMKRn-Y)!Y}^u#|>YB qv2Xq^Z{w^xO@jw*irdutQ18{fR&GnX0S`t0&Sa)%+jpnsm;VQXvYayj delta 3826 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 delta 3878 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 G>;D7y8Z;#U delta 3840 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 DW7!Jk diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_33.png b/assets/dolphin/external/L1_Mods_128x64/frame_33.png index b6c6fbb19168b4e5b01f36c2a17bbe00336a4a7d..768030b3c5614c681e3e2af785c662695bc9296f 100644 GIT binary patch delta 585 zcmV-P0=E71A+;c|u?z=7Gcq?uK{%7R3^fNrGcq?uK{u1Q3>~u(4Fmyy74nb}00006 zP)t-s|Ns900033O(|!N|0rE*iK~#9!?3s&>gdhw>d;kBZcQ&H*fl!dv-DI5TOrn_{ zN_$(7=yTw@9AE6`?**hDD);vtUx2?3K>rp1jw5mkfTS203@;quW2gD?9nS%94-l7z z6N3xOf^sTD$VG%&~OTvHIW{|K7s*+7VPx^d;p~N{zl{C08AE=iONVF zumrjgU{wiy<@gA+QfZ`Q*S@sejOYiT08~f9?Z#|YUxTafP1M*B380Ly4O8x&uva!* zYf4qnkv8Q3R$is9@&$%`h-qDM|0;m>$Q4&-B%MKRyDt7DORrD8FP5}+_fhu){0J}r XJERAEvsQ=J00000NkvXXu0mjfK%D;@ delta 776 zcmV+j1NZ#3AoL-yu?z<`FhMyuFgcUB3^fKeFhMyuFq5|o9c+j(>pP3Lt+T0D)tr34jmzKIQ4)xbO8 zTRzasNcR#E4u0iepVT@rbTW zf#}0US~eQbY0eA^^&Xv$n`24Jg=v{@{PZ0VrxhiYJjImIIi!1cA|u z$s#lmw9wQq!cXAJY+5U>698V~SB{#?C34V+GvY!y4g%-Y~4 zhyh3gK*WY?PJ?zMhziZq09pW*VQe*wlr6LAr~vpbnF9zQxbzDQ^#LQJphQtmN#uU(EkgDPYo-P2lXTmgj*QC97=swz$c8)>gNnkuW#sIB^Rl(N^D^|Z|`<+ zy63^sa)>*kjXuA`cx}&>0%`(4ApATl*R?xp&~F3$2rvM>mkCDR%M8f?0000~u(4FmyyFa*R>00006 zP)t-s|Ns900033O(|!N|0%1u+K~#9!?3jse!!QVj`QQJg*QrUt95(pKHffpGMoMab z<_4nIh0n+POWb~cfYeLZ^L^Jpz;6YhKM#P!by5YuLpCrt-f@7}KJH)cS_eQ3aLx@2 zhdZW%>tAhz=K>J}&<_KDSZ8QUJXC?4<_?``nBGOtQ z!o|=%9L`DL9Rw2qBL|t401|5cNZ{JO5&o(QAfIPc5XEWu=V%YQ41h@XRst>nEdY$d z<31I*ZrFP~mH>tlfUdz*enh8MtN=t_VE0#xs5rH?Bx@Fgcm-a69B`D7b3;m1#qb4L zj)c1aI7h7mr22yBh z~u(4FmyydMF~g0000C zP)t-s|Ns90000RI2@Vbp+&)wN00071NklEV20FW(QK;-u^U`;LEr-wr^3762WGrwM?EeBfqz?f|cO%%8qv z9RPIzzc3tFoLdxJf5k+9crFYx0J#I837~`F0RYR=SdgK#;z$(S0eFXD)}RKkpa9(i zoB`kRfxC>frT{L6=HlR&iq9n23jn@98PPif&|zj221UxV+ACfI>0zj!LU@Cx*_0L)36E;MFo?mK`-yD>Gc25Moi%%sYE;!gJ z)~DfMyLSlu>szW~s9`Jxxb4Hb0u6v{-n8cMUiRlVWEHjn)K<4RK}S4XL1Y!`)d%>= zMuTVuV6aQ(4nQ*iVoz`eK&^k50>Rq^+3PDow&;Xf0quo<6$QQvK+^!21i;q;?5ku4 zCxjh_(*HdHn8B|okSRL}kj`<~j8Fg+6$#&*e45oF*AVG-4s@?40E$Ui!!(<~@smpoegqf* YdZP#}Qxh%?_W%F@07*qoM6N<$f+LqJx&QzG diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_35.png b/assets/dolphin/external/L1_Mods_128x64/frame_35.png index 461270ba4b63ea40869f892013b3241507550ef3..9fca976de90623f1e32455e09b0efe1391403f20 100644 GIT binary patch delta 791 zcmV+y1L*wrA($etu?z<}G&VLhFgcUB3^fNiG&VLhFgTOA3>~u(4FmxMG)b^ElNk;h zf6qxoK~#9! z_xp}N1wdXdzrlbBp!^pTKwq9_0D&V8AkP5sLngS{-a3FX2Jl|Te8rA+0Pq1k7X^vU z?T7-Cf%YdB!XsgL1EA~&fD8Z~3_k$Cf3h?dXjsvKI{-Vva0H-p-~o7+fg|8YK5(Z< zYXHzN3^#}87&t^Q1mJtKgdRW{Z3aNV%n%&l((axw4_xG2T!y-dSs-kJ!{(=WfUn*N zLd$N)sqhwh(+mKeM(;`;5$~|Rj{vxKz=GF`RuM&#fqMXE7+&Wu{&=SuBXe*k0+ zCh{Y$t$aS}@n022fYgmJ0Aqc*A4Wj??RtS&VSrZyAb_BJ;JxOn-(PFxk0T=92q})H zRJuTQePF4^5&(LRLfdlv-uC;iwxw&eT7drQI);Fvdpqw>b_mC(VgO|g0E9?_`hW^U zUCt~ve9*Gxgic!)mIp7kmy%DOe~iGAAx1wi2LPs|l63qzd7X!YV*vrU8h1q7n|ap< zm|GD5o7$(06AULmk1=4|WJTOkG{GHl%>n>YqYi3op@~TVr%V)Hn&js}vmt&~+DLUc zqs<{5&sPx|Mu1+i(h@Gv91Wdm0DzZWAi&8FV@Buwd54{Bh|@3xtk%YCe>i&-(DsS7 zQIc9r0H7Vq2teU(Vgrb@uT~6_HOy!-`h-mYL}dkc@WAI&Fm!j&Q3V*F-78?#OrVR} zRc#7@e2R_3uCA2_nesLv1V{jY6W_2+pj)s-1_pBrG6GU6B=z2z{={qgVA|q?7N<=_ zLI<+hin%}2CXombQ$pkqX)~u(4FmxM7l;@IlNk;h zf2~PGK~#9!?3oF2!ypVr_3{1h+@!{!)d*v!?M&$;aq5MKb`+x5KzrLi*x~yPq%NxG z?;HOBzZHP~JOC2oNfiJevVpzSKncTp;QI^uqww z89o5uX&MV+fVyqQ3q}CbZa4|hWe@>8e=C9A;m>Sf6p_{f5h}y!;_#dV_8^!7_+Bg% z4}=F@l>icIhLQnV>}Ek^1t2MbW+W|maASeL4!O{E0Gmb;sK5oF>i~zn3t5=Q-lGEJ zhkT+={+agzN&#ro zgs=hQh9Yy`0AS*Qm4Gr_9x-k)LinXfPex)!rp5}t{ z0Q+co(IH48N70Ph@c{q#@zvdV=yMK1)(^ez&#^jEaYY9}^d)r4F2R%y!~l@%fa^h8 z43ciReq05Bl#<@H;}(D}OIRJq4B#|~asaUk2uc_>y)FX~!WN`*b?<2be*j1*Ay1$! zSro7E3yi3L*OUj!6O6C45@3YBlO-boa`WrfVBEo+=uz+uRM2@ncGsq#9|BA?NkAv_ zDhi!@833*Vq+8oCtpy3-Z<1%?K=yYK-wmbxrvWfO*nQOtWY&Wy{zu7ZUI4QAgvi<~ zsZ+9fJPjbXRy|0Wav%$EM_vBlo(o;2GHd!(&08eD6yt?K(#D51s n!u=vG>)Z3cn*B7umjD9*1@H+*2nLDc00000NkvXXu0mjfk}Fk- diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_36.png b/assets/dolphin/external/L1_Mods_128x64/frame_36.png index b018a94c19c4cdd239a3043b1ffe49e93cb0f471..4b2ab5863a557a803ea13e88513282e1c26b2c00 100644 GIT binary patch delta 831 zcmV-F1Hk;-A*mv;u?z<}G&VLhFg2673^fNiG&VLhFf^063>~u(4Fmyy3l+6$0000I zP)t-s|Ns900092}{s{>Q4h|0e{r!N0yn_G$0@_JLK~#9!>{yF#d@~N9Z z{1_7h>8*4sZM9XDg|R&z21@xIzvF)%NQ|Fd|Kou^F>5MN`jZ>+w13_M8Ke<_z5Ja3 zHbyel(O&~Fdgs7zW}B^l^)`U=VF13E5A{%%13vg?+W!FXg-ixV0M^@3zktDOV*r~< z)TcoZKROL~PfBJJ_=T%$r2S5ip`Hv;#oCc(L48Q&)O_J_EE3`~NTf^~z(7 zck%!LY)%21fp-izR&5_(?H4K}1whuf@yG<6Q=_^>tzmWW*a8 zwt*{}q(BWhu;sA~fNPKHG1u>~-@op;w@uYh+F?HP*j^dx3 zP>VB>Sg>Rdks#jT*NzNJ0I(}=z|>7cNb5xaz~p6zthLd^NdVVraO!|Dm>Tnv#{51e z*Jr23Y(KYF&Zpos+t$J*4o5>W4N{HIM*W+FRk&Erj2AAkK={WuR>`$2KDb&;ZVdp!*zx z{su3BKZ4zVWx(PMuAtb0#Ky5l@%jV+*NgPF1#;2ij*0L(K<=}!Vp>$`6au>uV5EfN zq`G(y-Z<462d5M5s6C!)J^{l0N_Oj6#e;b}negAe*DgZZ*s`8-IsZ_C;_h~G6Vvi(002ov JPDHLkV1lg=hIRk| delta 752 zcmV~u(4FmyybLkGg00006 zP)t-s|Ns900033O(|!N|0+>leK~#9!Lp z!CHG97;n!Har*m)W*YVD*ByTffc?6CBLX3S_Fqx}|MhkRKpZ@P^#}kTO2K4!=Kxv_ z;L%U`;*N6w$N}8Pf`!38jH6{Rx zGK!X`DgYW2X*Bs}q0x+o<8@~1#B?e!YP zM*PjN4d%o9rUU@m5dbaFPyo{0BDjBld50(>J_WHLpD#EOTM@|uHvvOOx7j`HER+Ba z{OVEyWFNprZ1-t@2<1}HoeFKq*fe0}3YK$=TI+x{mBeaP=S&P+j4G3EaghM})1#}> zJtOn8Xpz;PBe4Bv^)^HB22hTTHY7;JB}EX}$8^<58uaG#;)Tt+qTyJjg(H|)FKnTI zqBal&vJYmp2vrIu0HC83j_eq~NI_(cbp>z)VgWQ}5++Q4K>>hSzN&so8V<*FIe>=5 z7QQJi)Hqye`n!u272_uOrBL i-p>Em?Ari-1Q-CO>~u(4Fmyy1(n_30000I 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 delta 763 zcmV~u(4Fmyyb_4XU0000C zP)t-s|Ns900092}{{8*^nX3d|0007=Nklm5MRc?VS;l22TP}AqWQF9?=Ar1m|+(d^F1Kj07wR!U~$oLzWxk=T37!}Gk_fc zI|adTng}2b!X<#v%qfo?kvfy2@v7Aw> zd})AbjR8wQS7I08^+j5UA>C_j(F}lKVqud94&}yyxiU?U06+>o2Vhpxc!~jt*C4QB z#b9bEP^Q`hqpXa71+a73X{A@7gqjmn{fM={ag*A-hB3!j0DvV{LDnBw0KlafEpUX# zool1ctLChu=~EZ0(lU)zSNUroSuBJh@|$apAO!yO*0^%PGrT}VqObIt;&j)LJBZ8C z_+ktD88doU$XVi;i9yz-7#+a?fK6vk!sgsI0jOHa&E}PV76XU{AdCoOq`>i#TP(;+ zuFS%)-D=AAz+C_uL89b-q_Hf5DIhA3h42WNmPC?;bND;}8iBth4FI&W;}}p;B!lL! zHl+s{fDG1kD6;sE8q`j}M8Q%E7$ty^CYODHy|?EojNwB$;oVL+ddtN(t9o4uge(;q zT_!*`Fd6_>SCQy-<>3?1yy>ol-y0UXt@rrvi@28Glz0Pk1&KHOo+4u(fFvNJY=}2_ to%9yWE&w9@s#ErF=l^T=ZU8?53;-<>2@9NP^V9$U002ovPDHLkV1i^>TM_^O diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_40.png b/assets/dolphin/external/L1_Mods_128x64/frame_40.png index 7f6b4b29a38e935cdf69f158929d29cf0de5091e..acf000827ffb7177e5b7dbdc7935afc06a35d147 100644 GIT binary patch delta 840 zcmV-O1GoIyA+jQ{u?z<`FhMyuFhrBM3^fNfFhMyuFhi5L3>~u(4FmyydIsCu0000C zP)t-s|Ns90000RI2@Vbp+&)wN0008%Nklc{)kT|Pe`=ArWYeaAlqz}}X>V1NRU|HTFHw=Xk*#E}QE&H(UB zE|^SjAApPjJnYa{?$`%^fEd8{R>8vL?pOtsf$}zn@Rema0U-ASzzP7r7=8f&^E5VS z*vSJk0Cz0I5rD=)1mL?2ychf^24)#)4*&{=;pFf=2Hr_<1pq(`)nxz)H^YpE{%&(# zzrxgI1)v^M9>_9Kp8R;;3=Fhi>ZOU6{-Fy1qV+qFI_7z>-wgnNw+t%jkJBk~9ItQB zlggu@f42-w0RS$-x<5VbzpR&!gU>attp?a~BMfu^A{Sgzxw8Q9;RKdMHz_0~-7{2cf1 zuc7m|;3jStWG%gwl4N%vKnP$nu(Bva0GE>+u+(W_0Dw7yB&AV#0+{@6(KkmBml|o*((m@_Q5R?gK!>Vco<34q8g!e5VRckpo-6>`Bg&U8gaG(1y#*A!r3<13 z41g)Two->#e4+R4gZmRyaLuYVH^5aXH`F=-qQ;i~43Ofqu4ohTQ|B5HKhLzLyw1N$ zD6Y4Y8<_Un$HtB3DcvJ4pppbI%7%EY=Bf+q1^|g8 S@tutT00006qLO7GS3^fNZF)>6qLN}AR3>~u(4FmyyUtq?Y0000C zP)t-s|Ns900092}{{8*^nX3d|0007zNkl;L-87l`Y<@BjEhpO}?eX!zl-eA=(q1qNvbV2{5B;PypRoqbOL zt1$sjRHGpHKuhIRE{`(F9BFwn>Yy&_UK%=33e-l8bT$>pS06PG78iM6C z9zd9em8MDMCq@=alCd@m+Za z2!k7ObtOwMYC}xr^@IqtZkB(cry0PgQ6MVW`5Y2OoRJ0Zis)0OBAnAK%AyJbGXX=1 zLxeJn=)8q%%^PY4fHSdNgmE_u$;0#}o*(tHB30E7{t&lDJ5Vv7ZTxyhBQG=#YQoL%cp02)D{ z5=t}`tr97i$0`vh!2Vgo9{a$%E z0-85{Dq+`2hQevrO^aLlr8Z(uWR%_0f0!qEXwwA g{=a6Q2Jj=m0Ny?b`5&15WB>pF07*qoM6N<$f=b~`v;Y7A diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_41.png b/assets/dolphin/external/L1_Mods_128x64/frame_41.png new file mode 100644 index 0000000000000000000000000000000000000000..b6c6fbb19168b4e5b01f36c2a17bbe00336a4a7d GIT binary patch literal 4340 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 b7eWHHnZlOuxnixqe;n2pcIM@#p6C7teSDMt literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_42.png b/assets/dolphin/external/L1_Mods_128x64/frame_42.png new file mode 100644 index 0000000000000000000000000000000000000000..7d2dcda5d98ac939ae8263cb7db583cef6574fb7 GIT binary patch literal 4253 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 z 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
`cx7 zHpiOjL42rGG71I@4h~igR#PQWykQ6(9UT}P2}2^GEDdM?ok+#dpu_-$-wdX>04xPh zrs7FN@GnM;2Pu%M2Vpt;R}=)Ywe>&5#DKqZ#mX9th9Sccs&E*A@GG=GwF9Vjxc_(K zU$p}q=wuws4i`WQq+nTF;-&B#%u3&XH}p%9 z!i^CKGgEC-Q-rxW0%5KOH_|dO*ZhsOBnD71L@e&NZ9L2N-&nQ(iba`Fa2P6y;y@z# z|1Jbu9}<-m;6oyVk!q?M;KSA!ES~sFa^%-8{S~w+j)D)ud74v51n{3}M&bX(1x*cY zO-(Hf63Pk{2UW-5)S=p1+E}QLmzSrOr<$e)0-*-^8}IqQrVqw)3ihj3{-bt&i&zEu zYxqwyuqOYs6OPF0AquNmB%`IcSdGSSYvo|}^XE_25Cj4V3JMPC+wTAXdx@o~kppdD zJ`F^94dypnS=wO^<-g78<-ry%Sj{S4_sg7K96YBN1MTP#PH(-_g4B44Z9KFq~^=mqGNP{EgxF<0W`#-`{uwB z@N;dc_cQ%VfS^&IQ0=#_a+KW#Gj78lO4L@>mq`MRK>QqI&geA%ZDLi}SuRG>?ct{r z5)9Q7E^^KMqw3KVpq!WIxRhqCDu?hZiF`^R6VC>q4{jZQhKH7q@@8F>21?oU&kVv# zxIm+%+uq}btHHt}0tGvTY;c4AOTB!aeUXQEEn0le0Tt_4ng>*h>?`QH0^mv~J#-oc z%tv;DwR0eE33u~&UQH|l;hOc%Y(7D0o`t%+3hE#w9 Z;93Nk^X$3K`tbw+OS6-vrN-`;{|~Y=oI3yj literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_44.png b/assets/dolphin/external/L1_Mods_128x64/frame_44.png new file mode 100644 index 0000000000000000000000000000000000000000..b018a94c19c4cdd239a3043b1ffe49e93cb0f471 GIT binary patch literal 4315 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 Bcas1B literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_46.png b/assets/dolphin/external/L1_Mods_128x64/frame_46.png new file mode 100644 index 0000000000000000000000000000000000000000..ed38122f52a73a977c2ed044d22e8c113ae6c3f9 GIT binary patch literal 4301 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_47.png b/assets/dolphin/external/L1_Mods_128x64/frame_47.png new file mode 100644 index 0000000000000000000000000000000000000000..38610bb4b4a9aa68f97442f901f3318941a2305a GIT binary patch literal 4326 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 Lomr`g$L0S4vAUb6 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mods_128x64/frame_48.png b/assets/dolphin/external/L1_Mods_128x64/frame_48.png new file mode 100644 index 0000000000000000000000000000000000000000..7f6b4b29a38e935cdf69f158929d29cf0de5091e GIT binary patch literal 4313 zcmbVOXIN9&);{!JL^=u~2o?w_^hoF>C`~#lN(cc0qyV7=X-W}ADblMnMWiSW3L;HK zdJz;vKUsV}drYqJJak zj}AK%{XNT`UR_yu&{M8|U42?`y`LEE-m8{|ai#!ls*sCC!98GAm?_M-YXsj-r$ zp~1A}<(&^Z_47INyS>ytzKBBta!GTAo`8l`v?g*`D!~HX($NsXD1@G12Jz2zy>e%H z0{|;b)SxiRW9?mrMC`bNz&bPr^aa8qP9m%``%XZD9M>x5-mStTE8er3LS_ev#q=~q&4f^W- zXz&W)lckec(OeX{=Yt^zR9eN)cQNb1iJS8>`)$$Td+{gxrzhRw zF{}nU+{cLOW$)mb#} zm1uno2eWQF`(cbUGWL*5{4lteT_iJ}8H_52VCzw&wfwQ`x-f zLFq{~iF}C`cXm2n&(sJa-^5Otaugo3DoznNqk_|(WxjV8p_iHe@LW%6-h1|kvB1Wth2Kc(S!*8o;t65dghn zYOU}0(5>7p$t`!zr-y;JwQ6ET<73X5Ug=(*-YXC$h&H5Z$g{$&BCJAfBzUB8#AVrc zS$KJIgyv7q)yY-JT}Kj-oBkYis&(h;qU%Qe`@U+u!!A-6IMzGYc^5wQ8?O`Aiq=KG z(uQdLQfe?|cGW~NZ@4;kr8^P(#VZ3}+rJVu`QT8OM_p2jM^V2?(eYZjZ`a+YRf0sc z+{#HuT*{R{5u1*C?9q+RCQGlu!3`Zb^2@s~?H;&`SZA z953xONLu`nBbPS>BeajUT$pI+y5fw~LgBW17nrnKwHWUP-@V>=zY#o+YLp2Z3d;;* z+s)fKz1_8!@Uv->`dxU{oW+^pCBrO3!&ULCe=vD5NikKE!{&lNf^u?_2%GnE`V6d%*aKF%LTy1!+*(EW@(cEZ>@ zwpI!+mMO9oDtPh~;-TW#bJf-qAIhe}Q2C7Gj(bD=YC`F)=ch+KpZNy3mwS3!d1IHd zYa?nO)?N*|{?l+ZU4U}<7{~IBnU>)e)QxFB#(D27rJR{8n=}fxa(1lnxyal?Z&zNR zrlX2uVu*TlhCuog?b%3>o+VV&Vzz{6cJ%P~sO)G9!^Xnfh3BejYR_oinaj0H-BAB@ zI#hq#BgVqWzg3CD!b+Z+BzEVy%nvg=gQ3smeII>3LNroxQgVu{c<^b}@*iL|Cu%I* z@v&v?<3EOLgB({Uz)glPgk|EaMFJJ!PF8iULHLz{&@PXzCuw_@Qw~

r}$X$mcUPoy&{p#o|R``KDvjqcaVjx`S_HR(L8TR&UQrTqd0POeqNV zT#xUm?&<7dQo*P!U+8{TKKi{twP+(aH{7YqZm*)OrtzcP$WYU#z$-s^BaaH5{!B|* zs(&gUWbf5r7`jdz_;&46g1C!BUDI6Hr&{Aci#K@*SMFV5+c2apdQwQuIz2+~OQa#r9|^7&J|uXJZ$9v{CSa%I}`OF{4JvDZE0nc+3-?2Bls`~b4a zzZ_CT$VU}4(7xO%$~}7NsBvS>K^P4_jrDI+NwCk$&pm-!-I}?UJYC{il9y|)je4Is zM%^^s&Gd3Q=hWb?-QQ{5Bh!h`9aa?F13Nyx+GCUl>2m~R<>^aXTZj?NFe7o z(=n&ugrG;ejU#(s*|zzZ@?^=AlEZzSVRi@9MZdE7@x7^?vwaS`!z)}{aeYmd)Y2cmw6fAi z$Tpcasrp_jYW4nZMek@Rt(I0d-qs+Md16;*-||QQHny$gt;MF+e8~PTbTjJ5PK1W+ zA^NFOjAH0Ou_n1u0x`ZgK-ZPzf&-ZlFzz@j9LAOE(}B|j0Hz?kjRVEO%oK?w5fm}M zFp5D0GMxlt_9|vDGqOI;1CI{&#aRcN+hBve zuo|vlZ7q;y5R$HdfTLhQK?HB2A2J99{!=fKKK>mC|)S=UrsrgS%UOQzBrJY zA_9Vi!C)XY4Mn(%stQI;!$nyEgn%IsP?#zdt^`3KkT5v?2K{}3=>~mW-H=uWMt_^5 z&ro0w3Wbb>LIVQ>6$6zNNxtq-xQ2!X6o!Bz5D+>7;zuP?FhLNapUiI!1~@;gFP==n zlZc>S8Zj;;e+mjrclNI+2xK#}e-sn_{>~LWYtSGJ846c~K?#Ikq5X;Wqgdho-;IAo z``J**IH(oQkL2%*rEiIw%x^M1egECiFCg6;q=hg2071lf8<4R61RRlKVt@kER}@|G zu1IxtWsH&%Tos~>P*H{`GH6%{3wVQ7}X-?ze3`-S*#Hwg1XR>igm_6q2tEiRAse z5G*}N6q26@i3~z0DXM@@m|?JZ;xEa`U%T{I&;~ePd;reX$d^O_{h4MY{$E^BRZ&+} zRl^`4^iXjSWeiRkqOPWng=o0BxvIG;sj9%?O5nfwuK#QLpme98ziQ<_YUj6zUXZ_r z|1<-A@=rVAi1Z%vr8moE=hkd`qj6iB+87=j9MFgR`}=!)dzod-mjHk<(ZoR4CTL{I zF^<>*;*P61IG8uF=alCAn)2B^YiP7I%c#`n$Z=TG!Q#Pomq_el1MT3a-rbDU^BzAZ zD?>&eePCh5vpOdz|e84av!5t|N zY`#mJ_T%mVyvaJ6p~rU5FxkgfvjIG>Sz2n~S@DdFQUdlu%YZ#ugk#a>NJ3oj@UYkqJJbn4^Q5dp)T zBo^AuFV^?LIqwuY3ptsT81!%GM@VP^!8Z<)g;c(Y1!ix${LM{DfBt z4GvU^GoP~KzJHw&_s|K}+35hB&d&W77%$*yZn-Dp89ptSyC^<%qzC|H?Q}P!P5={U zZV9W8k*70wU%K9#gOd$=%Xu9I^_d+MtE<&?HHC*}LbGE+GFgC+!;&IN`OkD-1e0cP$2n&+5~F?%8g1(9Kb~2uVi!tdpS;vW`MYE{!HnOXcW-TV=!06FUjC{?2yf*s1{#@k#nF47k~;l!gMOm z)#qoK*@7-BC~i|+@ZA0t9?#>>Px2|uw*({PlW|hco6A+4q1%?`L7T@eE~_qK2EUwT zu)n8SgkxM|Fk*8?3hZ5?sxxM(g`UEEh^HgHWnGbJ20m-CZ%JkBx&Hb)m>8NHRO&fj`#-8ljZpvq literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Mods_128x64/meta.txt b/assets/dolphin/external/L1_Mods_128x64/meta.txt index 0225c7e5593..3164fe8d8b4 100644 --- a/assets/dolphin/external/L1_Mods_128x64/meta.txt +++ b/assets/dolphin/external/L1_Mods_128x64/meta.txt @@ -3,12 +3,12 @@ Version: 1 Width: 128 Height: 64 -Passive frames: 23 +Passive frames: 31 Active frames: 18 -Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 +Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 Active cycles: 1 Frame rate: 2 Duration: 3600 Active cooldown: 7 -Bubble slots: 0 \ No newline at end of file +Bubble slots: 0